mirror of
https://github.com/facebook/react-native.git
synced 2025-11-01 09:14:26 +00:00
Remove folly::EvictingCacheMap (#52019)
Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/52019 Replace folly::EvictionMap with pure std implementation changelog: [internal][Breaking] Remove unused set() method of SimpleThreadSafeCache Reviewed By: javache, sammy-SC Differential Revision: D76631579 fbshipit-source-id: 15dfa8a8c0d2809440c214a72e48def6e1dba2f0
This commit is contained in:
committed by
Facebook GitHub Bot
parent
2528e48e93
commit
089fb10740
@@ -8,11 +8,9 @@
|
||||
#pragma once
|
||||
|
||||
#include <concepts>
|
||||
#include <list>
|
||||
#include <mutex>
|
||||
#include <optional>
|
||||
#include <type_traits>
|
||||
|
||||
#include <folly/container/EvictingCacheMap.h>
|
||||
#include <unordered_map>
|
||||
|
||||
namespace facebook::react {
|
||||
|
||||
@@ -26,8 +24,8 @@ concept CacheGeneratorFunction = std::invocable<GeneratorT> &&
|
||||
template <typename KeyT, typename ValueT, int maxSize>
|
||||
class SimpleThreadSafeCache {
|
||||
public:
|
||||
SimpleThreadSafeCache() : map_{maxSize} {}
|
||||
SimpleThreadSafeCache(unsigned long size) : map_{size} {}
|
||||
SimpleThreadSafeCache() : maxSize_(maxSize) {}
|
||||
SimpleThreadSafeCache(unsigned long size) : maxSize_{size} {}
|
||||
|
||||
/*
|
||||
* Returns a value from the map with a given key.
|
||||
@@ -38,14 +36,23 @@ class SimpleThreadSafeCache {
|
||||
ValueT get(const KeyT& key, CacheGeneratorFunction<ValueT> auto generator)
|
||||
const {
|
||||
std::lock_guard<std::mutex> lock(mutex_);
|
||||
auto iterator = map_.find(key);
|
||||
if (iterator == map_.end()) {
|
||||
auto value = generator();
|
||||
map_.set(key, value);
|
||||
return value;
|
||||
|
||||
if (auto it = map_.find(key); it != map_.end()) {
|
||||
// Move accessed item to front of list
|
||||
list_.splice(list_.begin(), list_, it->second);
|
||||
return it->second->second;
|
||||
}
|
||||
|
||||
return iterator->second;
|
||||
auto value = generator();
|
||||
// Add new value to front of list and map
|
||||
list_.emplace_front(key, value);
|
||||
map_[key] = list_.begin();
|
||||
if (list_.size() > maxSize_) {
|
||||
// Evict least recently used item (back of list)
|
||||
map_.erase(list_.back().first);
|
||||
list_.pop_back();
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -55,26 +62,24 @@ class SimpleThreadSafeCache {
|
||||
*/
|
||||
std::optional<ValueT> get(const KeyT& key) const {
|
||||
std::lock_guard<std::mutex> lock(mutex_);
|
||||
auto iterator = map_.find(key);
|
||||
if (iterator == map_.end()) {
|
||||
return {};
|
||||
|
||||
if (auto it = map_.find(key); it != map_.end()) {
|
||||
// Move accessed item to front of list
|
||||
list_.splice(list_.begin(), list_, it->second);
|
||||
return it->second->second;
|
||||
}
|
||||
|
||||
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<std::mutex> lock(mutex_);
|
||||
map_.set(std::move(key), std::move(value));
|
||||
return ValueT{};
|
||||
}
|
||||
|
||||
private:
|
||||
mutable folly::EvictingCacheMap<KeyT, ValueT> map_;
|
||||
using EntryT = std::pair<KeyT, ValueT>;
|
||||
using iterator = typename std::list<EntryT>::iterator;
|
||||
|
||||
size_t maxSize_;
|
||||
mutable std::mutex mutex_;
|
||||
mutable std::list<EntryT> list_;
|
||||
mutable std::unordered_map<KeyT, iterator> map_;
|
||||
};
|
||||
|
||||
} // namespace facebook::react
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
#include <react/utils/SimpleThreadSafeCache.h>
|
||||
|
||||
namespace facebook::react {
|
||||
|
||||
TEST(EvictingCacheMapTest, BasicInsertAndGet) {
|
||||
SimpleThreadSafeCache<int, std::string, 3> cache;
|
||||
EXPECT_EQ(cache.get(1), ""); // Default constructed value is returned
|
||||
EXPECT_EQ(cache.get(2), ""); // Default constructed value is returned
|
||||
EXPECT_EQ(cache.get(3), ""); // Default constructed value is returned
|
||||
|
||||
cache.get(1, []() { return std::string("one"); });
|
||||
cache.get(2, []() { return std::string("two"); });
|
||||
cache.get(3, []() { return std::string("three"); });
|
||||
EXPECT_EQ(cache.get(1), "one");
|
||||
EXPECT_EQ(cache.get(2), "two");
|
||||
EXPECT_EQ(cache.get(3), "three");
|
||||
}
|
||||
|
||||
TEST(EvictingCacheMapTest, Eviction) {
|
||||
SimpleThreadSafeCache<int, std::string, 2> cache;
|
||||
cache.get(1, []() { return std::string("one"); });
|
||||
cache.get(2, []() { return std::string("two"); });
|
||||
cache.get(3, []() { return std::string("three"); }); // should evict key 1
|
||||
|
||||
EXPECT_EQ(
|
||||
cache.get(1),
|
||||
""); // key 1 should be evicted and default constructed value is returned
|
||||
EXPECT_EQ(cache.get(2), "two");
|
||||
EXPECT_EQ(cache.get(3), "three");
|
||||
}
|
||||
|
||||
} // namespace facebook::react
|
||||
Reference in New Issue
Block a user