From bb7dc34d6a4d8282e4dd9a7240b905ce580d2c97 Mon Sep 17 00:00:00 2001 From: Matan Breizman Date: Wed, 7 Dec 2022 13:17:23 +0000 Subject: [PATCH] common/intrusive_lru: Add clear_range() Signed-off-by: Matan Breizman (cherry picked from commit c4d996e0b733a8a198274949a9d77c1f2fed7fbd) --- src/common/intrusive_lru.h | 19 +++++++++ src/crimson/osd/object_context.h | 5 +++ src/test/common/test_intrusive_lru.cc | 60 +++++++++++++++++++++++++++ 3 files changed, 84 insertions(+) diff --git a/src/common/intrusive_lru.h b/src/common/intrusive_lru.h index 2837f67984b3d..d780b22119244 100644 --- a/src/common/intrusive_lru.h +++ b/src/common/intrusive_lru.h @@ -148,6 +148,25 @@ public: } } + /* + * Clears unreferenced elements from the lru set [from, to] + */ + void clear_range( + const K& from, + const K& to) { + auto from_iter = lru_set.lower_bound(from); + auto to_iter = lru_set.upper_bound(to); + for (auto i = from_iter; i != to_iter; ) { + if (!(*i).lru) { + unreferenced_list.erase(lru_list_t::s_iterator_to(*i)); + i = lru_set.erase_and_dispose(i, [](auto *p) + { delete p; } ); + } else { + i++; + } + } + } + /** * Returns the TRef corresponding to k if it exists or * nullptr otherwise. diff --git a/src/crimson/osd/object_context.h b/src/crimson/osd/object_context.h index c42f8647a0fa4..a4ecc6ec329e6 100644 --- a/src/crimson/osd/object_context.h +++ b/src/crimson/osd/object_context.h @@ -263,6 +263,11 @@ public: return obc_lru.get(hoid); } + void clear_range(const hobject_t &from, + const hobject_t &to) { + obc_lru.clear_range(from, to); + } + const char** get_tracked_conf_keys() const final; void handle_conf_change(const crimson::common::ConfigProxy& conf, const std::set &changed) final; diff --git a/src/test/common/test_intrusive_lru.cc b/src/test/common/test_intrusive_lru.cc index 62fb1a0829296..0654bd97d81ec 100644 --- a/src/test/common/test_intrusive_lru.cc +++ b/src/test/common/test_intrusive_lru.cc @@ -146,3 +146,63 @@ TEST(LRU, eviction_live_ref) { } } } + +TEST(LRU, clear_range) { + LRUTest cache; + const unsigned SIZE = 10; + cache.set_target_size(SIZE); + { + auto [ref, existed] = cache.add(1, 4); + ASSERT_FALSE(existed); + } + { + auto [ref, existed] = cache.add(2, 4); + ASSERT_FALSE(existed); + } + { + auto [ref, existed] = cache.add(3, 4); + ASSERT_FALSE(existed); + } + // Unlike above, the reference is not being destroyed + auto [live_ref1, existed1] = cache.add(4, 4); + ASSERT_FALSE(existed1); + + auto [live_ref2, existed2] = cache.add(5, 4); + ASSERT_FALSE(existed2); + + cache.clear_range(0,4); + + // Should not exists (Unreferenced): + { + auto [ref, existed] = cache.add(1, 4); + ASSERT_FALSE(existed); + } + { + auto [ref, existed] = cache.add(2, 4); + ASSERT_FALSE(existed); + } + { + auto [ref, existed] = cache.add(3, 4); + ASSERT_FALSE(existed); + } + // Should exist (Still being referenced): + { + auto [ref, existed] = cache.add(4, 4); + ASSERT_TRUE(existed); + } + // Should exists (Still being referenced and wasn't removed) + { + auto [ref, existed] = cache.add(5, 4); + ASSERT_TRUE(existed); + } + // Test out of bound deletion: + { + cache.clear_range(3,8); + auto [ref, existed] = cache.add(4, 4); + ASSERT_TRUE(existed); + } + { + auto [ref, existed] = cache.add(3, 4); + ASSERT_FALSE(existed); + } +} -- 2.39.5