]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
crimson/onode-staged-tree: implement staged::get_prev_slot()
authorYingxin Cheng <yingxin.cheng@intel.com>
Fri, 16 Apr 2021 05:45:09 +0000 (13:45 +0800)
committerYingxin Cheng <yingxin.cheng@intel.com>
Thu, 29 Apr 2021 08:03:37 +0000 (16:03 +0800)
Signed-off-by: Yingxin Cheng <yingxin.cheng@intel.com>
src/crimson/os/seastore/onode_manager/staged-fltree/node_layout.h
src/crimson/os/seastore/onode_manager/staged-fltree/stages/stage.h

index 9097c4bf7546cb9c0a763c097d015cfe8de6fc7e..3583ab2e4dda8075d79c560464b09575f3225c6d 100644 (file)
@@ -378,7 +378,24 @@ class NodeLayoutT final : public InternalNodeImpl, public LeafNodeImpl {
   void get_prev_slot(search_position_t& pos,
                      key_view_t* p_index_key = nullptr,
                      const value_t** pp_value = nullptr) const override {
-    ceph_abort("not implemented");
+    assert(!is_keys_empty());
+    assert(!pos.is_end());
+    auto& _pos = cast_down<STAGE>(pos);
+#ifndef NDEBUG
+    auto nxt_pos = _pos;
+#endif
+    if (!p_index_key && pp_value) {
+      STAGE_T::template get_prev_slot<false, true>(
+          extent.read(), _pos, nullptr, pp_value);
+    } else {
+      ceph_abort("not implemented");
+    }
+#ifndef NDEBUG
+    auto _nxt_pos = _pos;
+    STAGE_T::template get_next_slot<false, false>(
+        extent.read(), _nxt_pos, nullptr, nullptr);
+    assert(nxt_pos == _nxt_pos);
+#endif
   }
 
   void get_next_slot(search_position_t& pos,
index a6f439ca63bfe1af1dcd5bf01eeca0bf462c41e4..31803c71af829adcc77933fc894911e797e6bb2c 100644 (file)
@@ -1545,6 +1545,49 @@ struct staged {
     }
   }
 
+  template <bool GET_KEY, bool GET_VAL>
+  static void get_prev_slot(
+      const container_t& container,         // IN
+      position_t& pos,                      // IN&OUT
+      full_key_t<KeyT::VIEW>* p_index_key,  // OUT
+      const value_t** pp_value) {           // OUT
+    assert(pos != position_t::begin());
+    assert(!pos.is_end());
+    auto& index = pos.index;
+    auto iter = iterator_t(container);
+    if constexpr (!IS_BOTTOM) {
+      auto& nxt_pos = pos.nxt;
+      if (nxt_pos == NXT_STAGE_T::position_t::begin()) {
+        assert(index);
+        --index;
+        iter.seek_at(index);
+        auto nxt_container = iter.get_nxt_container();
+        NXT_STAGE_T::template get_largest_slot<true, GET_KEY, GET_VAL>(
+            nxt_container, &nxt_pos, p_index_key, pp_value);
+      } else {
+        iter.seek_at(index);
+        auto nxt_container = iter.get_nxt_container();
+        NXT_STAGE_T::template get_prev_slot<GET_KEY, GET_VAL>(
+            nxt_container, nxt_pos, p_index_key, pp_value);
+      }
+    } else {
+      assert(index);
+      --index;
+      iter.seek_at(index);
+      if constexpr (GET_VAL) {
+        assert(pp_value);
+        *pp_value = iter.get_p_value();
+      } else {
+        assert(!pp_value);
+      }
+    }
+    if constexpr (GET_KEY) {
+      p_index_key->set(iter.get_key());
+    } else {
+      assert(!p_index_key);
+    }
+  }
+
   struct _BaseEmpty {};
   class _BaseWithNxtIterator {
    protected: