diff --git a/roaring/containers.go b/roaring/containers.go index 3fe0814cc..9862b894c 100644 --- a/roaring/containers.go +++ b/roaring/containers.go @@ -156,6 +156,14 @@ func (sc *sliceContainers) Iterator(key uint64) (citer ContainerIterator, found return &sliceIterator{e: sc, i: i}, found } +func (sc *sliceContainers) Repair() { + for _, c := range sc.containers { + if c.isBitmap() { + c.bitmapRepair() + } + } +} + type sliceIterator struct { e *sliceContainers i int diff --git a/roaring/roaring.go b/roaring/roaring.go index 9b40399f0..60476d89f 100644 --- a/roaring/roaring.go +++ b/roaring/roaring.go @@ -100,6 +100,9 @@ type Containers interface { Count() uint64 + // Repair will n values after in-place operations. + Repair() + //Reset will clear the containers collection to allow for recycling during snapshot Reset() } @@ -567,17 +570,7 @@ func (b *Bitmap) unionIntoTarget(target *Bitmap, others ...*Bitmap) { } // Repair bitmaps after the fact - iter, _ := target.Containers.Iterator(0) - for iter.Next() { - _, container := iter.Value() - if container.isBitmap() { - n := int32(0) - for i := 0; i < bitmapN; i++ { - n += int32(popcount(container.bitmap[i])) - } - container.n = n - } - } + target.Containers.Repair() } // Difference returns the difference of b and other. @@ -1981,6 +1974,14 @@ func (c *Container) check() error { return a } +func (c *Container) bitmapRepair() { + n := int32(0) + for i := 0; i < bitmapN; i++ { + n += int32(popcount(c.bitmap[i])) + } + c.n = n +} + // containerInfo represents a point-in-time snapshot of container stats. type containerInfo struct { Key uint64 // container key