20#ifndef SHARDED_CACHE_H
21#define SHARDED_CACHE_H
23#if defined (__MINGW32__)
24#ifdef BS_THREAD_POOL_NATIVE_EXTENSIONS
36#include <shared_mutex>
37#include <unordered_map>
51template <
typename KEY,
typename VALUE, std::
size_t SHARDS = 256>
56 bool Get(
const KEY& aKey,
VALUE& aValue )
const
59 std::shared_lock<std::shared_mutex> lock( shard.
mutex );
61 auto it = shard.
map.find( aKey );
63 if( it == shard.
map.end() )
70 void Set(
const KEY& aKey,
const VALUE& aValue )
73 std::unique_lock<std::shared_mutex> lock( shard.
mutex );
75 shard.
map[aKey] = aValue;
89 std::unique_lock<std::shared_mutex> lock( shard.mutex );
98 tp.submit_loop( std::size_t( 0 ), SHARDS,
99 [
this]( std::size_t aShard )
101 std::unique_lock<std::shared_mutex> lock(
m_shards[aShard].mutex );
111 std::shared_lock<std::shared_mutex> lock( shard.mutex );
113 if( !shard.map.empty() )
127 std::size_t total = 0;
131 std::shared_lock<std::shared_mutex> lock( shard.mutex );
132 total += shard.map.size();
141 std::unordered_map<KEY, VALUE>
map;
146 return m_shards[std::hash<KEY>{}( aKey ) % SHARDS];
151 return m_shards[std::hash<KEY>{}( aKey ) % SHARDS];
A concurrent key/value cache split into independently locked shards.
const SHARD & shardFor(const KEY &aKey) const
std::array< SHARD, SHARDS > m_shards
bool Get(const KEY &aKey, VALUE &aValue) const
Look up a key. Returns false on a miss and leaves aValue untouched.
std::size_t Size() const
Only Clear() needs this; an exact concurrent size has no sound external use, so private.
void Set(const KEY &aKey, const VALUE &aValue)
SHARD & shardFor(const KEY &aKey)
static constexpr std::size_t PARALLEL_CLEAR_THRESHOLD
Entry count above which Clear() fans its per-shard deallocation across the worker pool.
std::unordered_map< KEY, VALUE > map
@ VALUE
Field Value of part, i.e. "3.3K".
thread_pool & GetKiCadThreadPool()
Get a reference to the current thread pool.
BS::priority_thread_pool thread_pool