]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
common/intrusive_lru: Add clear_range()
authorMatan Breizman <mbreizma@redhat.com>
Wed, 7 Dec 2022 13:17:23 +0000 (13:17 +0000)
committerMatan Breizman <mbreizma@redhat.com>
Sun, 21 May 2023 08:12:29 +0000 (08:12 +0000)
Signed-off-by: Matan Breizman <mbreizma@redhat.com>
(cherry picked from commit c4d996e0b733a8a198274949a9d77c1f2fed7fbd)

src/common/intrusive_lru.h
src/crimson/osd/object_context.h
src/test/common/test_intrusive_lru.cc

index 2837f67984b3d8ac4f17aa927da22435330baa1f..d780b22119244159da9aa3fab03a7d93870f54a1 100644 (file)
@@ -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.
index c42f8647a0fa48bd8df547a11fad402d9a302fcf..a4ecc6ec329e699b5f266a7f33a072fd96801279 100644 (file)
@@ -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 <std::string> &changed) final;
index 62fb1a0829296daa909da9c0de0e21fc6c7ab927..0654bd97d81ecaa51ddf8552f672cfff4e65364e 100644 (file)
@@ -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);
+  }
+}