summaryrefslogtreecommitdiffstats
path: root/searchlib
diff options
context:
space:
mode:
authorHenning Baldersheim <balder@yahoo-inc.com>2020-06-02 18:02:20 +0000
committerHenning Baldersheim <balder@yahoo-inc.com>2020-06-02 18:02:20 +0000
commitb38a099eb79efa9cf1fa4c9fce68a4d7e3d423b5 (patch)
treefe26883f49e0ef4fb07a3a003d2026f728a7a551 /searchlib
parent1b786c3929724340713aeb7dd09cb061232fe3dc (diff)
As the source bit vector might change in a different thread,
ensure that we sample size once to avoid incosistent read outs during copy.
Diffstat (limited to 'searchlib')
-rw-r--r--searchlib/src/vespa/searchlib/common/allocatedbitvector.cpp29
-rw-r--r--searchlib/src/vespa/searchlib/common/allocatedbitvector.h2
2 files changed, 23 insertions, 8 deletions
diff --git a/searchlib/src/vespa/searchlib/common/allocatedbitvector.cpp b/searchlib/src/vespa/searchlib/common/allocatedbitvector.cpp
index 3add7d1a328..cf159bccaca 100644
--- a/searchlib/src/vespa/searchlib/common/allocatedbitvector.cpp
+++ b/searchlib/src/vespa/searchlib/common/allocatedbitvector.cpp
@@ -17,6 +17,21 @@ size_t computeCapacity(size_t capacity, size_t allocatedBytes) {
return possibleCapacity;
}
+// This is to ensure that we only read size and capacity once during copy
+// to ensure that they do not change unexpectedly under our feet due to resizing in different thread.
+std::pair<BitVector::Index, BitVector::Index>
+extract_size_size(const BitVector & bv) {
+ BitVector::Index size = bv.size();
+ return std::pair<BitVector::Index, BitVector::Index>(size, size);
+}
+
+std::pair<BitVector::Index, BitVector::Index>
+extract_size_capacity(const AllocatedBitVector & bv) {
+ BitVector::Index size = bv.size();
+ BitVector::Index capacity = bv.capacity();
+ return std::pair<BitVector::Index, BitVector::Index>(size, capacity);
+}
+
}
AllocatedBitVector::AllocatedBitVector(Index numberOfElements) :
@@ -56,21 +71,21 @@ AllocatedBitVector::AllocatedBitVector(Index numberOfElements, Index capacityBit
}
AllocatedBitVector::AllocatedBitVector(const AllocatedBitVector & rhs) :
- AllocatedBitVector(rhs, rhs.capacity())
+ AllocatedBitVector(rhs, extract_size_capacity(rhs))
{ }
AllocatedBitVector::AllocatedBitVector(const BitVector & rhs) :
- AllocatedBitVector(rhs, rhs.size())
+ AllocatedBitVector(rhs, extract_size_size(rhs))
{ }
-AllocatedBitVector::AllocatedBitVector(const BitVector & rhs, Index capacity_) :
+AllocatedBitVector::AllocatedBitVector(const BitVector & rhs, std::pair<Index, Index> size_capacity) :
BitVector(),
- _capacityBits(capacity_),
- _alloc(allocatePaddedAndAligned(0, rhs.size(), capacity_))
+ _capacityBits(size_capacity.second),
+ _alloc(allocatePaddedAndAligned(0, size_capacity.first, size_capacity.second))
{
_capacityBits = computeCapacity(_capacityBits, _alloc.size());
- memcpy(_alloc.get(), rhs.getStart(), rhs.sizeBytes());
- init(_alloc.get(), 0, rhs.size());
+ memcpy(_alloc.get(), rhs.getStart(), numBytes(size_capacity.first - rhs.getStartIndex()));
+ init(_alloc.get(), 0, size_capacity.first);
setBit(size());
updateCount();
}
diff --git a/searchlib/src/vespa/searchlib/common/allocatedbitvector.h b/searchlib/src/vespa/searchlib/common/allocatedbitvector.h
index c52c52354a1..5a7d2e634ea 100644
--- a/searchlib/src/vespa/searchlib/common/allocatedbitvector.h
+++ b/searchlib/src/vespa/searchlib/common/allocatedbitvector.h
@@ -73,7 +73,7 @@ private:
BitVector::swap(rhs);
}
- AllocatedBitVector(const BitVector &other, Index capacity);
+ AllocatedBitVector(const BitVector &other, std::pair<Index, Index> size_capacity);
/**
* Prepare for potential reuse where new value might be filled in by