diff --git a/roaring/roaring.go b/roaring/roaring.go index bb27a4143..21e87ed0f 100644 --- a/roaring/roaring.go +++ b/roaring/roaring.go @@ -673,6 +673,27 @@ func (b *Bitmap) Check() error { return a } +func (b *Bitmap) Flip(start, end uint64) *Bitmap { + result := NewBitmap() + itr := b.Iterator() + itr.Seek(start) + v, eof := itr.Next() + for i := start; i < end; i++ { + if eof { + result.add(i) + } else if v == i { + v, eof = itr.Next() + } else { + result.add(i) + } + } + 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 diff --git a/roaring/roaring_test.go b/roaring/roaring_test.go index 32492d870..619e194e2 100644 --- a/roaring/roaring_test.go +++ b/roaring/roaring_test.go @@ -168,7 +168,48 @@ func TestBitmap_Xor_BitmapBitmap(t *testing.T) { } } +// Ensure bitmap turn on and turn off +func TestBitmap_Fipp_Empty(t *testing.T) { + bm := roaring.NewBitmap() + results := bm.Flip(0, 10) + if n := results.Count(); n != 10 { + 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_Fipp_Array(t *testing.T) { + bm := roaring.NewBitmap(0, 1, 2, 3, 4, 8, 16, 32, 64, 128, 256, 512, 1024) + results := bm.Flip(0, 5) + if n := results.Count(); n != 8 { + t.Fatalf("unexpected n: %d", n) + } + results = results.Flip(0, 5) + if n := results.Count(); n != 13 { + t.Fatalf("unexpected n: %d", n) + } + +} + +func TestBitmap_Fipp_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) + if n := results.Count(); n != size/2 { + t.Fatalf("unexpected n: %d", n) + } + results = results.Flip(0, size) //flipping back should be the same + if n := results.Count(); n != size/2 { + t.Fatalf("unexpected n: %d", n) + } +} // Ensure bitmap can return the number of intersecting bits in two bitmaps. func TestBitmap_IntersectionCount_ArrayArray(t *testing.T) {