diff --git a/roaring/roaring.go b/roaring/roaring.go index 9343828f5..0e039b970 100644 --- a/roaring/roaring.go +++ b/roaring/roaring.go @@ -16,6 +16,7 @@ package roaring import ( + "bytes" "encoding/binary" "errors" "fmt" @@ -101,6 +102,14 @@ func (b *Bitmap) Add(a ...uint64) (changed bool, err error) { return changed, nil } +func (b *Bitmap) String() string { + var buffer bytes.Buffer + for _, v := range b.Slice() { + buffer.WriteString(fmt.Sprintf("%d ", v)) + } + buffer.WriteString("\n") + return buffer.String() +} func (b *Bitmap) add(v uint64) bool { hb := highbits(v) @@ -710,9 +719,12 @@ func (b *Bitmap) Check() error { 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++ { + for v < start && !eof { + result.add(v) + v, eof = itr.Next() + } + for i := start; i <= end; i++ { if eof { result.add(i) } else if v == i { diff --git a/roaring/roaring_test.go b/roaring/roaring_test.go index eb5f912c6..c1d162551 100644 --- a/roaring/roaring_test.go +++ b/roaring/roaring_test.go @@ -203,7 +203,7 @@ func TestBitmap_Xor_BitmapBitmap(t *testing.T) { func TestBitmap_Flip_Empty(t *testing.T) { bm := roaring.NewBitmap() results := bm.Flip(0, 10) - if n := results.Count(); n != 10 { + if n := results.Count(); n != 11 { t.Fatalf("unexpected n: %d", n) } results = results.Flip(0, 10) @@ -215,13 +215,13 @@ func TestBitmap_Flip_Empty(t *testing.T) { // 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, 5) - if n := results.Count(); n != 8 { - t.Fatalf("unexpected n: %d", n) + results := bm.Flip(0, 4) + if !reflect.DeepEqual(results.Slice(), []uint64{8, 16, 32, 64, 128, 256, 512, 1024}) { + t.Fatalf("unexpected %s ", results.String()) } - results = results.Flip(0, 5) - if n := results.Count(); n != 13 { - t.Fatalf("unexpected n: %d", n) + 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 %s ", results.String()) } } @@ -232,16 +232,34 @@ func TestBitmap_Flip_Bitmap(t *testing.T) { for i := uint64(0); i < size; i += 2 { bm.Add(i) } - results := bm.Flip(0, size) + results := bm.Flip(0, size-1) if n := results.Count(); n != size/2 { t.Fatalf("unexpected n: %d", n) } - results = results.Flip(0, size) //flipping back should be the same + 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) } } +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 %s ", results.String()) + } + results = results.Flip(0, 1) + if !reflect.DeepEqual(results.Slice(), []uint64{1, 2, 4, 8, 9, 10}) { + t.Fatalf("unexpected %s ", results.String()) + } + results = results.Flip(4, 8) + if !reflect.DeepEqual(results.Slice(), []uint64{1, 2, 5, 6, 7, 9, 10}) { + t.Fatalf("unexpected %s ", results.String()) + } + +} + // 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)