diff options
Diffstat (limited to 'searchlib')
8 files changed, 71 insertions, 66 deletions
diff --git a/searchlib/src/tests/attribute/bitvector_search_cache/bitvector_search_cache_test.cpp b/searchlib/src/tests/attribute/bitvector_search_cache/bitvector_search_cache_test.cpp index b9c82892a97..bb65beed68b 100644 --- a/searchlib/src/tests/attribute/bitvector_search_cache/bitvector_search_cache_test.cpp +++ b/searchlib/src/tests/attribute/bitvector_search_cache/bitvector_search_cache_test.cpp @@ -9,8 +9,9 @@ using namespace search::attribute; using BitVectorSP = BitVectorSearchCache::BitVectorSP; using Entry = BitVectorSearchCache::Entry; +using EntrySP = std::shared_ptr<Entry>; -Entry::SP +EntrySP makeEntry() { return std::make_shared<Entry>(IDocumentMetaStoreContext::IReadGuard::SP(), BitVector::create(5), 10); @@ -18,8 +19,8 @@ makeEntry() struct Fixture { BitVectorSearchCache cache; - Entry::SP entry1; - Entry::SP entry2; + EntrySP entry1; + EntrySP entry2; Fixture() : cache(), entry1(makeEntry()), diff --git a/searchlib/src/tests/attribute/imported_search_context/imported_search_context_test.cpp b/searchlib/src/tests/attribute/imported_search_context/imported_search_context_test.cpp index 311d3ef71e7..61e66d384e1 100644 --- a/searchlib/src/tests/attribute/imported_search_context/imported_search_context_test.cpp +++ b/searchlib/src/tests/attribute/imported_search_context/imported_search_context_test.cpp @@ -467,7 +467,7 @@ struct SearchCacheFixture : Fixture { SearchCacheFixture::~SearchCacheFixture() = default; -BitVectorSearchCache::Entry::SP +std::shared_ptr<BitVectorSearchCache::Entry> makeSearchCacheEntry(const std::vector<uint32_t> docIds, uint32_t docIdLimit) { std::shared_ptr<BitVector> bitVector = BitVector::create(docIdLimit); diff --git a/searchlib/src/vespa/searchlib/attribute/attributemanager.cpp b/searchlib/src/vespa/searchlib/attribute/attributemanager.cpp index 2db35d1fd1e..8c1b453c354 100644 --- a/searchlib/src/vespa/searchlib/attribute/attributemanager.cpp +++ b/searchlib/src/vespa/searchlib/attribute/attributemanager.cpp @@ -151,12 +151,11 @@ AttributeManager::getAttributeRef(const string & name) const AttributeGuard::UP AttributeManager::getAttribute(const string & name) const { - AttributeGuard::UP attrGuard(new AttributeGuard(VectorHolder())); const VectorHolder * vh = findAndLoadAttribute(name); if ( vh != nullptr ) { - attrGuard.reset(new AttributeGuard(*vh)); + return std::make_unique<AttributeGuard>(*vh); } - return attrGuard; + return std::make_unique<AttributeGuard>(); } std::unique_ptr<attribute::AttributeReadGuard> diff --git a/searchlib/src/vespa/searchlib/attribute/bitvector_search_cache.cpp b/searchlib/src/vespa/searchlib/attribute/bitvector_search_cache.cpp index 4b8916273e7..70d34eef2ca 100644 --- a/searchlib/src/vespa/searchlib/attribute/bitvector_search_cache.cpp +++ b/searchlib/src/vespa/searchlib/attribute/bitvector_search_cache.cpp @@ -3,44 +3,45 @@ #include "bitvector_search_cache.h" #include <vespa/searchlib/common/bitvector.h> #include <vespa/vespalib/stllike/hash_map.hpp> +#include <mutex> namespace search::attribute { -using BitVectorSP = BitVectorSearchCache::BitVectorSP; +BitVectorSearchCache::BitVectorSearchCache() + : _mutex(), + _size(0), + _cache() +{} -BitVectorSearchCache::BitVectorSearchCache() = default; BitVectorSearchCache::~BitVectorSearchCache() = default; void -BitVectorSearchCache::insert(const vespalib::string &term, Entry::SP entry) +BitVectorSearchCache::insert(const vespalib::string &term, std::shared_ptr<Entry> entry) { - LockGuard guard(_mutex); + std::unique_lock guard(_mutex); _cache.insert(std::make_pair(term, std::move(entry))); + _size.store(_cache.size()); } -BitVectorSearchCache::Entry::SP +std::shared_ptr<BitVectorSearchCache::Entry> BitVectorSearchCache::find(const vespalib::string &term) const { - LockGuard guard(_mutex); - auto itr = _cache.find(term); - if (itr != _cache.end()) { - return itr->second; + if (size() > 0ul) { + std::shared_lock guard(_mutex); + auto itr = _cache.find(term); + if (itr != _cache.end()) { + return itr->second; + } } - return Entry::SP(); -} - -size_t -BitVectorSearchCache::size() const -{ - LockGuard guard(_mutex); - return _cache.size(); + return {}; } void BitVectorSearchCache::clear() { - LockGuard guard(_mutex); + std::unique_lock guard(_mutex); _cache.clear(); + _size.store(0ul, std::memory_order_relaxed); } } diff --git a/searchlib/src/vespa/searchlib/attribute/bitvector_search_cache.h b/searchlib/src/vespa/searchlib/attribute/bitvector_search_cache.h index 3936fb2ee67..455c27459cd 100644 --- a/searchlib/src/vespa/searchlib/attribute/bitvector_search_cache.h +++ b/searchlib/src/vespa/searchlib/attribute/bitvector_search_cache.h @@ -6,7 +6,8 @@ #include <vespa/vespalib/stllike/hash_map.h> #include <vespa/vespalib/stllike/string.h> #include <memory> -#include <mutex> +#include <shared_mutex> +#include <atomic> namespace search { class BitVector; } namespace search::attribute { @@ -22,7 +23,6 @@ public: using ReadGuardSP = IDocumentMetaStoreContext::IReadGuard::SP; struct Entry { - using SP = std::shared_ptr<Entry>; // We need to keep a document meta store read guard to ensure that no lids that are cached // in the bit vector are re-used until the guard is released. ReadGuardSP dmsReadGuard; @@ -33,18 +33,18 @@ public: }; private: - using LockGuard = std::lock_guard<std::mutex>; - using Cache = vespalib::hash_map<vespalib::string, Entry::SP>; + using Cache = vespalib::hash_map<vespalib::string, std::shared_ptr<Entry>>; - mutable std::mutex _mutex; + mutable std::shared_mutex _mutex; + std::atomic<uint64_t> _size; Cache _cache; public: BitVectorSearchCache(); ~BitVectorSearchCache(); - void insert(const vespalib::string &term, Entry::SP entry); - Entry::SP find(const vespalib::string &term) const; - size_t size() const; + void insert(const vespalib::string &term, std::shared_ptr<Entry> entry); + std::shared_ptr<Entry> find(const vespalib::string &term) const; + size_t size() const { return _size.load(std::memory_order_relaxed); } void clear(); }; diff --git a/searchlib/src/vespa/searchlib/attribute/imported_search_context.h b/searchlib/src/vespa/searchlib/attribute/imported_search_context.h index 77d09c55a41..3cbc9a3d97e 100644 --- a/searchlib/src/vespa/searchlib/attribute/imported_search_context.h +++ b/searchlib/src/vespa/searchlib/attribute/imported_search_context.h @@ -32,7 +32,7 @@ class ImportedSearchContext : public ISearchContext { const ImportedAttributeVector& _imported_attribute; vespalib::string _queryTerm; bool _useSearchCache; - BitVectorSearchCache::Entry::SP _searchCacheLookup; + std::shared_ptr<BitVectorSearchCache::Entry> _searchCacheLookup; IDocumentMetaStoreContext::IReadGuard::SP _dmsReadGuardFallback; const ReferenceAttribute& _reference_attribute; const IAttributeVector &_target_attribute; diff --git a/searchlib/src/vespa/searchlib/common/bitvectorcache.cpp b/searchlib/src/vespa/searchlib/common/bitvectorcache.cpp index 8bb24bcbbec..ea7fd5ee76c 100644 --- a/searchlib/src/vespa/searchlib/common/bitvectorcache.cpp +++ b/searchlib/src/vespa/searchlib/common/bitvectorcache.cpp @@ -4,19 +4,20 @@ #include <algorithm> #include <cassert> #include <cinttypes> +#include <mutex> #include <vespa/log/log.h> LOG_SETUP(".searchlib.common.bitvectorcache"); namespace search { -BitVectorCache::BitVectorCache(GenerationHolder &genHolder) : - _lookupCount(0), - _needPopulation(false), - _lock(), - _keys(), - _chunks(), - _genHolder(genHolder) +BitVectorCache::BitVectorCache(GenerationHolder &genHolder) + : _lookupCount(0), + _needPopulation(false), + _mutex(), + _keys(), + _chunks(), + _genHolder(genHolder) { } @@ -29,7 +30,7 @@ BitVectorCache::computeCountVector(KeySet & keys, CountVector & v) const std::vector<CondensedBitVector::KeySet> keySets; ChunkV chunks; { - std::lock_guard<std::mutex> guard(_lock); + std::shared_lock guard(_mutex); keySets.resize(_chunks.size()); Key2Index::const_iterator end(_keys.end()); for (Key k : keys) { @@ -61,13 +62,13 @@ BitVectorCache::KeySet BitVectorCache::lookupCachedSet(const KeyAndCountSet & keys) { KeySet cached(keys.size()*3); - std::lock_guard<std::mutex> guard(_lock); - _lookupCount++; - if (_lookupCount == 2000) { - _needPopulation = true; - } else if ((_lookupCount & 0x1fffff) == 0x100000) { - if (hasCostChanged(guard)) { - _needPopulation = true; + std::shared_lock shared_guard(_mutex); + uint64_t lookupCount = _lookupCount++; + if (lookupCount == 2000) { + requirePopulation(); + } else if ((lookupCount & 0x1fffff) == 0x100000) { + if (hasCostChanged(shared_guard)) { + requirePopulation(); } } for (const auto & e : keys) { @@ -79,7 +80,12 @@ BitVectorCache::lookupCachedSet(const KeyAndCountSet & keys) cached.insert(e.first); } } else { - _keys[e.first] = KeyMeta().lookup().bitCount(e.second); + shared_guard.unlock(); + { + std::unique_lock unique_guard(_mutex); + _keys[e.first] = KeyMeta().lookup().bitCount(e.second); + } + shared_guard.lock(); } } return cached; @@ -101,7 +107,7 @@ BitVectorCache::getSorted(Key2Index & keys) } bool -BitVectorCache::hasCostChanged(const std::lock_guard<std::mutex> & guard) +BitVectorCache::hasCostChanged(const std::shared_lock<std::shared_mutex> & guard) { (void) guard; if ( ! _chunks.empty()) { @@ -168,10 +174,8 @@ BitVectorCache::populate(Key2Index & newKeys, CondensedBitVector & chunk, const void BitVectorCache::populate(uint32_t sz, const PopulateInterface & lookup) { - std::unique_lock<std::mutex> guard(_lock); - if (! _needPopulation) { - return; - } + if (!needPopulation()) return; + std::unique_lock guard(_mutex); Key2Index newKeys(_keys); guard.unlock(); @@ -187,7 +191,7 @@ BitVectorCache::populate(uint32_t sz, const PopulateInterface & lookup) void BitVectorCache::set(Key key, uint32_t index, bool v) { - std::lock_guard<std::mutex> guard(_lock); + std::shared_lock guard(_mutex); auto found = _keys.find(key); if (found != _keys.end()) { const KeyMeta & m(found->second); @@ -207,7 +211,7 @@ BitVectorCache::get(Key key, uint32_t index) const void BitVectorCache::removeIndex(uint32_t index) { - std::lock_guard<std::mutex> guard(_lock); + std::unique_lock guard(_mutex); for (auto & chunk : _chunks) { chunk->clearIndex(index); } diff --git a/searchlib/src/vespa/searchlib/common/bitvectorcache.h b/searchlib/src/vespa/searchlib/common/bitvectorcache.h index 6fac1352d94..bb8f019c128 100644 --- a/searchlib/src/vespa/searchlib/common/bitvectorcache.h +++ b/searchlib/src/vespa/searchlib/common/bitvectorcache.h @@ -4,7 +4,7 @@ #include "condensedbitvectors.h" #include <vespa/vespalib/stllike/hash_set.h> #include <vespa/vespalib/stllike/hash_map.h> -#include <mutex> +#include <shared_mutex> namespace search { @@ -39,7 +39,7 @@ public: void removeIndex(uint32_t index); void adjustDocIdLimit(uint32_t docId); void populate(uint32_t count, const PopulateInterface &); - bool needPopulation() const { return _needPopulation; } + bool needPopulation() const { return _needPopulation.load(std::memory_order_relaxed); } void requirePopulation() { _needPopulation = true; } private: class KeyMeta { @@ -75,14 +75,14 @@ private: VESPA_DLL_LOCAL static SortedKeyMeta getSorted(Key2Index & keys); VESPA_DLL_LOCAL static void populate(Key2Index & newKeys, CondensedBitVector & chunk, const PopulateInterface & lookup); - VESPA_DLL_LOCAL bool hasCostChanged(const std::lock_guard<std::mutex> &); + VESPA_DLL_LOCAL bool hasCostChanged(const std::shared_lock<std::shared_mutex> &); - uint64_t _lookupCount; - bool _needPopulation; - mutable std::mutex _lock; - Key2Index _keys; - ChunkV _chunks; - GenerationHolder &_genHolder; + std::atomic<uint64_t> _lookupCount; + std::atomic<bool> _needPopulation; + mutable std::shared_mutex _mutex; + Key2Index _keys; + ChunkV _chunks; + GenerationHolder &_genHolder; }; } |