diff options
19 files changed, 97 insertions, 69 deletions
diff --git a/searchcore/src/tests/proton/documentdb/feedview/feedview_test.cpp b/searchcore/src/tests/proton/documentdb/feedview/feedview_test.cpp index f915ba9d898..5018b203216 100644 --- a/searchcore/src/tests/proton/documentdb/feedview/feedview_test.cpp +++ b/searchcore/src/tests/proton/documentdb/feedview/feedview_test.cpp @@ -36,7 +36,6 @@ using document::DocumentUpdate; using proton::matching::SessionManager; using proton::test::MockGidToLidChangeHandler; using search::AttributeVector; -using search::CacheStats; using search::DocumentMetaData; using vespalib::IDestructorCallback; using vespalib::Gate; @@ -49,6 +48,7 @@ using storage::spi::BucketChecksum; using storage::spi::BucketInfo; using storage::spi::Timestamp; using storage::spi::UpdateResult; +using vespalib::CacheStats; using vespalib::eval::ValueType; using namespace proton; diff --git a/searchcore/src/tests/proton/server/documentretriever_test.cpp b/searchcore/src/tests/proton/server/documentretriever_test.cpp index b4236ba4e3e..f5c163fefb5 100644 --- a/searchcore/src/tests/proton/server/documentretriever_test.cpp +++ b/searchcore/src/tests/proton/server/documentretriever_test.cpp @@ -71,7 +71,6 @@ using document::WSetHelper; using search::AttributeFactory; using search::AttributeGuard; using search::AttributeVector; -using search::CacheStats; using search::DocumentIdT; using search::DocumentMetaData; using search::FloatingPointAttribute; @@ -89,6 +88,7 @@ using search::tensor::TensorAttribute; using storage::spi::Bucket; using storage::spi::Timestamp; using storage::spi::test::makeSpiBucket; +using vespalib::CacheStats; using vespalib::make_string; using vespalib::string; using vespalib::eval::SimpleValue; diff --git a/searchcore/src/vespa/searchcore/proton/server/documentdb.h b/searchcore/src/vespa/searchcore/proton/server/documentdb.h index c842eb5ada7..078fce65ff2 100644 --- a/searchcore/src/vespa/searchcore/proton/server/documentdb.h +++ b/searchcore/src/vespa/searchcore/proton/server/documentdb.h @@ -23,8 +23,8 @@ #include <vespa/searchcore/proton/metrics/documentdb_job_trackers.h> #include <vespa/searchcore/proton/metrics/documentdb_tagged_metrics.h> #include <vespa/searchcore/proton/persistenceengine/i_resource_write_filter.h> -#include <vespa/searchlib/docstore/cachestats.h> #include <vespa/searchlib/transactionlog/syncproxy.h> +#include <vespa/vespalib/stllike/cache_stats.h> #include <vespa/vespalib/util/retain_guard.h> #include <vespa/vespalib/util/varholder.h> #include <mutex> diff --git a/searchcore/src/vespa/searchcore/proton/server/documentdb_metrics_updater.cpp b/searchcore/src/vespa/searchcore/proton/server/documentdb_metrics_updater.cpp index 4e156539441..d8ae75b40b1 100644 --- a/searchcore/src/vespa/searchcore/proton/server/documentdb_metrics_updater.cpp +++ b/searchcore/src/vespa/searchcore/proton/server/documentdb_metrics_updater.cpp @@ -16,7 +16,7 @@ #include <vespa/searchcore/proton/metrics/documentdb_job_trackers.h> #include <vespa/searchcore/proton/metrics/executor_threading_service_stats.h> #include <vespa/searchlib/attribute/attributevector.h> -#include <vespa/searchlib/docstore/cachestats.h> +#include <vespa/vespalib/stllike/cache_stats.h> #include <vespa/searchlib/util/searchable_stats.h> #include <vespa/vespalib/util/memoryusage.h> @@ -24,7 +24,7 @@ LOG_SETUP(".proton.server.documentdb_metrics_updater"); using search::LidUsageStats; -using search::CacheStats; +using vespalib::CacheStats; using vespalib::MemoryUsage; namespace proton { @@ -253,7 +253,7 @@ updateDocumentStoreMetrics(DocumentDBTaggedMetrics::SubDBMetrics::DocumentStoreM metrics.maxBucketSpread.set(storageStats.maxBucketSpread()); updateMemoryUsageMetrics(metrics.memoryUsage, backingStore.getMemoryUsage(), totalStats); - search::CacheStats cacheStats = backingStore.getCacheStats(); + vespalib::CacheStats cacheStats = backingStore.getCacheStats(); totalStats.memoryUsage.incAllocatedBytes(cacheStats.memory_used); metrics.cache.memoryUsage.set(cacheStats.memory_used); metrics.cache.elements.set(cacheStats.elements); diff --git a/searchcore/src/vespa/searchcore/proton/server/documentdb_metrics_updater.h b/searchcore/src/vespa/searchcore/proton/server/documentdb_metrics_updater.h index 381d98b2199..3c9c2eca103 100644 --- a/searchcore/src/vespa/searchcore/proton/server/documentdb_metrics_updater.h +++ b/searchcore/src/vespa/searchcore/proton/server/documentdb_metrics_updater.h @@ -3,7 +3,7 @@ #include "feed_handler_stats.h" #include <vespa/searchcore/proton/metrics/documentdb_tagged_metrics.h> -#include <vespa/searchlib/docstore/cachestats.h> +#include <vespa/vespalib/stllike/cache_stats.h> #include <optional> namespace proton { @@ -25,9 +25,9 @@ class DocumentDBMetricsUpdater { public: struct DocumentStoreCacheStats { - search::CacheStats readySubDb; - search::CacheStats notReadySubDb; - search::CacheStats removedSubDb; + vespalib::CacheStats readySubDb; + vespalib::CacheStats notReadySubDb; + vespalib::CacheStats removedSubDb; DocumentStoreCacheStats() : readySubDb(), notReadySubDb(), removedSubDb() {} }; diff --git a/searchcore/src/vespa/searchcore/proton/test/dummy_document_store.h b/searchcore/src/vespa/searchcore/proton/test/dummy_document_store.h index 7194cc4d403..9e0e8f66dc0 100644 --- a/searchcore/src/vespa/searchcore/proton/test/dummy_document_store.h +++ b/searchcore/src/vespa/searchcore/proton/test/dummy_document_store.h @@ -1,7 +1,7 @@ // Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. #pragma once -#include <vespa/searchlib/docstore/cachestats.h> +#include <vespa/vespalib/stllike/cache_stats.h> #include <vespa/searchlib/docstore/idocumentstore.h> namespace proton::test { @@ -34,7 +34,7 @@ struct DummyDocumentStore : public search::IDocumentStore size_t getDiskFootprint() const override { return 0; } size_t getDiskBloat() const override { return 0; } size_t getMaxSpreadAsBloat() const override { return getDiskBloat(); } - search::CacheStats getCacheStats() const override { return search::CacheStats(); } + vespalib::CacheStats getCacheStats() const override { return vespalib::CacheStats(); } const vespalib::string &getBaseDir() const override { return _baseDir; } void accept(search::IDocumentStoreReadVisitor &, search::IDocumentStoreVisitorProgress &, diff --git a/searchlib/src/tests/docstore/document_store/document_store_test.cpp b/searchlib/src/tests/docstore/document_store/document_store_test.cpp index 0483ea26423..5050592dc87 100644 --- a/searchlib/src/tests/docstore/document_store/document_store_test.cpp +++ b/searchlib/src/tests/docstore/document_store/document_store_test.cpp @@ -2,7 +2,7 @@ #include <vespa/vespalib/testkit/test_kit.h> #include <vespa/searchlib/docstore/logdocumentstore.h> #include <vespa/searchlib/docstore/value.h> -#include <vespa/searchlib/docstore/cachestats.h> +#include <vespa/vespalib/stllike/cache_stats.h> #include <vespa/document/repo/documenttyperepo.h> #include <vespa/document/fieldvalue/document.h> diff --git a/searchlib/src/tests/docstore/document_store_visitor/document_store_visitor_test.cpp b/searchlib/src/tests/docstore/document_store_visitor/document_store_visitor_test.cpp index c08aa7ce9fc..e811e68f4b5 100644 --- a/searchlib/src/tests/docstore/document_store_visitor/document_store_visitor_test.cpp +++ b/searchlib/src/tests/docstore/document_store_visitor/document_store_visitor_test.cpp @@ -3,7 +3,7 @@ #include <vespa/vespalib/testkit/test_kit.h> #include <vespa/searchlib/docstore/documentstore.h> #include <vespa/searchlib/docstore/logdocumentstore.h> -#include <vespa/searchlib/docstore/cachestats.h> +#include <vespa/vespalib/stllike/cache_stats.h> #include <vespa/searchlib/index/dummyfileheadercontext.h> #include <vespa/searchlib/common/bitvector.h> #include <vespa/document/repo/documenttyperepo.h> diff --git a/searchlib/src/tests/docstore/logdatastore/logdatastore_test.cpp b/searchlib/src/tests/docstore/logdatastore/logdatastore_test.cpp index bb2d0177dd9..fffa1778c85 100644 --- a/searchlib/src/tests/docstore/logdatastore/logdatastore_test.cpp +++ b/searchlib/src/tests/docstore/logdatastore/logdatastore_test.cpp @@ -13,6 +13,7 @@ #include <vespa/searchlib/index/dummyfileheadercontext.h> #include <vespa/searchlib/test/directory_handler.h> #include <vespa/vespalib/stllike/asciistream.h> +#include <vespa/vespalib/stllike/cache_stats.h> #include <vespa/vespalib/test/insertion_operators.h> #include <vespa/vespalib/util/exceptions.h> #include <vespa/vespalib/util/threadstackexecutor.h> @@ -24,6 +25,7 @@ using document::StringFieldValue; using namespace search::docstore; using namespace search; using namespace vespalib::alloc; +using vespalib::CacheStats; using search::index::DummyFileHeaderContext; using search::test::DirectoryHandler; diff --git a/searchlib/src/vespa/searchlib/docstore/documentstore.cpp b/searchlib/src/vespa/searchlib/docstore/documentstore.cpp index b4ff050c0f6..0853672e949 100644 --- a/searchlib/src/vespa/searchlib/docstore/documentstore.cpp +++ b/searchlib/src/vespa/searchlib/docstore/documentstore.cpp @@ -1,6 +1,5 @@ // Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -#include "cachestats.h" #include "documentstore.h" #include "visitcache.h" #include "ibucketizer.h" @@ -16,6 +15,7 @@ LOG_SETUP(".searchlib.docstore.documentstore"); using document::DocumentTypeRepo; +using vespalib::CacheStats; using vespalib::compression::CompressionConfig; namespace search { @@ -437,8 +437,8 @@ DocumentStore::getFileChunkStats() const CacheStats DocumentStore::getCacheStats() const { CacheStats visitStats = _visitCache->getCacheStats(); - CacheStats singleStats(_cache->getHit(), _cache->getMiss() + _uncached_lookups, - _cache->size(), _cache->sizeBytes(), _cache->getInvalidate()); + CacheStats singleStats = _cache->get_stats(); + singleStats.add_extra_misses(_uncached_lookups.load(std::memory_order_relaxed)); singleStats += visitStats; return singleStats; } diff --git a/searchlib/src/vespa/searchlib/docstore/documentstore.h b/searchlib/src/vespa/searchlib/docstore/documentstore.h index 6402c16cd5e..6270108efb8 100644 --- a/searchlib/src/vespa/searchlib/docstore/documentstore.h +++ b/searchlib/src/vespa/searchlib/docstore/documentstore.h @@ -82,7 +82,7 @@ public: size_t getDiskFootprint() const override { return _backingStore.getDiskFootprint(); } size_t getDiskBloat() const override { return _backingStore.getDiskBloat(); } size_t getMaxSpreadAsBloat() const override { return _backingStore.getMaxSpreadAsBloat(); } - CacheStats getCacheStats() const override; + vespalib::CacheStats getCacheStats() const override; size_t memoryMeta() const override { return _backingStore.memoryMeta(); } const vespalib::string & getBaseDir() const override { return _backingStore.getBaseDir(); } void accept(IDocumentStoreReadVisitor &visitor, IDocumentStoreVisitorProgress &visitorProgress, diff --git a/searchlib/src/vespa/searchlib/docstore/idocumentstore.h b/searchlib/src/vespa/searchlib/docstore/idocumentstore.h index d84a5ad7e7e..08983efb0da 100644 --- a/searchlib/src/vespa/searchlib/docstore/idocumentstore.h +++ b/searchlib/src/vespa/searchlib/docstore/idocumentstore.h @@ -12,12 +12,13 @@ namespace document { class DocumentTypeRepo; } -namespace vespalib { class nbostream; } +namespace vespalib { +class CacheStats; +class nbostream; +} namespace search { -struct CacheStats; - class IDocumentStoreReadVisitor { public: @@ -163,7 +164,7 @@ public: /** * Returns statistics about the cache. */ - virtual CacheStats getCacheStats() const = 0; + virtual vespalib::CacheStats getCacheStats() const = 0; /** * Returns the base directory from which all structures are stored. diff --git a/searchlib/src/vespa/searchlib/docstore/visitcache.cpp b/searchlib/src/vespa/searchlib/docstore/visitcache.cpp index c37fe30b421..fd6146dae47 100644 --- a/searchlib/src/vespa/searchlib/docstore/visitcache.cpp +++ b/searchlib/src/vespa/searchlib/docstore/visitcache.cpp @@ -11,6 +11,7 @@ namespace search::docstore { +using vespalib::CacheStats; using vespalib::ConstBufferRef; using vespalib::DataBuffer; using vespalib::alloc::Alloc; @@ -221,7 +222,7 @@ VisitCache::remove(uint32_t key) { CacheStats VisitCache::getCacheStats() const { - return CacheStats(_cache->getHit(), _cache->getMiss(), _cache->size(), _cache->sizeBytes(), _cache->getInvalidate()); + return _cache->get_stats(); } VisitCache::Cache::Cache(BackingStore & b, size_t maxBytes) : diff --git a/searchlib/src/vespa/searchlib/docstore/visitcache.h b/searchlib/src/vespa/searchlib/docstore/visitcache.h index 1e2dbd29062..558f01f5e80 100644 --- a/searchlib/src/vespa/searchlib/docstore/visitcache.h +++ b/searchlib/src/vespa/searchlib/docstore/visitcache.h @@ -3,7 +3,6 @@ #pragma once #include "idocumentstore.h" -#include "cachestats.h" #include <vespa/vespalib/stllike/cache.h> #include <vespa/vespalib/stllike/hash_set.h> #include <vespa/vespalib/stllike/hash_map.h> @@ -105,7 +104,7 @@ public: void remove(uint32_t key); void invalidate(uint32_t key) { remove(key); } - CacheStats getCacheStats() const; + vespalib::CacheStats getCacheStats() const; void reconfigure(size_t cacheSize, const CompressionConfig &compression); private: /** diff --git a/staging_vespalib/src/vespa/vespalib/stllike/cache.h b/staging_vespalib/src/vespa/vespalib/stllike/cache.h index 181bb2ac63a..bf58f1aef98 100644 --- a/staging_vespalib/src/vespa/vespalib/stllike/cache.h +++ b/staging_vespalib/src/vespa/vespalib/stllike/cache.h @@ -1,12 +1,14 @@ // Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. #pragma once -#include <vespa/vespalib/stllike/lrucache_map.h> +#include "lrucache_map.h" #include <atomic> #include <mutex> namespace vespalib { +struct CacheStats; + template<typename K, typename V> class NullStore { public: @@ -74,9 +76,9 @@ public: cache & setCapacityBytes(size_t sz); size_t capacity() const { return Lru::capacity(); } - size_t capacityBytes() const { return _maxBytes; } + size_t capacityBytes() const { return _maxBytes.load(std::memory_order_relaxed); } size_t size() const { return Lru::size(); } - size_t sizeBytes() const { return _sizeBytes; } + size_t sizeBytes() const { return _sizeBytes.load(std::memory_order_relaxed); } bool empty() const { return Lru::empty(); } /** @@ -109,15 +111,16 @@ public: */ bool hasKey(const K & key) const; - size_t getHit() const { return _hit; } - size_t getMiss() const { return _miss; } - size_t getNoneExisting() const { return _noneExisting; } - size_t getRace() const { return _race; } - size_t getInsert() const { return _insert; } - size_t getWrite() const { return _write; } - size_t getErase() const { return _erase; } - size_t getInvalidate() const { return _invalidate; } - size_t getlookup() const { return _lookup; } + CacheStats get_stats() const; + + size_t getHit() const { return _hit.load(std::memory_order_relaxed); } + size_t getMiss() const { return _miss.load(std::memory_order_relaxed); } + size_t getNoneExisting() const { return _noneExisting.load(std::memory_order_relaxed); } + size_t getRace() const { return _race.load(std::memory_order_relaxed); } + size_t getInsert() const { return _insert.load(std::memory_order_relaxed); } + size_t getWrite() const { return _write.load(std::memory_order_relaxed); } + size_t getInvalidate() const { return _invalidate.load(std::memory_order_relaxed); } + size_t getlookup() const { return _lookup.load(std::memory_order_relaxed); } protected: using UniqueLock = std::unique_lock<std::mutex>; @@ -138,21 +141,30 @@ private: size_t h(_hasher(k)); return _addLocks[h%(sizeof(_addLocks)/sizeof(_addLocks[0]))]; } + + template <typename V> + static void increment_stat(std::atomic<V>& v, const std::lock_guard<std::mutex>&) { + v.store(v.load(std::memory_order_relaxed) + 1, std::memory_order_relaxed); + } + template <typename V> + static void increment_stat(std::atomic<V>& v, const std::unique_lock<std::mutex>&) { + v.store(v.load(std::memory_order_relaxed) + 1, std::memory_order_relaxed); + } + Hash _hasher; SizeK _sizeK; SizeV _sizeV; - size_t _maxBytes; - size_t _sizeBytes; - mutable size_t _hit; - mutable size_t _miss; - std::atomic<size_t> _noneExisting; - mutable size_t _race; - mutable size_t _insert; - mutable size_t _write; - mutable size_t _update; - mutable size_t _erase; - mutable size_t _invalidate; - mutable size_t _lookup; + std::atomic<size_t> _maxBytes; + std::atomic<size_t> _sizeBytes; + mutable std::atomic<size_t> _hit; + mutable std::atomic<size_t> _miss; + std::atomic<size_t> _noneExisting; + mutable std::atomic<size_t> _race; + mutable std::atomic<size_t> _insert; + mutable std::atomic<size_t> _write; + mutable std::atomic<size_t> _update; + mutable std::atomic<size_t> _invalidate; + mutable std::atomic<size_t> _lookup; BackingStore & _store; mutable std::mutex _hashLock; /// Striped locks that can be used for having a locked access to the backing store. diff --git a/staging_vespalib/src/vespa/vespalib/stllike/cache.hpp b/staging_vespalib/src/vespa/vespalib/stllike/cache.hpp index 880b5abf2f1..bb05d564f1f 100644 --- a/staging_vespalib/src/vespa/vespalib/stllike/cache.hpp +++ b/staging_vespalib/src/vespa/vespalib/stllike/cache.hpp @@ -2,6 +2,7 @@ #pragma once #include "cache.h" +#include "cache_stats.h" #include "lrucache_map.hpp" namespace vespalib { @@ -23,7 +24,7 @@ cache<P>::reserveElements(size_t elems) { template< typename P > cache<P> & cache<P>::setCapacityBytes(size_t sz) { - _maxBytes = sz; + _maxBytes.store(sz, std::memory_order_relaxed); return *this; } @@ -56,7 +57,6 @@ cache<P>::cache(BackingStore & b, size_t maxBytes) : _insert(0), _write(0), _update(0), - _erase(0), _invalidate(0), _lookup(0), _store(b) @@ -67,7 +67,7 @@ bool cache<P>::removeOldest(const value_type & v) { bool remove(Lru::removeOldest(v) || (sizeBytes() >= capacityBytes())); if (remove) { - _sizeBytes -= calcSize(v.first, v.second._value); + _sizeBytes.store(sizeBytes() - calcSize(v.first, v.second._value), std::memory_order_relaxed); } return remove; } @@ -85,10 +85,10 @@ cache<P>::read(const K & key) { std::lock_guard guard(_hashLock); if (Lru::hasKey(key)) { - _hit++; + increment_stat(_hit, guard); return (*this)[key]; } else { - _miss++; + increment_stat(_miss, guard); } } @@ -97,7 +97,7 @@ cache<P>::read(const K & key) std::lock_guard guard(_hashLock); if (Lru::hasKey(key)) { // Somebody else just fetched it ahead of me. - _race++; + increment_stat(_race, guard); return (*this)[key]; } } @@ -105,8 +105,8 @@ cache<P>::read(const K & key) if (_store.read(key, value)) { std::lock_guard guard(_hashLock); Lru::insert(key, value); - _sizeBytes += calcSize(key, value); - _insert++; + _sizeBytes.store(sizeBytes() + calcSize(key, value), std::memory_order_relaxed); + increment_stat(_insert, guard); } else { _noneExisting.fetch_add(1); } @@ -122,8 +122,8 @@ cache<P>::write(const K & key, V value) { std::lock_guard guard(_hashLock); if (Lru::hasKey(key)) { - _sizeBytes -= calcSize(key, (*this)[key]); - _update++; + _sizeBytes.store(sizeBytes() - calcSize(key, (*this)[key]), std::memory_order_relaxed); + increment_stat(_update, guard); } } @@ -131,8 +131,8 @@ cache<P>::write(const K & key, V value) { std::lock_guard guard(_hashLock); (*this)[key] = std::move(value); - _sizeBytes += newSize; - _write++; + _sizeBytes.store(sizeBytes() + newSize, std::memory_order_relaxed); + increment_stat(_write, guard); } } @@ -151,8 +151,8 @@ cache<P>::invalidate(const UniqueLock & guard, const K & key) { verifyHashLock(guard); if (Lru::hasKey(key)) { - _sizeBytes -= calcSize(key, (*this)[key]); - _invalidate++; + _sizeBytes.store(sizeBytes() - calcSize(key, (*this)[key]), std::memory_order_relaxed); + increment_stat(_invalidate, guard); Lru::erase(key); } } @@ -162,7 +162,7 @@ bool cache<P>::hasKey(const UniqueLock & guard, const K & key) const { verifyHashLock(guard); - _lookup++; + increment_stat(_lookup, guard); return Lru::hasKey(key); } @@ -173,5 +173,13 @@ cache<P>::verifyHashLock(const UniqueLock & guard) const { assert(guard.owns_lock()); } +template <typename P> +CacheStats +cache<P>::get_stats() const +{ + std::lock_guard guard(_hashLock); + return CacheStats(getHit(), getMiss(), Lru::size(), sizeBytes(), getInvalidate()); +} + } diff --git a/searchlib/src/vespa/searchlib/docstore/cachestats.h b/staging_vespalib/src/vespa/vespalib/stllike/cache_stats.h index 4bad9b48fa3..7c83da2b004 100644 --- a/searchlib/src/vespa/searchlib/docstore/cachestats.h +++ b/staging_vespalib/src/vespa/vespalib/stllike/cache_stats.h @@ -5,7 +5,7 @@ #include <cstdint> #include <sys/types.h> -namespace search { +namespace vespalib { struct CacheStats { size_t hits; @@ -41,6 +41,8 @@ struct CacheStats { return *this; } + void add_extra_misses(size_t extra_misses) { misses += extra_misses; } + size_t lookups() const { return hits + misses; } }; diff --git a/staging_vespalib/src/vespa/vespalib/stllike/lrucache_map.h b/staging_vespalib/src/vespa/vespalib/stllike/lrucache_map.h index 4c7f0fa3b4a..ffb7a427d11 100644 --- a/staging_vespalib/src/vespa/vespalib/stllike/lrucache_map.h +++ b/staging_vespalib/src/vespa/vespalib/stllike/lrucache_map.h @@ -4,6 +4,7 @@ #include <vespa/vespalib/stllike/hashtable.h> #include <vespa/vespalib/stllike/hash_fun.h> #include <vespa/vespalib/stllike/select.h> +#include <atomic> #include <vector> namespace vespalib { @@ -90,7 +91,7 @@ public: virtual ~lrucache_map(); lrucache_map & maxElements(size_t elems) { - _maxElements = elems; + _maxElements.store(elems, std::memory_order_relaxed); return *this; } lrucache_map & reserve(size_t elems) { @@ -99,7 +100,7 @@ public: } - size_t capacity() const { return _maxElements; } + size_t capacity() const { return _maxElements.load(std::memory_order_relaxed); } size_t size() const { return HashTable::size(); } bool empty() const { return HashTable::empty(); } iterator begin() { return iterator(this, _head); } @@ -199,7 +200,7 @@ private: lrucache_map & _lru; }; - size_t _maxElements; + std::atomic<size_t> _maxElements; mutable uint32_t _head; mutable uint32_t _tail; bool _moveRecordingEnabled; diff --git a/staging_vespalib/src/vespa/vespalib/stllike/lrucache_map.hpp b/staging_vespalib/src/vespa/vespalib/stllike/lrucache_map.hpp index 138f1e05eea..73e9956ffdf 100644 --- a/staging_vespalib/src/vespa/vespalib/stllike/lrucache_map.hpp +++ b/staging_vespalib/src/vespa/vespalib/stllike/lrucache_map.hpp @@ -80,7 +80,9 @@ lrucache_map<P>::~lrucache_map() = default; template< typename P > void lrucache_map<P>::swap(lrucache_map & rhs) { - std::swap(_maxElements, rhs._maxElements); + auto maxElements = rhs._maxElements.load(std::memory_order_relaxed); + rhs._maxElements.store(_maxElements.load(std::memory_order_relaxed), std::memory_order_relaxed); + _maxElements.store(maxElements, std::memory_order_relaxed); std::swap(_head, rhs._head); std::swap(_tail, rhs._tail); HashTable::swap(rhs); |