mirror of
https://github.com/VictoriaMetrics/VictoriaMetrics.git
synced 2024-11-21 14:44:00 +00:00
lib/uint64set: remove memory allocation in bucket16.appendTo when sorting smallPool
This commit is contained in:
parent
8ec45ff335
commit
1bf6cd814d
1 changed files with 25 additions and 20 deletions
|
@ -743,9 +743,11 @@ const (
|
||||||
type bucket16 struct {
|
type bucket16 struct {
|
||||||
bits *[wordsPerBucket]uint64
|
bits *[wordsPerBucket]uint64
|
||||||
smallPoolLen int
|
smallPoolLen int
|
||||||
smallPool [56]uint16
|
smallPool [smallPoolSize]uint16
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const smallPoolSize = 56
|
||||||
|
|
||||||
func (b *bucket16) isZero() bool {
|
func (b *bucket16) isZero() bool {
|
||||||
return b.bits == nil && b.smallPoolLen == 0
|
return b.bits == nil && b.smallPoolLen == 0
|
||||||
}
|
}
|
||||||
|
@ -927,22 +929,20 @@ func (b *bucket16) delFromSmallPool(x uint16) bool {
|
||||||
func (b *bucket16) appendTo(dst []uint64, hi uint32, hi16 uint16) []uint64 {
|
func (b *bucket16) appendTo(dst []uint64, hi uint32, hi16 uint16) []uint64 {
|
||||||
hi64 := uint64(hi)<<32 | uint64(hi16)<<16
|
hi64 := uint64(hi)<<32 | uint64(hi16)<<16
|
||||||
if b.bits == nil {
|
if b.bits == nil {
|
||||||
|
// Use smallPoolSorter instead of sort.Slice here in order to reduce memory allocations.
|
||||||
|
sps := smallPoolSorterPool.Get().(*smallPoolSorter)
|
||||||
// Sort a copy of b.smallPool, since b must be readonly in order to prevent from data races
|
// Sort a copy of b.smallPool, since b must be readonly in order to prevent from data races
|
||||||
// when b.appendTo is called from concurrent goroutines.
|
// when b.appendTo is called from concurrent goroutines.
|
||||||
smallPool := b.smallPool
|
sps.smallPool = b.smallPool
|
||||||
|
sps.a = sps.smallPool[:b.smallPoolLen]
|
||||||
// Use uint16Sorter instead of sort.Slice here in order to reduce memory allocations.
|
if len(sps.a) > 1 && !sort.IsSorted(sps) {
|
||||||
a := uint16SorterPool.Get().(*uint16Sorter)
|
sort.Sort(sps)
|
||||||
*a = uint16Sorter(smallPool[:b.smallPoolLen])
|
|
||||||
if len(*a) > 1 && !sort.IsSorted(a) {
|
|
||||||
sort.Sort(a)
|
|
||||||
}
|
}
|
||||||
for _, v := range *a {
|
for _, v := range sps.a {
|
||||||
x := hi64 | uint64(v)
|
x := hi64 | uint64(v)
|
||||||
dst = append(dst, x)
|
dst = append(dst, x)
|
||||||
}
|
}
|
||||||
*a = nil
|
smallPoolSorterPool.Put(sps)
|
||||||
uint16SorterPool.Put(a)
|
|
||||||
return dst
|
return dst
|
||||||
}
|
}
|
||||||
var wordNum uint64
|
var wordNum uint64
|
||||||
|
@ -966,20 +966,25 @@ func (b *bucket16) appendTo(dst []uint64, hi uint32, hi16 uint16) []uint64 {
|
||||||
return dst
|
return dst
|
||||||
}
|
}
|
||||||
|
|
||||||
var uint16SorterPool = &sync.Pool{
|
var smallPoolSorterPool = &sync.Pool{
|
||||||
New: func() interface{} {
|
New: func() interface{} {
|
||||||
return &uint16Sorter{}
|
return &smallPoolSorter{}
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
type uint16Sorter []uint16
|
type smallPoolSorter struct {
|
||||||
|
smallPool [smallPoolSize]uint16
|
||||||
func (s uint16Sorter) Len() int { return len(s) }
|
a []uint16
|
||||||
func (s uint16Sorter) Less(i, j int) bool {
|
|
||||||
return s[i] < s[j]
|
|
||||||
}
|
}
|
||||||
func (s uint16Sorter) Swap(i, j int) {
|
|
||||||
s[i], s[j] = s[j], s[i]
|
func (sps *smallPoolSorter) Len() int { return len(sps.a) }
|
||||||
|
func (sps *smallPoolSorter) Less(i, j int) bool {
|
||||||
|
a := sps.a
|
||||||
|
return a[i] < a[j]
|
||||||
|
}
|
||||||
|
func (sps *smallPoolSorter) Swap(i, j int) {
|
||||||
|
a := sps.a
|
||||||
|
a[i], a[j] = a[j], a[i]
|
||||||
}
|
}
|
||||||
|
|
||||||
func getWordNumBitMask(x uint16) (uint16, uint64) {
|
func getWordNumBitMask(x uint16) (uint16, uint64) {
|
||||||
|
|
Loading…
Reference in a new issue