mirror of
https://github.com/VictoriaMetrics/VictoriaMetrics.git
synced 2024-12-31 15:06:26 +00:00
wip
This commit is contained in:
parent
15c66abbe0
commit
6026112913
4 changed files with 75 additions and 8 deletions
|
@ -146,6 +146,28 @@ func (bm *bitmap) forEachSetBit(f func(idx int) bool) {
|
|||
}
|
||||
}
|
||||
|
||||
// forEachSetBitReadonly calls f for each set bit
|
||||
func (bm *bitmap) forEachSetBitReadonly(f func(idx int)) {
|
||||
a := bm.a
|
||||
bitsLen := bm.bitsLen
|
||||
for i, word := range a {
|
||||
if word == 0 {
|
||||
continue
|
||||
}
|
||||
for j := 0; j < 64; j++ {
|
||||
mask := uint64(1) << j
|
||||
if (word & mask) == 0 {
|
||||
continue
|
||||
}
|
||||
idx := i*64 + j
|
||||
if idx >= bitsLen {
|
||||
break
|
||||
}
|
||||
f(idx)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (bm *bitmap) onesCount() int {
|
||||
n := 0
|
||||
for _, word := range bm.a {
|
||||
|
|
|
@ -32,7 +32,7 @@ func TestBitmap(t *testing.T) {
|
|||
|
||||
// Make sure that all the bits are set.
|
||||
nextIdx := 0
|
||||
bm.forEachSetBit(func(idx int) bool {
|
||||
bm.forEachSetBitReadonly(func(idx int) {
|
||||
if idx >= i {
|
||||
t.Fatalf("index must be smaller than %d", i)
|
||||
}
|
||||
|
@ -40,7 +40,6 @@ func TestBitmap(t *testing.T) {
|
|||
t.Fatalf("unexpected idx; got %d; want %d", idx, nextIdx)
|
||||
}
|
||||
nextIdx++
|
||||
return true
|
||||
})
|
||||
|
||||
if !bm.areAllBitsSet() {
|
||||
|
@ -66,12 +65,11 @@ func TestBitmap(t *testing.T) {
|
|||
}
|
||||
|
||||
nextIdx = 1
|
||||
bm.forEachSetBit(func(idx int) bool {
|
||||
bm.forEachSetBitReadonly(func(idx int) {
|
||||
if idx != nextIdx {
|
||||
t.Fatalf("unexpected idx; got %d; want %d", idx, nextIdx)
|
||||
}
|
||||
nextIdx += 2
|
||||
return true
|
||||
})
|
||||
|
||||
// Clear all the bits
|
||||
|
@ -93,9 +91,8 @@ func TestBitmap(t *testing.T) {
|
|||
}
|
||||
|
||||
bitsCount := 0
|
||||
bm.forEachSetBit(func(_ int) bool {
|
||||
bm.forEachSetBitReadonly(func(_ int) {
|
||||
bitsCount++
|
||||
return true
|
||||
})
|
||||
if bitsCount != 0 {
|
||||
t.Fatalf("unexpected non-zero number of set bits remained: %d", bitsCount)
|
||||
|
|
|
@ -4,6 +4,35 @@ import (
|
|||
"testing"
|
||||
)
|
||||
|
||||
func BenchmarkBitmapForEachSetBitReadonly(b *testing.B) {
|
||||
const bitsLen = 64*1024
|
||||
|
||||
b.Run("no-zero-bits", func(b *testing.B) {
|
||||
bm := getBitmap(bitsLen)
|
||||
bm.setBits()
|
||||
benchmarkBitmapForEachSetBitReadonly(b, bm)
|
||||
putBitmap(bm)
|
||||
})
|
||||
b.Run("half-zero-bits", func(b *testing.B) {
|
||||
bm := getBitmap(bitsLen)
|
||||
bm.setBits()
|
||||
bm.forEachSetBit(func(idx int) bool {
|
||||
return idx%2 == 0
|
||||
})
|
||||
benchmarkBitmapForEachSetBitReadonly(b, bm)
|
||||
putBitmap(bm)
|
||||
})
|
||||
b.Run("one-set-bit", func(b *testing.B) {
|
||||
bm := getBitmap(bitsLen)
|
||||
bm.setBits()
|
||||
bm.forEachSetBit(func(idx int) bool {
|
||||
return idx == bitsLen/2
|
||||
})
|
||||
benchmarkBitmapForEachSetBitReadonly(b, bm)
|
||||
putBitmap(bm)
|
||||
})
|
||||
}
|
||||
|
||||
func BenchmarkBitmapForEachSetBit(b *testing.B) {
|
||||
const bitsLen = 64*1024
|
||||
|
||||
|
@ -57,14 +86,33 @@ func BenchmarkBitmapForEachSetBit(b *testing.B) {
|
|||
})
|
||||
}
|
||||
|
||||
func benchmarkBitmapForEachSetBitReadonly(b *testing.B, bm *bitmap) {
|
||||
b.SetBytes(int64(bm.bitsLen))
|
||||
b.ReportAllocs()
|
||||
b.RunParallel(func(pb *testing.PB) {
|
||||
bmLocal := getBitmap(bm.bitsLen)
|
||||
n := 0
|
||||
for pb.Next() {
|
||||
bmLocal.copyFrom(bm)
|
||||
bmLocal.forEachSetBitReadonly(func(idx int) {
|
||||
n++
|
||||
})
|
||||
}
|
||||
putBitmap(bmLocal)
|
||||
GlobalSink.Add(uint64(n))
|
||||
})
|
||||
}
|
||||
|
||||
func benchmarkBitmapForEachSetBit(b *testing.B, bm *bitmap, isClearBits bool) {
|
||||
b.SetBytes(int64(bm.bitsLen))
|
||||
b.ReportAllocs()
|
||||
b.RunParallel(func(pb *testing.PB) {
|
||||
bmLocal := getBitmap(bm.bitsLen)
|
||||
n := 0
|
||||
for pb.Next() {
|
||||
bmLocal.copyFrom(bm)
|
||||
bmLocal.forEachSetBit(func(idx int) bool {
|
||||
n++
|
||||
return !isClearBits
|
||||
})
|
||||
if isClearBits {
|
||||
|
@ -78,5 +126,6 @@ func benchmarkBitmapForEachSetBit(b *testing.B, bm *bitmap, isClearBits bool) {
|
|||
}
|
||||
}
|
||||
putBitmap(bmLocal)
|
||||
GlobalSink.Add(uint64(n))
|
||||
})
|
||||
}
|
||||
|
|
|
@ -278,10 +278,9 @@ func (br *blockResult) mustInit(bs *blockSearch, bm *bitmap) {
|
|||
|
||||
// Slow path - copy only the needed timestamps to br according to filter results.
|
||||
dstTimestamps := br.timestamps[:0]
|
||||
bm.forEachSetBit(func(idx int) bool {
|
||||
bm.forEachSetBitReadonly(func(idx int) {
|
||||
ts := srcTimestamps[idx]
|
||||
dstTimestamps = append(dstTimestamps, ts)
|
||||
return true
|
||||
})
|
||||
br.timestamps = dstTimestamps
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue