]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
crimson/seastore: integrate and test oid list to OnodeManager
authorYingxin Cheng <yingxin.cheng@intel.com>
Thu, 29 Apr 2021 02:20:05 +0000 (10:20 +0800)
committerYingxin Cheng <yingxin.cheng@intel.com>
Sat, 8 May 2021 02:04:46 +0000 (10:04 +0800)
Signed-off-by: Yingxin Cheng <yingxin.cheng@intel.com>
src/crimson/os/seastore/onode_manager.h
src/crimson/os/seastore/onode_manager/staged-fltree/fltree_onode_manager.cc
src/crimson/os/seastore/onode_manager/staged-fltree/fltree_onode_manager.h
src/test/crimson/seastore/onode_tree/test_fltree_onode_manager.cc

index c7b29148924f084314292b3b394ba38e2382018e..95045bc411ab2f6e4e97432b7517ee3f1de1eb58 100644 (file)
@@ -69,6 +69,15 @@ public:
     Transaction &trans,
     OnodeRef &onode) = 0;
 
+  using list_onodes_ertr = base_ertr;
+  using list_onodes_bare_ret = std::tuple<std::vector<ghobject_t>, ghobject_t>;
+  using list_onodes_ret = list_onodes_ertr::future<list_onodes_bare_ret>;
+  virtual list_onodes_ret list_onodes(
+    Transaction &trans,
+    const ghobject_t& start,
+    const ghobject_t& end,
+    uint64_t limit) = 0;
+
   virtual ~OnodeManager() {}
 };
 using OnodeManagerRef = std::unique_ptr<OnodeManager>;
index e0b406d81821926cbb71cc4db3322f3289f42683..82a12eb1d0670c29a36c219c61111065eab14fda 100644 (file)
@@ -148,6 +148,55 @@ FLTreeOnodeManager::erase_onode_ret FLTreeOnodeManager::erase_onode(
   return erase_onode_ertr::now();
 }
 
+FLTreeOnodeManager::list_onodes_ret FLTreeOnodeManager::list_onodes(
+  Transaction &trans,
+  const ghobject_t& start,
+  const ghobject_t& end,
+  uint64_t limit)
+{
+  return tree.lower_bound(trans, start
+  ).safe_then([this, &trans, end, limit] (auto&& cursor) {
+    using crimson::os::seastore::onode::full_key_t;
+    return seastar::do_with(
+        limit,
+        std::move(cursor),
+        list_onodes_bare_ret(),
+        [this, &trans, end] (auto& to_list, auto& current_cursor, auto& ret) {
+      using get_next_ertr = typename OnodeTree::btree_ertr;
+      return crimson::do_until(
+          [this, &trans, end, &to_list, &current_cursor, &ret] () mutable
+          -> get_next_ertr::future<bool> {
+        if (current_cursor.is_end() ||
+            current_cursor.get_ghobj() >= end) {
+          std::get<1>(ret) = end;
+          return seastar::make_ready_future<bool>(true);
+        }
+        if (to_list == 0) {
+          std::get<1>(ret) = current_cursor.get_ghobj();
+          return seastar::make_ready_future<bool>(true);
+        }
+        std::get<0>(ret).emplace_back(current_cursor.get_ghobj());
+        return tree.get_next(trans, current_cursor
+        ).safe_then([&to_list, &current_cursor] (auto&& next_cursor) mutable {
+          // we intentionally hold the current_cursor during get_next() to
+          // accelerate tree lookup.
+          --to_list;
+          current_cursor = next_cursor;
+          return seastar::make_ready_future<bool>(false);
+        });
+      }).safe_then([&ret] () mutable {
+        return seastar::make_ready_future<list_onodes_bare_ret>(
+            std::move(ret));
+      });
+    });
+  }).handle_error(
+    list_onodes_ertr::pass_further{},
+    crimson::ct_error::assert_all{
+      "Invalid error in FLTreeOnodeManager::list_onodes"
+    }
+  );
+}
+
 FLTreeOnodeManager::~FLTreeOnodeManager() {}
 
 }
index 4146d08d82bc3bdc418f5b224222a272f77921c0..2a24dc1829068f8981eceb88925489f349cc8419 100644 (file)
@@ -132,6 +132,12 @@ public:
     Transaction &trans,
     OnodeRef &onode) final;
 
+  list_onodes_ret list_onodes(
+    Transaction &trans,
+    const ghobject_t& start,
+    const ghobject_t& end,
+    uint64_t limit) final;
+
   ~FLTreeOnodeManager();
 };
 using FLTreeOnodeManagerRef = std::unique_ptr<FLTreeOnodeManager>;
index c9fc0ae8d001b8dba05520237dfc5308bf9c86ae..9a314dcb5f94f42dab5a3105faed2e2631a82f42 100644 (file)
@@ -197,6 +197,26 @@ struct fltree_onode_manager_test_t
     });
   }
 
+  static constexpr uint64_t LIST_LIMIT = 10;
+  void validate_list_onodes(KVPool<onode_item_t>& pool) {
+    with_onodes_process(pool.begin(), pool.end(),
+        [this] (auto& t, auto& oids, auto& items) {
+      std::vector<ghobject_t> listed_oids;
+      auto start = ghobject_t();
+      auto end = ghobject_t::get_max();
+      assert(start < end);
+      assert(start < oids[0]);
+      assert(oids[0] < end);
+      while (start != end) {
+        auto [list_ret, list_end] = manager->list_onodes(
+            t, start, end, LIST_LIMIT).unsafe_get0();
+        listed_oids.insert(listed_oids.end(), list_ret.begin(), list_ret.end());
+        start = list_end;
+      }
+      ceph_assert(oids.size() == listed_oids.size());
+    });
+  }
+
   fltree_onode_manager_test_t() {}
 };
 
@@ -215,6 +235,8 @@ TEST_F(fltree_onode_manager_test_t, 1_single)
     });
     validate_onode(iter);
 
+    validate_list_onodes(pool);
+
     with_onode_write(iter, [this](auto& t, auto& onode, auto& item) {
       OnodeRef onode_ref = &onode;
       manager->erase_onode(t, onode_ref).unsafe_get0();
@@ -236,6 +258,8 @@ TEST_F(fltree_onode_manager_test_t, 2_synthetic)
     });
     validate_onodes(start, end);
 
+    validate_list_onodes(pool);
+
     auto rd_start = pool.random_begin();
     auto rd_end = rd_start + 50;
     with_onodes_write(rd_start, rd_end,
@@ -266,5 +290,7 @@ TEST_F(fltree_onode_manager_test_t, 2_synthetic)
     start = pool.begin();
     end = pool.end();
     validate_onodes(start, end);
+
+    validate_list_onodes(pool);
   });
 }