]> git.proxmox.com Git - ceph.git/blobdiff - ceph/src/crimson/os/seastore/onode_manager/staged-fltree/node_layout_replayable.h
import quincy beta 17.1.0
[ceph.git] / ceph / src / crimson / os / seastore / onode_manager / staged-fltree / node_layout_replayable.h
index c1499d6093db0bb3d732a764714a4aecf68ea714..ece058111f452134e97837fad93df336e53bc0bd 100644 (file)
@@ -23,6 +23,7 @@ struct NodeLayoutReplayableT {
   using node_stage_t = node_extent_t<FieldType, NODE_TYPE>;
   using position_t = typename STAGE_T::position_t;
   using StagedIterator = typename STAGE_T::StagedIterator;
+  using value_input_t = value_input_type_t<NODE_TYPE>;
   using value_t = value_type_t<NODE_TYPE>;
   static constexpr auto FIELD_TYPE = FieldType::FIELD_TYPE;
 
@@ -31,7 +32,7 @@ struct NodeLayoutReplayableT {
       NodeExtentMutable& mut,
       const node_stage_t& node_stage,
       const full_key_t<KT>& key,
-      const value_t& value,
+      const value_input_t& value,
       position_t& insert_pos,
       match_stage_t& insert_stage,
       node_offset_t& insert_size) {
@@ -54,7 +55,7 @@ struct NodeLayoutReplayableT {
       const node_stage_t& node_stage,
       StagedIterator& split_at,
       const full_key_t<KT>& key,
-      const value_t& value,
+      const value_input_t& value,
       position_t& insert_pos,
       match_stage_t& insert_stage,
       node_offset_t& insert_size) {
@@ -70,6 +71,69 @@ struct NodeLayoutReplayableT {
     assert(NODE_TYPE == node_type_t::INTERNAL);
     mut.copy_in_absolute(p_addr, new_addr);
   }
+
+  static std::tuple<match_stage_t, position_t> erase(
+      NodeExtentMutable& mut,
+      const node_stage_t& node_stage,
+      const position_t& _erase_pos) {
+    if (_erase_pos.is_end()) {
+      // must be internal node
+      assert(node_stage.is_level_tail());
+      // return erase_stage, last_pos
+      return update_last_to_tail(mut, node_stage);
+    }
+
+    assert(node_stage.keys() != 0);
+    position_t erase_pos = _erase_pos;
+    auto erase_stage = STAGE_T::erase(mut, node_stage, erase_pos);
+    // return erase_stage, next_pos
+    return {erase_stage, erase_pos};
+  }
+
+  static position_t make_tail(
+      NodeExtentMutable& mut,
+      const node_stage_t& node_stage) {
+    assert(!node_stage.is_level_tail());
+    if constexpr (NODE_TYPE == node_type_t::INTERNAL) {
+      auto [r_stage, r_last_pos] = update_last_to_tail(mut, node_stage);
+      std::ignore = r_stage;
+      return r_last_pos;
+    } else {
+      node_stage_t::update_is_level_tail(mut, node_stage, true);
+      // no need to calculate the last pos
+      return position_t::end();
+    }
+  }
+
+ private:
+  static std::tuple<match_stage_t, position_t> update_last_to_tail(
+      NodeExtentMutable& mut,
+      const node_stage_t& node_stage) {
+    if constexpr (NODE_TYPE == node_type_t::INTERNAL) {
+      assert(node_stage.keys() != 0);
+      position_t last_pos;
+      laddr_t last_value;
+      {
+        const laddr_packed_t* p_last_value;
+        STAGE_T::template get_largest_slot<true, false, true>(
+            node_stage, &last_pos, nullptr, &p_last_value);
+        last_value = p_last_value->value;
+      }
+
+      auto erase_pos = last_pos;
+      auto erase_stage = STAGE_T::erase(mut, node_stage, erase_pos);
+      assert(erase_pos.is_end());
+
+      node_stage_t::update_is_level_tail(mut, node_stage, true);
+      auto p_last_value = const_cast<laddr_packed_t*>(
+          node_stage.get_end_p_laddr());
+      mut.copy_in_absolute(p_last_value, last_value);
+      // return erase_stage, last_pos
+      return {erase_stage, last_pos};
+    } else {
+      ceph_abort("impossible path");
+    }
+  }
 };
 
 }