summaryrefslogtreecommitdiffstats
path: root/searchcore
diff options
context:
space:
mode:
authorTor Egge <Tor.Egge@online.no>2022-04-28 12:17:24 +0200
committerTor Egge <Tor.Egge@online.no>2022-04-28 12:17:24 +0200
commit60c7873fbfda349cd731098223168a67d122ea9c (patch)
tree4e6545d725fd912eae47053339060e0730d3becf /searchcore
parent5e28bd110a7dd893d9aea61f47923c64b49055a2 (diff)
Use atomic for _lowest and _highest in proton::LidStateVector.
Diffstat (limited to 'searchcore')
-rw-r--r--searchcore/src/vespa/searchcore/proton/documentmetastore/lidstatevector.cpp59
-rw-r--r--searchcore/src/vespa/searchcore/proton/documentmetastore/lidstatevector.h26
2 files changed, 40 insertions, 45 deletions
diff --git a/searchcore/src/vespa/searchcore/proton/documentmetastore/lidstatevector.cpp b/searchcore/src/vespa/searchcore/proton/documentmetastore/lidstatevector.cpp
index 7309f7a518c..27b9cfdd197 100644
--- a/searchcore/src/vespa/searchcore/proton/documentmetastore/lidstatevector.cpp
+++ b/searchcore/src/vespa/searchcore/proton/documentmetastore/lidstatevector.cpp
@@ -23,9 +23,11 @@ LidStateVector::~LidStateVector() = default;
void
LidStateVector::resizeVector(uint32_t newSize, uint32_t newCapacity)
{
- assert(!_trackLowest || _lowest <= _bv.size());
- assert(!_trackHighest || _bv.size() == 0 || _highest < _bv.size());
- bool nolowest(_lowest == _bv.size());
+ uint32_t lowest = getLowest();
+ uint32_t highest = getHighest();
+ assert(!_trackLowest || lowest <= _bv.size());
+ assert(!_trackHighest || _bv.size() == 0 || highest < _bv.size());
+ bool nolowest(lowest == _bv.size());
if (_bv.size() > newSize) {
_bv.shrink(newSize);
}
@@ -36,55 +38,44 @@ LidStateVector::resizeVector(uint32_t newSize, uint32_t newCapacity)
_bv.extend(newSize);
}
if (_trackLowest) {
- if (nolowest) {
- _lowest = _bv.size();
- }
- if (_lowest > _bv.size()) {
- _lowest = _bv.size();
+ if (nolowest || lowest > _bv.size()) {
+ lowest = _bv.size();
+ _lowest.store(lowest, std::memory_order_relaxed);
}
}
if (_trackHighest) {
- if (_highest >= _bv.size()) {
- _highest = _bv.size() > 0 ? _bv.getPrevTrueBit(_bv.size() - 1) : 0;
+ if (highest >= _bv.size()) {
+ highest = _bv.size() > 0 ? _bv.getPrevTrueBit(_bv.size() - 1) : 0;
+ _highest.store(highest, std::memory_order_relaxed);
}
}
- maybeUpdateLowest();
- maybeUpdateHighest();
}
void
-LidStateVector::updateLowest()
+LidStateVector::updateLowest(uint32_t lowest)
{
- if (_lowest >= _bv.size())
- return;
- if (_bv.testBit(_lowest))
- return;
- uint32_t lowest = _bv.getNextTrueBit(_lowest);
+ lowest = _bv.getNextTrueBit(lowest);
assert(lowest <= _bv.size());
- _lowest = lowest;
+ _lowest.store(lowest, std::memory_order_relaxed);
}
void
-LidStateVector::updateHighest()
+LidStateVector::updateHighest(uint32_t highest)
{
- if (_highest == 0)
- return;
- if (_bv.testBit(_highest))
- return;
- uint32_t highest = _bv.getPrevTrueBit(_highest);
+ highest = _bv.getPrevTrueBit(highest);
assert(_bv.size() == 0 || highest < _bv.size());
- _highest = highest;
+ _highest.store(highest, std::memory_order_relaxed);
}
void
LidStateVector::setBit(unsigned int idx)
{
assert(idx < _bv.size());
- if (_trackLowest && idx < _lowest) {
- _lowest = idx;
+ if (_trackLowest && idx < getLowest()) {
+ _lowest.store(idx, std::memory_order_relaxed);
}
- if (_trackHighest && idx > _highest) {
- _highest = idx;
+ if (_trackHighest && idx > getHighest()) {
+ _highest.store(idx, std::memory_order_relaxed);
}
assert(!_bv.testBit(idx));
_bv.setBitAndMaintainCount(idx);
@@ -111,11 +102,11 @@ LidStateVector::assert_is_not_set_then_set_bits_helper(const std::vector<uint32_
}
}
if (do_set) {
- if (_trackLowest && low < _lowest) {
- _lowest = low;
+ if (_trackLowest && low < getLowest()) {
+ _lowest.store(low, std::memory_order_relaxed);
}
- if (_trackHighest && high > _highest) {
- _highest = high;
+ if (_trackHighest && high > getHighest()) {
+ _highest.store(high, std::memory_order_relaxed);
}
}
return high;
diff --git a/searchcore/src/vespa/searchcore/proton/documentmetastore/lidstatevector.h b/searchcore/src/vespa/searchcore/proton/documentmetastore/lidstatevector.h
index c0db4e99fa5..592ca23e63c 100644
--- a/searchcore/src/vespa/searchcore/proton/documentmetastore/lidstatevector.h
+++ b/searchcore/src/vespa/searchcore/proton/documentmetastore/lidstatevector.h
@@ -3,27 +3,31 @@
#pragma once
#include <vespa/searchlib/common/growablebitvector.h>
+#include <atomic>
namespace proton {
class LidStateVector
{
search::GrowableBitVector _bv;
- uint32_t _lowest;
- uint32_t _highest;
+ std::atomic<uint32_t> _lowest;
+ std::atomic<uint32_t> _highest;
bool _trackLowest;
bool _trackHighest;
- void updateLowest();
- void updateHighest();
+ void updateLowest(uint32_t lowest);
+ void updateHighest(uint32_t highest);
void maybeUpdateLowest() {
- if (_trackLowest && _lowest < _bv.size() && !_bv.testBit(_lowest))
- updateLowest();
+ uint32_t lowest = getLowest();
+ if (_trackLowest && lowest < _bv.size() && !_bv.testBit(lowest)) {
+ updateLowest(lowest);
+ }
}
-
void maybeUpdateHighest() {
- if (_trackHighest && _highest != 0 && !_bv.testBit(_highest))
- updateHighest();
+ uint32_t highest = getHighest();
+ if (_trackHighest && highest != 0 && !_bv.testBit(highest)) {
+ updateHighest(highest);
+ }
}
template <bool do_set>
uint32_t assert_is_not_set_then_set_bits_helper(const std::vector<uint32_t>& idxs);
@@ -51,8 +55,8 @@ public:
return _bv.extraByteSize() + sizeof(LidStateVector);
}
bool empty() const { return count() == 0u; }
- unsigned int getLowest() const { return _lowest; }
- unsigned int getHighest() const { return _highest; }
+ unsigned int getLowest() const { return _lowest.load(std::memory_order_relaxed); }
+ unsigned int getHighest() const { return _highest.load(std::memory_order_relaxed); }
/**
* Get cached number of bits set in vector. Called by read or