Commit 57e26df8 authored by Adam Norton's avatar Adam Norton Committed by Facebook Github Bot

EvictingCacheMap::insert

Summary: Add insert method to mimic std::unordered_map::insert. Allows for insertion without overwriting an existing element.

Reviewed By: yfeldblum

Differential Revision: D13928583

fbshipit-source-id: 54f0eb5069b753bcaca55b04c09968d12dceb5e3
parent df20b646
...@@ -335,6 +335,31 @@ class EvictingCacheMap { ...@@ -335,6 +335,31 @@ class EvictingCacheMap {
} }
} }
/**
* Insert a new key-value pair in the dictionary if no element exists for key
* @param key key to associate with value
* @param value value to associate with the key
* @param pruneHook callback to use on eviction (if it occurs).
* @return a pair consisting of an iterator to the inserted element (or to the
* element that prevented the insertion) and a bool denoting whether the
* insertion took place.
*/
std::pair<iterator, bool>
insert(const TKey& key, TValue value, PruneHookCall pruneHook = nullptr) {
auto node = std::make_unique<Node>(key, std::move(value));
auto pair = index_.insert(*node);
if (pair.second) {
lru_.push_front(*node);
node.release();
// no evictions if maxSize_ is 0 i.e. unlimited capacity
if (maxSize_ > 0 && size() > maxSize_) {
prune(clearSize_, pruneHook);
}
}
return std::make_pair(iterator(lru_.iterator_to(*pair.first)), pair.second);
}
/** /**
* Get the number of elements in the dictionary * Get the number of elements in the dictionary
* @return the size of the dictionary * @return the size of the dictionary
......
...@@ -312,6 +312,17 @@ TEST(EvictingCacheMap, DestructorInvocationTest) { ...@@ -312,6 +312,17 @@ TEST(EvictingCacheMap, DestructorInvocationTest) {
~SumInt() { ~SumInt() {
*ref += val; *ref += val;
} }
SumInt(SumInt const&) = delete;
SumInt& operator=(SumInt const&) = delete;
SumInt(SumInt&& other) : val(std::exchange(other.val, 0)), ref(other.ref) {}
SumInt& operator=(SumInt&& other) {
std::swap(val, other.val);
std::swap(ref, other.ref);
return *this;
}
int val; int val;
int* ref; int* ref;
}; };
...@@ -408,7 +419,25 @@ TEST(EvictingCacheMap, DestructorInvocationTest) { ...@@ -408,7 +419,25 @@ TEST(EvictingCacheMap, DestructorInvocationTest) {
EXPECT_EQ(i, map.get(i).val); EXPECT_EQ(i, map.get(i).val);
} }
EXPECT_EQ((89 * 90) / 2, sum); EXPECT_EQ((89 * 90) / 2, sum);
sum = 0; sum = 0;
for (int i = 0; i < 90; i++) {
auto pair = map.insert(i, SumInt(i + 1, &sum));
EXPECT_EQ(i + 1, pair.first->second.val);
EXPECT_TRUE(pair.second);
EXPECT_TRUE(map.exists(i));
}
EXPECT_EQ(0, sum);
for (int i = 90; i < 100; i++) {
auto pair = map.insert(i, SumInt(i + 1, &sum));
EXPECT_EQ(i, pair.first->second.val);
EXPECT_FALSE(pair.second);
EXPECT_TRUE(map.exists(i));
}
EXPECT_EQ((10 * 191) / 2, sum);
sum = 0;
map.prune(100);
EXPECT_EQ((90 * 91) / 2 + (10 * 189) / 2, sum);
} }
TEST(EvictingCacheMap, LruSanityTest) { TEST(EvictingCacheMap, LruSanityTest) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment