Efficient iteration and search in HashForLabels and HashWithoutLabels (#5707)
* Efficient iteration and search in Labels.HashForLabels Signed-off-by: Ganesh Vernekar <cs15btech11018@iith.ac.in> * Better names for variables Signed-off-by: Ganesh Vernekar <cs15btech11018@iith.ac.in> * HashWithoutLabels optimizations Signed-off-by: Ganesh Vernekar <cs15btech11018@iith.ac.in> * Refactor HashForLabels and HashWithoutLabels to take sorted names Signed-off-by: Ganesh Vernekar <cs15btech11018@iith.ac.in> * Fix review comments Signed-off-by: Ganesh Vernekar <cs15btech11018@iith.ac.in>
This commit is contained in:
parent
06bdaf076f
commit
588eb20018
|
@ -131,44 +131,46 @@ func (ls Labels) Hash() uint64 {
|
|||
}
|
||||
|
||||
// HashForLabels returns a hash value for the labels matching the provided names.
|
||||
func (ls Labels) HashForLabels(names ...string) uint64 {
|
||||
b := make([]byte, 0, 1024)
|
||||
|
||||
for _, v := range ls {
|
||||
for _, n := range names {
|
||||
if v.Name == n {
|
||||
b = append(b, v.Name...)
|
||||
b = append(b, sep)
|
||||
b = append(b, v.Value...)
|
||||
b = append(b, sep)
|
||||
break
|
||||
}
|
||||
// 'names' have to be sorted in ascending order.
|
||||
func (ls Labels) HashForLabels(b []byte, names ...string) (uint64, []byte) {
|
||||
b = b[:0]
|
||||
i, j := 0, 0
|
||||
for i < len(ls) && j < len(names) {
|
||||
if names[j] < ls[i].Name {
|
||||
j++
|
||||
} else if ls[i].Name < names[j] {
|
||||
i++
|
||||
} else {
|
||||
b = append(b, ls[i].Name...)
|
||||
b = append(b, sep)
|
||||
b = append(b, ls[i].Value...)
|
||||
b = append(b, sep)
|
||||
i++
|
||||
j++
|
||||
}
|
||||
}
|
||||
return xxhash.Sum64(b)
|
||||
return xxhash.Sum64(b), b
|
||||
}
|
||||
|
||||
// HashWithoutLabels returns a hash value for all labels except those matching
|
||||
// the provided names.
|
||||
func (ls Labels) HashWithoutLabels(names ...string) uint64 {
|
||||
b := make([]byte, 0, 1024)
|
||||
|
||||
Outer:
|
||||
for _, v := range ls {
|
||||
if v.Name == MetricName {
|
||||
// 'names' have to be sorted in ascending order.
|
||||
func (ls Labels) HashWithoutLabels(b []byte, names ...string) (uint64, []byte) {
|
||||
b = b[:0]
|
||||
j := 0
|
||||
for i := range ls {
|
||||
for j < len(names) && names[j] < ls[i].Name {
|
||||
j++
|
||||
}
|
||||
if ls[i].Name == MetricName || (j < len(names) && ls[i].Name == names[j]) {
|
||||
continue
|
||||
}
|
||||
for _, n := range names {
|
||||
if v.Name == n {
|
||||
continue Outer
|
||||
}
|
||||
}
|
||||
b = append(b, v.Name...)
|
||||
b = append(b, ls[i].Name...)
|
||||
b = append(b, sep)
|
||||
b = append(b, v.Value...)
|
||||
b = append(b, ls[i].Value...)
|
||||
b = append(b, sep)
|
||||
}
|
||||
return xxhash.Sum64(b)
|
||||
return xxhash.Sum64(b), b
|
||||
}
|
||||
|
||||
// Copy returns a copy of the labels.
|
||||
|
|
|
@ -1523,13 +1523,17 @@ func (ev *evaluator) VectorBinop(op ItemType, lhs, rhs Vector, matching *VectorM
|
|||
// signatureFunc returns a function that calculates the signature for a metric
|
||||
// ignoring the provided labels. If on, then the given labels are only used instead.
|
||||
func signatureFunc(on bool, names ...string) func(labels.Labels) uint64 {
|
||||
// TODO(fabxc): ensure names are sorted and then use that and sortedness
|
||||
// of labels by names to speed up the operations below.
|
||||
// Alternatively, inline the hashing and don't build new label sets.
|
||||
sort.Strings(names)
|
||||
if on {
|
||||
return func(lset labels.Labels) uint64 { return lset.HashForLabels(names...) }
|
||||
return func(lset labels.Labels) uint64 {
|
||||
h, _ := lset.HashForLabels(make([]byte, 0, 1024), names...)
|
||||
return h
|
||||
}
|
||||
}
|
||||
return func(lset labels.Labels) uint64 {
|
||||
h, _ := lset.HashWithoutLabels(make([]byte, 0, 1024), names...)
|
||||
return h
|
||||
}
|
||||
return func(lset labels.Labels) uint64 { return lset.HashWithoutLabels(names...) }
|
||||
}
|
||||
|
||||
// resultMetric returns the metric for the given sample(s) based on the Vector
|
||||
|
@ -1722,8 +1726,9 @@ func (ev *evaluator) aggregation(op ItemType, grouping []string, without bool, p
|
|||
}
|
||||
}
|
||||
|
||||
sort.Strings(grouping)
|
||||
lb := labels.NewBuilder(nil)
|
||||
|
||||
buf := make([]byte, 0, 1024)
|
||||
for _, s := range vec {
|
||||
metric := s.Metric
|
||||
|
||||
|
@ -1737,9 +1742,9 @@ func (ev *evaluator) aggregation(op ItemType, grouping []string, without bool, p
|
|||
groupingKey uint64
|
||||
)
|
||||
if without {
|
||||
groupingKey = metric.HashWithoutLabels(grouping...)
|
||||
groupingKey, buf = metric.HashWithoutLabels(buf, grouping...)
|
||||
} else {
|
||||
groupingKey = metric.HashForLabels(grouping...)
|
||||
groupingKey, buf = metric.HashForLabels(buf, grouping...)
|
||||
}
|
||||
|
||||
group, ok := result[groupingKey]
|
||||
|
|
Loading…
Reference in New Issue