mirror of
https://github.com/VictoriaMetrics/VictoriaMetrics.git
synced 2024-11-21 14:44:00 +00:00
lib/uint64set: optimize Set.AddMulti for large sorted sets
This commit is contained in:
parent
43504ebd14
commit
eb103e1527
1 changed files with 40 additions and 53 deletions
|
@ -141,36 +141,32 @@ func (s *Set) AddMulti(a []uint64) {
|
||||||
if len(a) == 0 {
|
if len(a) == 0 {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
slowPath := false
|
hiPrev := uint32(a[0] >> 32)
|
||||||
hi := uint32(a[0] >> 32)
|
i := 0
|
||||||
for _, x := range a[1:] {
|
for j, x := range a {
|
||||||
if hi != uint32(x>>32) {
|
hi := uint32(x >> 32)
|
||||||
slowPath = true
|
if hi == hiPrev {
|
||||||
break
|
continue
|
||||||
}
|
}
|
||||||
|
b32 := s.getOrCreateBucket32(hiPrev)
|
||||||
|
s.itemsCount += b32.addMulti(a[i:j])
|
||||||
|
hiPrev = hi
|
||||||
|
i = j
|
||||||
}
|
}
|
||||||
if slowPath {
|
b32 := s.getOrCreateBucket32(hiPrev)
|
||||||
for _, x := range a {
|
s.itemsCount += b32.addMulti(a[i:])
|
||||||
s.Add(x)
|
}
|
||||||
}
|
|
||||||
return
|
func (s *Set) getOrCreateBucket32(hi uint32) *bucket32 {
|
||||||
}
|
|
||||||
// Fast path - all the items in a have identical higher 32 bits.
|
|
||||||
// Put them in a bulk into the corresponding bucket32.
|
|
||||||
bs := s.buckets
|
bs := s.buckets
|
||||||
var b32 *bucket32
|
|
||||||
for i := range bs {
|
for i := range bs {
|
||||||
if bs[i].hi == hi {
|
if bs[i].hi == hi {
|
||||||
b32 = &bs[i]
|
return &bs[i]
|
||||||
break
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if b32 == nil {
|
b32 := s.addBucket32()
|
||||||
b32 = s.addBucket32()
|
b32.hi = hi
|
||||||
b32.hi = hi
|
return b32
|
||||||
}
|
|
||||||
n := b32.addMulti(a)
|
|
||||||
s.itemsCount += n
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Set) addBucket32() *bucket32 {
|
func (s *Set) addBucket32() *bucket32 {
|
||||||
|
@ -609,41 +605,32 @@ func (b *bucket32) addMulti(a []uint64) int {
|
||||||
if len(a) == 0 {
|
if len(a) == 0 {
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
hi := uint16(a[0] >> 16)
|
count := 0
|
||||||
slowPath := false
|
hiPrev := uint16(a[0] >> 16)
|
||||||
for _, x := range a[1:] {
|
i := 0
|
||||||
if hi != uint16(x>>16) {
|
for j, x := range a {
|
||||||
slowPath = true
|
hi := uint16(x >> 16)
|
||||||
break
|
if hi == hiPrev {
|
||||||
|
continue
|
||||||
}
|
}
|
||||||
|
b16 := b.getOrCreateBucket16(hiPrev)
|
||||||
|
count += b16.addMulti(a[i:j])
|
||||||
|
hiPrev = hi
|
||||||
|
i = j
|
||||||
}
|
}
|
||||||
if slowPath {
|
b16 := b.getOrCreateBucket16(hiPrev)
|
||||||
count := 0
|
count += b16.addMulti(a[i:])
|
||||||
for _, x := range a {
|
return count
|
||||||
if b.add(uint32(x)) {
|
}
|
||||||
count++
|
|
||||||
}
|
func (b *bucket32) getOrCreateBucket16(hi uint16) *bucket16 {
|
||||||
}
|
|
||||||
return count
|
|
||||||
}
|
|
||||||
// Fast path - all the items in a have identical higher 32+16 bits.
|
|
||||||
// Put them to a single bucket16 in a bulk.
|
|
||||||
var b16 *bucket16
|
|
||||||
his := b.b16his
|
his := b.b16his
|
||||||
bs := b.buckets
|
bs := b.buckets
|
||||||
if n := b.getHint(); n < uint32(len(his)) && his[n] == hi {
|
n := binarySearch16(his, hi)
|
||||||
b16 = &bs[n]
|
if n < 0 || n >= len(his) || his[n] != hi {
|
||||||
|
return b.addBucketAtPos(hi, n)
|
||||||
}
|
}
|
||||||
if b16 == nil {
|
return &bs[n]
|
||||||
n := binarySearch16(his, hi)
|
|
||||||
if n < 0 || n >= len(his) || his[n] != hi {
|
|
||||||
b16 = b.addBucketAtPos(hi, n)
|
|
||||||
} else {
|
|
||||||
b.setHint(n)
|
|
||||||
b16 = &bs[n]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return b16.addMulti(a)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *bucket32) addSlow(hi, lo uint16) bool {
|
func (b *bucket32) addSlow(hi, lo uint16) bool {
|
||||||
|
|
Loading…
Reference in a new issue