diff --git a/ReactCommon/utils/BUCK b/ReactCommon/utils/BUCK index e086a4a0e..dd317a18e 100644 --- a/ReactCommon/utils/BUCK +++ b/ReactCommon/utils/BUCK @@ -26,6 +26,10 @@ rn_xplat_cxx_library( "PUBLIC", ], deps = [ + "fbsource//xplat/folly:evicting_cache_map", + "fbsource//xplat/folly:headers_only", + "fbsource//xplat/folly:memory", + "fbsource//xplat/folly:molly", react_native_xplat_target("better:better"), ], ) diff --git a/ReactCommon/utils/SimpleThreadSafeCache.h b/ReactCommon/utils/SimpleThreadSafeCache.h new file mode 100644 index 000000000..2d525d917 --- /dev/null +++ b/ReactCommon/utils/SimpleThreadSafeCache.h @@ -0,0 +1,74 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +#include +#include +#include + +#include +#include + +namespace facebook { +namespace react { + +/* + * Simple thread-safe LRU cache. + */ +template +class SimpleThreadSafeCache { +public: + SimpleThreadSafeCache() : map_{maxSize} {} + + /* + * Returns a value from the map with a given key. + * If the value wasn't found in the cache, constructs the value using given + * generator function, stores it inside a cache and returns it. + * Can be called from any thread. + */ + ValueT get(const KeyT &key, std::function generator) const { + std::lock_guard lock(mutex_); + auto iterator = map_.find(key); + if (iterator == map_.end()) { + auto value = generator(key); + map_.set(key, value); + return value; + } + + return iterator->second; + } + + /* + * Returns a value from the map with a given key. + * If the value wasn't found in the cache, returns empty optional. + * Can be called from any thread. + */ + better::optional get(const KeyT &key) const { + std::lock_guard lock(mutex_); + auto iterator = map_.find(key); + if (iterator == map_.end()) { + return {}; + } + + return iterator->second; + } + + /* + * Sets a key-value pair in the LRU cache. + * Can be called from any thread. + */ + void set(const KeyT &key, const ValueT &value) const { + std::lock_guard lock(mutex_); + map_.set(std::move(key), std::move(value)); + } + +private: + mutable folly::EvictingCacheMap map_; + mutable std::mutex mutex_; +}; + +} // namespace react +} // namespace facebook