Head Cardinality Status Page (#6125)
* Adding TSDB Head Stats like cardinality to Status Page Signed-off-by: Sharad Gaur <sgaur@splunk.com> * Moving mutx to Head Signed-off-by: Sharad Gaur <sgaur@splunk.com> * Renaming variabls Signed-off-by: Sharad Gaur <sgaur@splunk.com> * Renaming variabls and html Signed-off-by: Sharad Gaur <sgaur@splunk.com> * Removing unwanted whitespaces Signed-off-by: Sharad Gaur <sgaur@splunk.com> * Adding Tests, Banchmarks and Max Heap for Postings Stats Signed-off-by: Sharad Gaur <sgaur@splunk.com> * Adding more tests for postingstats and web handler Signed-off-by: Sharad Gaur <sgaur@splunk.com> * Adding more tests for postingstats and web handler Signed-off-by: Sharad Gaur <sgaur@splunk.com> * Remove generated asset file that is no longer used Signed-off-by: Chris Marchbanks <csmarchbanks@gmail.com> * Changing comment and variable name for more readability Signed-off-by: Sharad Gaur <sgaur@splunk.com> * Using time.Duration in postings status function and removing refresh button from web page Signed-off-by: Sharad Gaur <sgaur@splunk.com>pull/6273/head
parent
1a38075f83
commit
e94503ff5c
@ -0,0 +1,69 @@ |
||||
// Copyright 2019 The Prometheus Authors
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
package index |
||||
|
||||
import ( |
||||
"math" |
||||
"sort" |
||||
) |
||||
|
||||
// Stat holds values for a single cardinality statistic.
|
||||
type Stat struct { |
||||
Name string |
||||
Count uint64 |
||||
} |
||||
|
||||
type maxHeap struct { |
||||
maxLength int |
||||
minValue uint64 |
||||
minIndex int |
||||
Items []Stat |
||||
} |
||||
|
||||
func (m *maxHeap) init(len int) { |
||||
m.maxLength = len |
||||
m.minValue = math.MaxUint64 |
||||
m.Items = make([]Stat, 0, len) |
||||
} |
||||
|
||||
func (m *maxHeap) push(item Stat) { |
||||
if len(m.Items) < m.maxLength { |
||||
if item.Count < m.minValue { |
||||
m.minValue = item.Count |
||||
m.minIndex = len(m.Items) |
||||
} |
||||
m.Items = append(m.Items, item) |
||||
return |
||||
} |
||||
if item.Count < m.minValue { |
||||
return |
||||
} |
||||
|
||||
m.Items[m.minIndex] = item |
||||
m.minValue = item.Count |
||||
|
||||
for i, stat := range m.Items { |
||||
if stat.Count < m.minValue { |
||||
m.minValue = stat.Count |
||||
m.minIndex = i |
||||
} |
||||
} |
||||
|
||||
} |
||||
|
||||
func (m *maxHeap) get() []Stat { |
||||
sort.Slice(m.Items, func(i, j int) bool { |
||||
return m.Items[i].Count > m.Items[j].Count |
||||
}) |
||||
return m.Items |
||||
} |
@ -0,0 +1,77 @@ |
||||
// Copyright 2019 The Prometheus Authors
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
package index |
||||
|
||||
import ( |
||||
"fmt" |
||||
"testing" |
||||
|
||||
"github.com/prometheus/prometheus/util/testutil" |
||||
) |
||||
|
||||
func TestPostingsStats(t *testing.T) { |
||||
stats := &maxHeap{} |
||||
max := 3000000 |
||||
heapLength := 10 |
||||
stats.init(heapLength) |
||||
for i := 0; i < max; i++ { |
||||
item := Stat{ |
||||
Name: "Label-da", |
||||
Count: uint64(i), |
||||
} |
||||
stats.push(item) |
||||
} |
||||
stats.push(Stat{Name: "Stuff", Count: 3000000}) |
||||
|
||||
data := stats.get() |
||||
testutil.Equals(t, 10, len(data)) |
||||
for i := 0; i < heapLength; i++ { |
||||
fmt.Printf("%d", data[i].Count) |
||||
testutil.Equals(t, uint64(max-i), data[i].Count) |
||||
} |
||||
|
||||
} |
||||
|
||||
func TestPostingsStats2(t *testing.T) { |
||||
stats := &maxHeap{} |
||||
heapLength := 10 |
||||
|
||||
stats.init(heapLength) |
||||
stats.push(Stat{Name: "Stuff", Count: 10}) |
||||
stats.push(Stat{Name: "Stuff", Count: 11}) |
||||
stats.push(Stat{Name: "Stuff", Count: 1}) |
||||
stats.push(Stat{Name: "Stuff", Count: 6}) |
||||
|
||||
data := stats.get() |
||||
|
||||
testutil.Equals(t, 4, len(data)) |
||||
testutil.Equals(t, uint64(11), data[0].Count) |
||||
} |
||||
func BenchmarkPostingStatsMaxHep(b *testing.B) { |
||||
stats := &maxHeap{} |
||||
max := 9000000 |
||||
heapLength := 10 |
||||
b.ResetTimer() |
||||
for n := 0; n < b.N; n++ { |
||||
stats.init(heapLength) |
||||
for i := 0; i < max; i++ { |
||||
item := Stat{ |
||||
Name: "Label-da", |
||||
Count: uint64(i), |
||||
} |
||||
stats.push(item) |
||||
} |
||||
stats.get() |
||||
} |
||||
|
||||
} |
Loading…
Reference in new issue