lib/storage: reduce memory allocations when merging metricID sets

This commit is contained in:
Aliaksandr Valialkin 2020-01-17 22:10:36 +02:00
parent 29d21259f0
commit 476c7fb109
2 changed files with 25 additions and 8 deletions

View file

@ -1775,7 +1775,7 @@ func (is *indexSearch) updateMetricIDsForTagFilters(metricIDs *uint64set.Set, tf
}
minMetricIDs = mIDs
}
metricIDs.Union(minMetricIDs)
metricIDs.UnionMayOwn(minMetricIDs)
return nil
}
@ -2094,7 +2094,7 @@ func (is *indexSearch) getMetricIDsForTimeRange(tr TimeRange, maxMetrics int, ac
err := isLocal.getMetricIDsForDate(date, &result, maxMetrics, accountID, projectID)
mu.Lock()
if metricIDs.Len() < maxMetrics {
metricIDs.Union(&result)
metricIDs.UnionMayOwn(&result)
}
if err != nil {
errGlobal = err
@ -2140,7 +2140,7 @@ func (is *indexSearch) tryUpdatingMetricIDsForDateRange(metricIDs *uint64set.Set
ok, err := isLocal.tryUpdatingMetricIDsForDate(date, &result, tfs, maxMetrics)
mu.Lock()
if metricIDs.Len() < maxMetrics {
metricIDs.Union(&result)
metricIDs.UnionMayOwn(&result)
}
if !ok {
okGlobal = ok
@ -2229,7 +2229,7 @@ func (is *indexSearch) tryUpdatingMetricIDsForDate(date uint64, metricIDs *uint6
return true, nil
}
}
metricIDs.Union(result)
metricIDs.UnionMayOwn(result)
return true, nil
}

View file

@ -165,16 +165,33 @@ func (s *Set) sort() {
// Union adds all the items from a to s.
func (s *Set) Union(a *Set) {
s.union(a, false)
}
// UnionMayOwn adds all the items from a to s.
//
// It may own a if s is empty. This means that `a` cannot be used
// after the call to UnionMayOwn.
func (s *Set) UnionMayOwn(a *Set) {
s.union(a, true)
}
func (s *Set) union(a *Set, mayOwn bool) {
if mayOwn && s.Len() < a.Len() {
// Swap `a` with `s` in order to reduce the number of iterations in ForEach loop below.
// This operation is safe only if `a` is no longer used after the call to union.
*a, *s = *s, *a
}
if a.Len() == 0 {
// Fast path - nothing to union.
return
}
if s.Len() == 0 {
// Fast path - just copy a.
aCopy := a.Clone()
*s = *aCopy
return
}
if a.Len() == 0 {
// Fast path - nothing to union.
return
}
a.ForEach(func(part []uint64) bool {
for _, x := range part {
s.Add(x)