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 {
|
func (bm *bitmap) onesCount() int {
|
||||||
n := 0
|
n := 0
|
||||||
for _, word := range bm.a {
|
for _, word := range bm.a {
|
||||||
|
|
|
@ -32,7 +32,7 @@ func TestBitmap(t *testing.T) {
|
||||||
|
|
||||||
// Make sure that all the bits are set.
|
// Make sure that all the bits are set.
|
||||||
nextIdx := 0
|
nextIdx := 0
|
||||||
bm.forEachSetBit(func(idx int) bool {
|
bm.forEachSetBitReadonly(func(idx int) {
|
||||||
if idx >= i {
|
if idx >= i {
|
||||||
t.Fatalf("index must be smaller than %d", 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)
|
t.Fatalf("unexpected idx; got %d; want %d", idx, nextIdx)
|
||||||
}
|
}
|
||||||
nextIdx++
|
nextIdx++
|
||||||
return true
|
|
||||||
})
|
})
|
||||||
|
|
||||||
if !bm.areAllBitsSet() {
|
if !bm.areAllBitsSet() {
|
||||||
|
@ -66,12 +65,11 @@ func TestBitmap(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
nextIdx = 1
|
nextIdx = 1
|
||||||
bm.forEachSetBit(func(idx int) bool {
|
bm.forEachSetBitReadonly(func(idx int) {
|
||||||
if idx != nextIdx {
|
if idx != nextIdx {
|
||||||
t.Fatalf("unexpected idx; got %d; want %d", idx, nextIdx)
|
t.Fatalf("unexpected idx; got %d; want %d", idx, nextIdx)
|
||||||
}
|
}
|
||||||
nextIdx += 2
|
nextIdx += 2
|
||||||
return true
|
|
||||||
})
|
})
|
||||||
|
|
||||||
// Clear all the bits
|
// Clear all the bits
|
||||||
|
@ -93,9 +91,8 @@ func TestBitmap(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
bitsCount := 0
|
bitsCount := 0
|
||||||
bm.forEachSetBit(func(_ int) bool {
|
bm.forEachSetBitReadonly(func(_ int) {
|
||||||
bitsCount++
|
bitsCount++
|
||||||
return true
|
|
||||||
})
|
})
|
||||||
if bitsCount != 0 {
|
if bitsCount != 0 {
|
||||||
t.Fatalf("unexpected non-zero number of set bits remained: %d", bitsCount)
|
t.Fatalf("unexpected non-zero number of set bits remained: %d", bitsCount)
|
||||||
|
|
|
@ -4,6 +4,35 @@ import (
|
||||||
"testing"
|
"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) {
|
func BenchmarkBitmapForEachSetBit(b *testing.B) {
|
||||||
const bitsLen = 64*1024
|
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) {
|
func benchmarkBitmapForEachSetBit(b *testing.B, bm *bitmap, isClearBits bool) {
|
||||||
b.SetBytes(int64(bm.bitsLen))
|
b.SetBytes(int64(bm.bitsLen))
|
||||||
b.ReportAllocs()
|
b.ReportAllocs()
|
||||||
b.RunParallel(func(pb *testing.PB) {
|
b.RunParallel(func(pb *testing.PB) {
|
||||||
bmLocal := getBitmap(bm.bitsLen)
|
bmLocal := getBitmap(bm.bitsLen)
|
||||||
|
n := 0
|
||||||
for pb.Next() {
|
for pb.Next() {
|
||||||
bmLocal.copyFrom(bm)
|
bmLocal.copyFrom(bm)
|
||||||
bmLocal.forEachSetBit(func(idx int) bool {
|
bmLocal.forEachSetBit(func(idx int) bool {
|
||||||
|
n++
|
||||||
return !isClearBits
|
return !isClearBits
|
||||||
})
|
})
|
||||||
if isClearBits {
|
if isClearBits {
|
||||||
|
@ -78,5 +126,6 @@ func benchmarkBitmapForEachSetBit(b *testing.B, bm *bitmap, isClearBits bool) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
putBitmap(bmLocal)
|
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.
|
// Slow path - copy only the needed timestamps to br according to filter results.
|
||||||
dstTimestamps := br.timestamps[:0]
|
dstTimestamps := br.timestamps[:0]
|
||||||
bm.forEachSetBit(func(idx int) bool {
|
bm.forEachSetBitReadonly(func(idx int) {
|
||||||
ts := srcTimestamps[idx]
|
ts := srcTimestamps[idx]
|
||||||
dstTimestamps = append(dstTimestamps, ts)
|
dstTimestamps = append(dstTimestamps, ts)
|
||||||
return true
|
|
||||||
})
|
})
|
||||||
br.timestamps = dstTimestamps
|
br.timestamps = dstTimestamps
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue