diff options
author | Henning Baldersheim <balder@yahoo-inc.com> | 2023-01-23 17:54:23 +0000 |
---|---|---|
committer | Henning Baldersheim <balder@yahoo-inc.com> | 2023-01-23 17:54:23 +0000 |
commit | 78e994df4130ab8a3eb07135f17e306695947207 (patch) | |
tree | 258159c756b5a32e6b295703964bb7a8090a147a | |
parent | 6d55ba7e9bdfd6248d5a83786c9dd1e5ee63e9b9 (diff) |
Add rangecheck to BitVector::store(Word & word).
Handle nonoverlapping vectors in orWith, andWith and andNotWith.
-rw-r--r-- | searchlib/src/vespa/searchlib/common/bitvector.cpp | 15 | ||||
-rw-r--r-- | searchlib/src/vespa/searchlib/common/bitvector.h | 27 |
2 files changed, 25 insertions, 17 deletions
diff --git a/searchlib/src/vespa/searchlib/common/bitvector.cpp b/searchlib/src/vespa/searchlib/common/bitvector.cpp index 47ca590c9bc..1e403702fad 100644 --- a/searchlib/src/vespa/searchlib/common/bitvector.cpp +++ b/searchlib/src/vespa/searchlib/common/bitvector.cpp @@ -90,11 +90,16 @@ void BitVector::clearInterval(Index start, Index end) { clearIntervalNoInvalidation(Range(start, end)); - invalidateCachedCount(); } void +BitVector::store(Word &word, Word value) { + assert(!_enable_range_check && (&word >= getActiveStart())); + return store_unchecked(word, value); +} + +void BitVector::clearIntervalNoInvalidation(Range range_in) { Range range = sanitize(range_in); @@ -107,7 +112,7 @@ BitVector::clearIntervalNoInvalidation(Range range_in) if (endw > startw) { store(_words[startw], _words[startw] & startBits(range.start())); for (Index i = startw + 1; i < endw; ++i) { - store(_words[i], 0); + store_unchecked(_words[i], 0); } store(_words[endw], _words[endw] & endBits(last)); } else { @@ -128,7 +133,7 @@ BitVector::setInterval(Index start_in, Index end_in) if (endw > startw) { store(_words[startw], _words[startw] | checkTab(range.start())); for (Index i = startw + 1; i < endw; ++i) { - store(_words[i], allBits()); + store_unchecked(_words[i], allBits()); } store(_words[endw], _words[endw] | ~endBits(last)); } else { @@ -190,7 +195,7 @@ BitVector::orWith(const BitVector & right) verifyInclusiveStart(*this, right); if (right.size() < size()) { - if (right.size() > 0) { + if (right.size() > getStartIndex()) { ssize_t commonBytes = numActiveBytes(getStartIndex(), right.size()) - sizeof(Word); if (commonBytes > 0) { IAccelrated::getAccelerator().orBit(getActiveStart(), right.getWordIndex(getStartIndex()), commonBytes); @@ -240,7 +245,7 @@ BitVector::andNotWith(const BitVector& right) verifyInclusiveStart(*this, right); if (right.size() < size()) { - if (right.size() > 0) { + if (right.size() > getStartIndex()) { ssize_t commonBytes = numActiveBytes(getStartIndex(), right.size()) - sizeof(Word); if (commonBytes > 0) { IAccelrated::getAccelerator().andNotBit(getActiveStart(), right.getWordIndex(getStartIndex()), commonBytes); diff --git a/searchlib/src/vespa/searchlib/common/bitvector.h b/searchlib/src/vespa/searchlib/common/bitvector.h index 1d289435f6d..973d1a8704b 100644 --- a/searchlib/src/vespa/searchlib/common/bitvector.h +++ b/searchlib/src/vespa/searchlib/common/bitvector.h @@ -28,10 +28,10 @@ public: using UP = std::unique_ptr<BitVector>; class Range { public: - Range(Index start_in, Index end_in) : _start(start_in), _end(end_in) {} - Index start() const { return _start; } - Index end() const { return _end; } - bool validNonZero() const { return _end > _start; } + Range(Index start_in, Index end_in) noexcept : _start(start_in), _end(end_in) {} + [[nodiscard]] Index start() const noexcept { return _start; } + [[nodiscard]] Index end() const noexcept { return _end; } + [[nodiscard]] bool validNonZero() const noexcept { return _end > _start; } private: Index _start; Index _end; @@ -144,15 +144,15 @@ public: vespalib::atomic::store_ref_release(_sz, sz); } void set_bit_no_range_check(Index idx) { - store(_words[wordNum(idx)], _words[wordNum(idx)] | mask(idx)); + store_unchecked(_words[wordNum(idx)], _words[wordNum(idx)] | mask(idx)); } void clear_bit_no_range_check(Index idx) { - store(_words[wordNum(idx)], _words[wordNum(idx)] & ~ mask(idx)); + store_unchecked(_words[wordNum(idx)], _words[wordNum(idx)] & ~ mask(idx)); } void flip_bit_no_range_check(Index idx) { - store(_words[wordNum(idx)], _words[wordNum(idx)] ^ mask(idx)); + store_unchecked(_words[wordNum(idx)], _words[wordNum(idx)] ^ mask(idx)); } - void range_check(Index idx) { + void range_check(Index idx) const { assert(!_enable_range_check || (idx >= _startOffset && idx < _sz)); } void setBit(Index idx) { @@ -301,8 +301,11 @@ protected: static Alloc allocatePaddedAndAligned(Index start, Index end, Index capacity, const Alloc* init_alloc = nullptr); private: - Word load(const Word &word) const { return vespalib::atomic::load_ref_relaxed(word); } - void store(Word &word, Word value) { return vespalib::atomic::store_ref_relaxed(word, value); } + static Word load(const Word &word) { return vespalib::atomic::load_ref_relaxed(word); } + VESPA_DLL_LOCAL void store(Word &word, Word value); + static void store_unchecked(Word &word, Word value) { + return vespalib::atomic::store_ref_relaxed(word, value); + } friend PartialBitVector; const Word * getWordIndex(Index index) const { return static_cast<const Word *>(getStart()) + wordNum(index); } Word * getWordIndex(Index index) { return static_cast<Word *>(getStart()) + wordNum(index); } @@ -330,8 +333,8 @@ private: } VESPA_DLL_LOCAL void repairEnds(); Range sanitize(Range range) const { - return Range(std::max(range.start(), getStartIndex()), - std::min(range.end(), size())); + return {std::max(range.start(), getStartIndex()), + std::min(range.end(), size())}; } Index count() const; bool hasTrueBitsInternal() const; |