mirror of
https://github.com/featurebasedb/featurebase.git
synced 2026-09-07 17:15:56 +00:00
Merge pull request #592 from tgruben/flip
add support for bit flip (negate) in roaring
This commit is contained in:
commit
f4815484a7
2 changed files with 92 additions and 2 deletions
|
|
@ -101,7 +101,6 @@ func (b *Bitmap) Add(a ...uint64) (changed bool, err error) {
|
|||
|
||||
return changed, nil
|
||||
}
|
||||
|
||||
func (b *Bitmap) add(v uint64) bool {
|
||||
hb := highbits(v)
|
||||
i := search64(b.keys, hb)
|
||||
|
|
@ -706,6 +705,34 @@ func (b *Bitmap) Check() error {
|
|||
return a
|
||||
}
|
||||
|
||||
//Perform a logical negate of the bits in the range [start,end].
|
||||
func (b *Bitmap) Flip(start, end uint64) *Bitmap {
|
||||
result := NewBitmap()
|
||||
itr := b.Iterator()
|
||||
v, eof := itr.Next()
|
||||
//copy over previous bits.
|
||||
for v < start && !eof {
|
||||
result.add(v)
|
||||
v, eof = itr.Next()
|
||||
}
|
||||
//flip bits in range .
|
||||
for i := start; i <= end; i++ {
|
||||
if eof {
|
||||
result.add(i)
|
||||
} else if v == i {
|
||||
v, eof = itr.Next()
|
||||
} else {
|
||||
result.add(i)
|
||||
}
|
||||
}
|
||||
//add remaining.
|
||||
for !eof {
|
||||
result.add(v)
|
||||
v, eof = itr.Next()
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
// BitmapInfo represents a point-in-time snapshot of bitmap stats.
|
||||
type BitmapInfo struct {
|
||||
OpN int
|
||||
|
|
|
|||
|
|
@ -15,8 +15,8 @@
|
|||
package roaring_test
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"bytes"
|
||||
"math"
|
||||
"math/rand"
|
||||
"reflect"
|
||||
|
|
@ -199,6 +199,69 @@ func TestBitmap_Xor_BitmapBitmap(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
// Ensure bitmap contents alternate.
|
||||
func TestBitmap_Flip_Empty(t *testing.T) {
|
||||
bm := roaring.NewBitmap()
|
||||
results := bm.Flip(0, 10)
|
||||
if n := results.Count(); n != 11 {
|
||||
t.Fatalf("unexpected n: %d", n)
|
||||
}
|
||||
results = results.Flip(0, 10)
|
||||
if n := results.Count(); n != 0 {
|
||||
t.Fatalf("unexpected n: %d", n)
|
||||
}
|
||||
}
|
||||
|
||||
// Test Subrange Flip should not affect bits outside of Range
|
||||
func TestBitmap_Flip_Array(t *testing.T) {
|
||||
bm := roaring.NewBitmap(0, 1, 2, 3, 4, 8, 16, 32, 64, 128, 256, 512, 1024)
|
||||
results := bm.Flip(0, 4)
|
||||
if !reflect.DeepEqual(results.Slice(), []uint64{8, 16, 32, 64, 128, 256, 512, 1024}) {
|
||||
t.Fatalf("unexpected %v ", results.Slice())
|
||||
}
|
||||
results = results.Flip(0, 4)
|
||||
if !reflect.DeepEqual(results.Slice(), []uint64{0, 1, 2, 3, 4, 8, 16, 32, 64, 128, 256, 512, 1024}) {
|
||||
t.Fatalf("unexpected %v ", results.Slice())
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Ensure Flip works with underlying Bitmap container.
|
||||
func TestBitmap_Flip_Bitmap(t *testing.T) {
|
||||
bm := roaring.NewBitmap()
|
||||
size := uint64(10000)
|
||||
for i := uint64(0); i < size; i += 2 {
|
||||
bm.Add(i)
|
||||
}
|
||||
results := bm.Flip(0, size-1)
|
||||
if n := results.Count(); n != size/2 {
|
||||
t.Fatalf("unexpected n: %d", n)
|
||||
}
|
||||
results = results.Flip(0, size-1) //flipping back should be the same
|
||||
if n := results.Count(); n != size/2 {
|
||||
t.Fatalf("unexpected n: %d", n)
|
||||
}
|
||||
}
|
||||
|
||||
// Verify Flip works correctly with in different regions of bitmap, beginning, middle, and end.
|
||||
func TestBitmap_Flip_After(t *testing.T) {
|
||||
bm := roaring.NewBitmap(0, 2, 4, 8)
|
||||
results := bm.Flip(9, 10)
|
||||
|
||||
if !reflect.DeepEqual(results.Slice(), []uint64{0, 2, 4, 8, 9, 10}) {
|
||||
t.Fatalf("unexpected %v ", results.Slice())
|
||||
}
|
||||
results = results.Flip(0, 1)
|
||||
if !reflect.DeepEqual(results.Slice(), []uint64{1, 2, 4, 8, 9, 10}) {
|
||||
t.Fatalf("unexpected %v ", results.Slice())
|
||||
}
|
||||
results = results.Flip(4, 8)
|
||||
if !reflect.DeepEqual(results.Slice(), []uint64{1, 2, 5, 6, 7, 9, 10}) {
|
||||
t.Fatalf("unexpected %v ", results.Slice())
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Ensure bitmap can return the number of intersecting bits in two bitmaps.
|
||||
func TestBitmap_IntersectionCount_ArrayArray(t *testing.T) {
|
||||
bm0 := roaring.NewBitmap(0, 1000001, 1000002, 1000003)
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue