1 /* 2 * Copyright (c) Meta Platforms, Inc. and affiliates. 3 * 4 * This source code is licensed under the MIT license found in the 5 * LICENSE file in the root directory of this source tree. 6 */ 7 8 #include <functional> 9 #include <memory> 10 #include <mutex> 11 #include <optional> 12 13 #include <folly/container/EvictingCacheMap.h> 14 15 namespace ABI49_0_0facebook { 16 namespace ABI49_0_0React { 17 18 /* 19 * Simple thread-safe LRU cache. 20 */ 21 template <typename KeyT, typename ValueT, int maxSize> 22 class SimpleThreadSafeCache { 23 public: SimpleThreadSafeCache()24 SimpleThreadSafeCache() : map_{maxSize} {} SimpleThreadSafeCache(unsigned long size)25 SimpleThreadSafeCache(unsigned long size) : map_{size} {} 26 27 /* 28 * Returns a value from the map with a given key. 29 * If the value wasn't found in the cache, constructs the value using given 30 * generator function, stores it inside a cache and returns it. 31 * Can be called from any thread. 32 */ get(const KeyT & key,std::function<ValueT (const KeyT & key)> generator)33 ValueT get(const KeyT &key, std::function<ValueT(const KeyT &key)> generator) 34 const { 35 std::lock_guard<std::mutex> lock(mutex_); 36 auto iterator = map_.find(key); 37 if (iterator == map_.end()) { 38 auto value = generator(key); 39 map_.set(key, value); 40 return value; 41 } 42 43 return iterator->second; 44 } 45 46 /* 47 * Returns a value from the map with a given key. 48 * If the value wasn't found in the cache, returns empty optional. 49 * Can be called from any thread. 50 */ get(const KeyT & key)51 std::optional<ValueT> get(const KeyT &key) const { 52 std::lock_guard<std::mutex> lock(mutex_); 53 auto iterator = map_.find(key); 54 if (iterator == map_.end()) { 55 return {}; 56 } 57 58 return iterator->second; 59 } 60 61 /* 62 * Sets a key-value pair in the LRU cache. 63 * Can be called from any thread. 64 */ set(const KeyT & key,const ValueT & value)65 void set(const KeyT &key, const ValueT &value) const { 66 std::lock_guard<std::mutex> lock(mutex_); 67 map_.set(std::move(key), std::move(value)); 68 } 69 70 private: 71 mutable folly::EvictingCacheMap<KeyT, ValueT> map_; 72 mutable std::mutex mutex_; 73 }; 74 75 } // namespace ABI49_0_0React 76 } // namespace ABI49_0_0facebook 77