]> git.apps.os.sepia.ceph.com Git - ceph-ci.git/commitdiff
crimson/os/seastore/linked_tree_node: resize child pointer vector if
authorXuehan Xu <xuxuehan@qianxin.com>
Wed, 22 Jan 2025 09:44:13 +0000 (17:44 +0800)
committerXuehan Xu <xuxuehan@qianxin.com>
Mon, 14 Apr 2025 04:26:53 +0000 (12:26 +0800)
necessary

Signed-off-by: Xuehan Xu <xuxuehan@qianxin.com>
src/crimson/os/seastore/backref/backref_tree_node.h
src/crimson/os/seastore/lba_manager/btree/lba_btree_node.h
src/crimson/os/seastore/linked_tree_node.h

index 742d5074a0579aa18c0c48f04a2caa9896d246b9..e31ac24acb5a8be9b716a80e00a4c2c459aa2f29 100644 (file)
@@ -91,6 +91,7 @@ class BackrefInternalNode
     "INTERNAL_NODE_CAPACITY doesn't fit in BACKREF_NODE_SIZE");
 public:
   using key_type = paddr_t;
+  static constexpr uint32_t CHILD_VEC_UNIT = 0;
   template <typename... T>
   BackrefInternalNode(T&&... t) :
     FixedKVInternalNode(std::forward<T>(t)...) {}
index c865f6b84a998444b6e3d325676bc6ec6f63df74..9a66169ae2b48408a78960b3aa5cbff3dbe90667 100644 (file)
@@ -94,6 +94,7 @@ struct LBAInternalNode
   template <typename... T>
   LBAInternalNode(T&&... t) :
     FixedKVInternalNode(std::forward<T>(t)...) {}
+  static constexpr uint32_t CHILD_VEC_UNIT = 0;
 
   static constexpr extent_types_t TYPE = extent_types_t::LADDR_INTERNAL;
 
@@ -173,6 +174,7 @@ struct LBALeafNode
   using key_type = laddr_t;
   using parent_node_t = ParentNode<LBALeafNode, laddr_t>;
   using child_t = LogicalChildNode;
+  static constexpr uint32_t CHILD_VEC_UNIT = 0;
   LBALeafNode(ceph::bufferptr &&ptr)
     : parent_type_t(std::move(ptr)),
       parent_node_t(LEAF_NODE_CAPACITY) {}
index 9ed0f67fb7785c52bcae525421ac1f1ca664908d..112a6d32cb03f0d0999ce35619e0d6591b5a107f 100644 (file)
@@ -357,6 +357,7 @@ public:
   void link_child(BaseChildNode<T, node_key_t>* child, btreenode_pos_t pos) {
     auto &me = down_cast();
     assert(pos < me.get_size());
+    assert(pos < children.capacity());
     assert(child);
     ceph_assert(!me.is_pending());
     assert(child->valid() && !child->pending());
@@ -375,6 +376,8 @@ public:
     if (size == 0) {
       size = me.get_size();
     }
+    maybe_expand_children(size + 1);
+    assert(size < children.capacity());
     auto raw_children = children.data();
     std::memmove(
       &raw_children[offset + 1],
@@ -393,11 +396,9 @@ public:
 
 protected:
   ParentNode(btreenode_pos_t capacity)
-    : children(capacity, nullptr),
-      capacity(capacity) {}
+    : children(capacity, nullptr) {}
   ParentNode(const ParentNode &rhs)
-    : children(rhs.capacity, nullptr),
-      capacity(rhs.capacity) {}
+    : children(rhs.children.capacity(), nullptr) {}
   void add_copy_dest(Transaction &t, TCachedExtentRef<T> dest) {
     ceph_assert(down_cast().is_stable());
     ceph_assert(dest->is_pending());
@@ -448,6 +449,7 @@ protected:
       &raw_children[offset],
       &raw_children[offset + 1],
       (me.get_size() - offset - 1) * sizeof(BaseChildNode<T, node_key_t>*));
+    maybe_shink_children();
   }
 
   void on_rewrite(Transaction &t, T &foreign_extent) {
@@ -552,8 +554,10 @@ protected:
     auto &me = down_cast();
     assert(!left.my_tracker);
     assert(!right.my_tracker);
+    btreenode_pos_t pivot = me.get_node_split_pivot();
+    left.maybe_expand_children(pivot);
+    right.maybe_expand_children(me.get_size() - pivot);
     if (me.is_pending()) {
-      btreenode_pos_t pivot = me.get_node_split_pivot();
       move_child_ptrs(left, me, 0, 0, pivot);
       move_child_ptrs(right, me, 0, pivot, me.get_size());
       my_tracker = nullptr;
@@ -584,6 +588,7 @@ protected:
     auto &me = down_cast();
     ceph_assert(!my_tracker);
 
+    maybe_expand_children(left.get_size() + right.get_size());
     if (left.is_pending()) {
       move_child_ptrs(me, left, 0, 0, left.get_size());
       left.my_tracker = nullptr;
@@ -632,6 +637,9 @@ protected:
       pivot_idx++;
     }
 
+    replacement_left.maybe_expand_children(pivot_idx);
+    replacement_right.maybe_expand_children(r_size + l_size - pivot_idx);
+
     assert(!replacement_left.my_tracker);
     assert(!replacement_right.my_tracker);
     if (pivot_idx < l_size) {
@@ -922,10 +930,29 @@ private:
   const T& down_cast() const {
     return *static_cast<const T*>(this);
   }
+  void maybe_expand_children(size_t size) {
+    if constexpr (T::CHILD_VEC_UNIT) {
+      if (size > children.capacity()) {
+       children.resize(p2roundup(size, (size_t)T::CHILD_VEC_UNIT));
+      }
+    } else {
+      // children.capacity() is static and assigned upon construction
+      assert(size <= children.capacity());
+    }
+  }
+  void maybe_shink_children() {
+    if constexpr (T::CHILD_VEC_UNIT) {
+      auto &me = down_cast();
+      if (children.capacity() > T::CHILD_VEC_UNIT &&
+         me.get_size() < (children.capacity() / 3 /*should be parameterized*/)) {
+       children.resize(p2roundup(me.get_size(), T::CHILD_VEC_UNIT));
+       children.shrink_to_fit();
+      }
+    }
+  }
 
   std::vector<BaseChildNode<T, node_key_t>*> children;
   std::set<TCachedExtentRef<T>, Comparator> copy_sources;
-  btreenode_pos_t capacity = 0;
 
   // copy dests points from a stable node back to its pending nodes
   // having copy sources at the same tree level, it serves as a two-level index: