fix roaring bitmap mapping flag

This commit properly sets the `mapped` flag on a roaring bitmap
container so that it can be unmapped when it's changed.
This commit is contained in:
Ben Johnson 2015-12-16 13:20:18 -07:00
parent 4fa0c0e025
commit dd8d1e0718
2 changed files with 26 additions and 12 deletions

View file

@ -69,7 +69,6 @@ func (b *Bitmap) add(v uint32) {
i = -i - 1
}
println("DBG*", highbits(v))
b.containers[i].add(lowbits(v))
}
@ -221,7 +220,10 @@ func (b *Bitmap) UnmarshalBinary(data []byte) error {
// Read container key headers.
for i, buf := 0, data[8:]; i < int(keyN); i, buf = i+1, buf[4:] {
b.keys[i] = binary.LittleEndian.Uint16(buf[0:2])
b.containers[i] = &container{n: int(binary.LittleEndian.Uint16(buf[2:4])) + 1}
b.containers[i] = &container{
n: int(binary.LittleEndian.Uint16(buf[2:4])) + 1,
mapped: true,
}
}
// Read container offsets and attach data.
@ -459,7 +461,6 @@ func (c *container) arrayAdd(v uint16) {
// Otherwise insert into array.
c.unmap()
println("DBG&&&&&", v)
i = -i - 1
c.array = append(c.array, 0)
copy(c.array[i+1:], c.array[i:])
@ -616,8 +617,6 @@ func (op *op) WriteTo(w io.Writer) (n int64, err error) {
h := fnv.New32a()
h.Write(buf[0:5])
binary.LittleEndian.PutUint32(buf[5:9], h.Sum32())
fmt.Println("")
fmt.Println("W<<<<<<<<<<<<", op.value)
// Write to writer.
nn, err := w.Write(buf)
@ -640,7 +639,6 @@ func (op *op) UnmarshalBinary(data []byte) error {
// Read type and value.
op.typ = opType(data[0])
op.value = binary.LittleEndian.Uint32(data[1:5])
fmt.Println("R>", op.value)
return nil
}

View file

@ -132,12 +132,19 @@ func TestBitmap_Marshal_Quick_LargeValue(t *testing.T) {
// Ensure a bitmap can be marshaled and unmarshaled.
func testBitmapMarshalQuick(t *testing.T, n int, min, max uint32) {
quick.Check(func(a0, a1 []uint32) bool {
println("=================================================")
if testing.Short() {
t.Skip("short")
}
quick.Check(func(a0, a1 []uint32) bool {
// Create bitmap with initial values set.
bm := roaring.NewBitmap(a0...)
set := make(map[uint32]struct{})
for _, v := range a0 {
set[v] = struct{}{}
}
// Write snapshot to buffer.
var buf bytes.Buffer
if n, err := bm.WriteTo(&buf); err != nil {
@ -151,19 +158,28 @@ func testBitmapMarshalQuick(t *testing.T, n int, min, max uint32) {
// Add more values to bitmap.
for _, v := range a1 {
set[v] = struct{}{}
if err := bm.Add(v); err != nil {
t.Fatal(err)
}
// Extract buffer as a byte slice so it can be mapped.
data := buf.Bytes()
// Create new bitmap from ops log data.
bm2 := roaring.NewBitmap()
if err := bm2.UnmarshalBinary(buf.Bytes()); err != nil {
if err := bm2.UnmarshalBinary(data); err != nil {
t.Fatal(err)
}
// Verify the two bitmaps match.
if x, y := bm.Slice(), bm2.Slice(); !reflect.DeepEqual(x, y) {
t.Fatalf("mismatch: %s\n\nbm1=%+v\n\nbm2=%+v\n\n", diff(x, y), x, y)
// Verify the original bitmap has the correct set of values.
if exp, got := uint32SetSlice(set), bm.Slice(); !reflect.DeepEqual(exp, got) {
t.Fatalf("mismatch: %s\n\nexp=%+v\n\ngot=%+v\n\n", diff(exp, got), exp, got)
}
// Verify the bitmap loaded with the ops log has the correct set of values.
if exp, got := uint32SetSlice(set), bm2.Slice(); !reflect.DeepEqual(exp, got) {
t.Fatalf("mismatch: %s\n\nexp=%+v\n\ngot=%+v\n\n", diff(exp, got), exp, got)
}
}