diff --git a/fragment.go b/fragment.go index 5d89f4815..3ba4bb151 100644 --- a/fragment.go +++ b/fragment.go @@ -1596,7 +1596,7 @@ func (f *fragment) importPositions(set, clear []uint64, rowSet map[uint64]struct var results *roaring.Bitmap if smallWrite { results = f.storage - } else if beforeCnt := f.storage.Count(); !smallWrite && beforeCnt > 0 { + } else if beforeCnt := f.storage.Count(); beforeCnt > 0 { // Merge localBitmap into fragment's existing data. if len(clear) > 0 { f.storage = f.storage.Difference(clearBitmap) @@ -1741,9 +1741,11 @@ func (f *fragment) importValue(columnIDs, values []uint64, bitDepth uint, clear smallWrite = true // TODO figure out how to avoid re-allocating these each time. Probably // possible to store them on the fragment with a capacity based on - // MaxOpN. - toSet = make([]uint64, 0, len(columnIDs)*int(bitDepth)/2) - toClear = make([]uint64, 0, len(columnIDs)*int(bitDepth)/2) + // MaxOpN. For now, we know that the total number of bits to be + // set+cleared is len(values)*(bitDepth+1), so we make each slice + // slightly more than half of that to try to avoid reallocation. + toSet = make([]uint64, 0, len(columnIDs)*int(bitDepth+1)*(5/8)) + toClear = make([]uint64, 0, len(columnIDs)*int(bitDepth+1)*(5/8)) } f.mu.RUnlock() diff --git a/roaring/roaring.go b/roaring/roaring.go index 701f86925..5ce30b667 100644 --- a/roaring/roaring.go +++ b/roaring/roaring.go @@ -291,6 +291,21 @@ func (b *Bitmap) Count() (n uint64) { return b.Containers.Count() } +// Any returns "b.Count() > 0"... but faster than doing that. +func (b *Bitmap) Any() bool { + iter, _ := b.Containers.Iterator(0) + // TODO (jaffee) I'm not sure if it's possible/legal to have an empty + // container, so this loop may be totally uneccesary. In theory, any empty + // container should be removed from the bitmap though. + for b := iter.Next(); b; iter.Next() { + _, c := iter.Value() + if c.n > 0 { + return true + } + } + return false +} + // Size returns the number of bytes required for the bitmap. func (b *Bitmap) Size() int { numbytes := 0