diff --git a/fragment.go b/fragment.go index 0eeeb8012..556e966a9 100644 --- a/fragment.go +++ b/fragment.go @@ -417,6 +417,7 @@ func (f *fragment) handleMutex(rowID, columnID uint64) error { return nil } +// unprotectedSetBit TODO should be replaced by an invocation of importPositions with a single bit to set. func (f *fragment) unprotectedSetBit(rowID, columnID uint64) (changed bool, err error) { changed = false // Determine the position of the bit in the storage. @@ -469,6 +470,8 @@ func (f *fragment) clearBit(rowID, columnID uint64) (bool, error) { return f.unprotectedClearBit(rowID, columnID) } +// unprotectedClearBit TODO should be replaced by an invocation of +// importPositions with a single bit to clear. func (f *fragment) unprotectedClearBit(rowID, columnID uint64) (changed bool, err error) { changed = false // Determine the position of the bit in the storage. @@ -638,6 +641,39 @@ func (f *fragment) setValue(columnID uint64, bitDepth uint, value uint64) (chang return f.setValueBase(columnID, bitDepth, value, false) } +func (f *fragment) positionsForValue(columnID uint64, bitDepth uint, value uint64, clear bool) (toSet, toClear []uint64, err error) { + toSet = make([]uint64, 0, bitDepth+1) + toClear = make([]uint64, 0, bitDepth+1) // TODO store these on the fragment + // (as [64]uint64?) and make sure + // they aren't used concurrently to + // avoid extra allocations + for i := uint(0); i < bitDepth; i++ { + bit, err := f.pos(uint64(i), columnID) + if err != nil { + return toSet, toClear, errors.Wrap(err, "getting pos") + } + if value&(1<