1 #ifndef GENESIS_UTILS_CONTAINERS_FUNCTION_CACHE_H_
2 #define GENESIS_UTILS_CONTAINERS_FUNCTION_CACHE_H_
43 #include <unordered_map>
80 template <
typename R,
typename... A>
95 using container_type = std::unordered_map<key_type, value_type, genesis::utils::hash<key_type>>;
128 : load_function_( load_function )
131 throw std::invalid_argument(
"Cannot initialize FunctionCache with shards==0" );
133 shards_.reserve( shards );
134 for(
size_t i = 0; i < shards; ++i ) {
137 shards_.push_back( genesis::utils::make_unique<Shard>() );
159 for(
auto const& shard : shards_ ) {
160 std::lock_guard<std::mutex> lock( shard->guard_ );
161 result += shard->cache_.size();
173 auto result = std::vector<size_t>( shards_.size(), 0 );
174 for(
size_t i = 0; i < shards_.size(); ++i ) {
175 auto const& shard = shards_[i];
176 std::lock_guard<std::mutex> lock( shard->guard_ );
177 result[i] = shard->cache_.size();
199 for(
auto& shard : shards_ ) {
200 std::lock_guard<std::mutex> lock( shard->guard_ );
201 shard->cache_.clear();
262 std::tuple<A...>
const key( arguments... );
265 assert( shard_index_( key ) < shards_.size() );
266 assert( shards_[ shard_index_( key ) ] );
267 auto& shard = *shards_[ shard_index_( key ) ];
270 std::lock_guard<std::mutex> lock( shard.guard_ );
275 return shard.cache_[key] = load_function_( arguments... );
279 auto search = shard.cache_.find( key );
280 if( search != shard.cache_.end() ) {
282 return search->second;
287 return shard.cache_[key] = load_function_( arguments... );
297 std::tuple<A...>
const key( arguments... );
298 auto& shard = *shards_[ shard_index_( key ) ];
299 std::lock_guard<std::mutex> lock( shard.guard_ );
300 auto search = shard.cache_.find( key );
301 return search != shard.cache_.end();
310 size_t shard_index_(
key_type const& key )
const
326 std::function<R(A...)> load_function_;
331 std::vector<std::unique_ptr<Shard>> shards_;
334 bool enabled_ =
true;
338 size_t hit_count_ = 0;
339 size_t miss_count_ = 0;
346 #endif // include guard