lib/mergeset: optimize Set.AddMulti() a bit for len(items) < 10000

This should improve the search speed for time series matching the given label filters
This commit is contained in:
Aliaksandr Valialkin 2024-02-15 14:30:08 +02:00
parent cdac04997a
commit c0a9b87f46
No known key found for this signature in database
GPG key ID: 52C003EE2BCDB9EB

View file

@ -814,21 +814,23 @@ func (b *bucket16) add(x uint16) bool {
} }
func (b *bucket16) addMulti(a []uint64) int { func (b *bucket16) addMulti(a []uint64) int {
count := 0
if b.bits == nil { if b.bits == nil {
// Slow path if b.smallPoolLen + len(a) > len(b.smallPool) {
for i, x := range a { b.switchSmallPoolToBits()
if b.add(uint16(x)) {
count++
}
if b.bits != nil {
a = a[i+1:]
goto fastPath goto fastPath
} }
// Slow path
count := 0
for _, x := range a {
if b.addToSmallPool(uint16(x)) {
count++
}
} }
return count return count
} }
fastPath: fastPath:
count := 0
bits := b.bits bits := b.bits
for _, x := range a { for _, x := range a {
wordNum, bitMask := getWordNumBitMask(uint16(x)) wordNum, bitMask := getWordNumBitMask(uint16(x))
@ -850,14 +852,19 @@ func (b *bucket16) addToSmallPool(x uint16) bool {
b.smallPoolLen++ b.smallPoolLen++
return true return true
} }
b.switchSmallPoolToBits()
b.add(x)
return true
}
func (b *bucket16) switchSmallPoolToBits() {
smallPoolLen := b.smallPoolLen
b.smallPoolLen = 0 b.smallPoolLen = 0
var bits [wordsPerBucket]uint64 var bits [wordsPerBucket]uint64
b.bits = &bits b.bits = &bits
for _, v := range sp[:] { for _, v := range b.smallPool[:smallPoolLen] {
b.add(v) b.add(v)
} }
b.add(x)
return true
} }
func (b *bucket16) has(x uint16) bool { func (b *bucket16) has(x uint16) bool {