summaryrefslogtreecommitdiffstats
path: root/searchlib
diff options
context:
space:
mode:
authorHenning Baldersheim <balder@yahoo-inc.com>2023-01-24 10:59:52 +0000
committerHenning Baldersheim <balder@yahoo-inc.com>2023-01-24 10:59:52 +0000
commit3daed2c24de48fc9de415dc96156ce58192ec744 (patch)
treefbf7329d86c3cb513263a9725e0dc7105d01a043 /searchlib
parent7869bcbded510978fb3c375c5734f53e3a6ee7b2 (diff)
Test that creating overlapping and non-overlapping partial bitvectors behaves as expected.
Diffstat (limited to 'searchlib')
-rw-r--r--searchlib/src/tests/common/bitvector/bitvector_test.cpp32
-rw-r--r--searchlib/src/vespa/searchlib/common/partialbitvector.cpp18
2 files changed, 45 insertions, 5 deletions
diff --git a/searchlib/src/tests/common/bitvector/bitvector_test.cpp b/searchlib/src/tests/common/bitvector/bitvector_test.cpp
index 9afc4601801..fcda2408afb 100644
--- a/searchlib/src/tests/common/bitvector/bitvector_test.cpp
+++ b/searchlib/src/tests/common/bitvector/bitvector_test.cpp
@@ -712,4 +712,36 @@ TEST("require that growable bit vectors keeps memory allocator")
g.reclaim(2);
}
+TEST("require that creating partial nonoverlapping vector is cleared") {
+ AllocatedBitVector org(1000);
+ org.setInterval(org.getStartIndex(), org.size());
+ EXPECT_EQUAL(1000u, org.countTrueBits());
+
+ BitVector::UP after = BitVector::create(org, 2000, 3000);
+ EXPECT_EQUAL(2000u, after->getStartIndex());
+ EXPECT_EQUAL(3000u, after->size());
+ EXPECT_EQUAL(0u, after->countTrueBits());
+
+ BitVector::UP before = BitVector::create(*after, 0, 1000);
+ EXPECT_EQUAL(0u, before->getStartIndex());
+ EXPECT_EQUAL(1000u, before->size());
+ EXPECT_EQUAL(0u, before->countTrueBits());
+}
+
+TEST("require that creating partial overlapping vector is properly copied") {
+ AllocatedBitVector org(1000);
+ org.setInterval(org.getStartIndex(), org.size());
+ EXPECT_EQUAL(1000u, org.countTrueBits());
+
+ BitVector::UP after = BitVector::create(org, 900, 1100);
+ EXPECT_EQUAL(900u, after->getStartIndex());
+ EXPECT_EQUAL(1100u, after->size());
+ EXPECT_EQUAL(100u, after->countTrueBits());
+
+ BitVector::UP before = BitVector::create(*after, 0, 1000);
+ EXPECT_EQUAL(0u, before->getStartIndex());
+ EXPECT_EQUAL(1000u, before->size());
+ EXPECT_EQUAL(100u, before->countTrueBits());
+}
+
TEST_MAIN() { TEST_RUN_ALL(); }
diff --git a/searchlib/src/vespa/searchlib/common/partialbitvector.cpp b/searchlib/src/vespa/searchlib/common/partialbitvector.cpp
index af4e2efd315..b5733e8cc79 100644
--- a/searchlib/src/vespa/searchlib/common/partialbitvector.cpp
+++ b/searchlib/src/vespa/searchlib/common/partialbitvector.cpp
@@ -20,11 +20,19 @@ PartialBitVector::PartialBitVector(const BitVector & org, Index start, Index end
_alloc(allocatePaddedAndAligned(start, end))
{
init(_alloc.get(), start, end);
- const Word * startWord = org.getWordIndex(start);
- size_t numBytes2Copy = numActiveBytes(start, std::min(org.size(), end));
- memcpy(_alloc.get(), startWord, numBytes2Copy);
- if (org.size() < end) {
- clearInterval(org.size(), end);
+ Range range = sanitize(org.range());
+ if (range.validNonZero()) {
+ const Word *startWord = org.getWordIndex(range.start());
+ size_t numBytes2Copy = numActiveBytes(range.start(), range.end());
+ memcpy(getWordIndex(range.start()), startWord, numBytes2Copy);
+ if (range.end() < end) {
+ clearInterval(range.end(), end);
+ }
+ if (start < range.start()) {
+ clearInterval(start, range.start());
+ }
+ } else {
+ clear();
}
set_bit_no_range_check(size());
}