]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
crimson/onode-staged-tree: fix trim related issue when insert front
authorYingxin Cheng <yingxin.cheng@intel.com>
Fri, 25 Sep 2020 07:17:10 +0000 (15:17 +0800)
committerYingxin Cheng <yingxin.cheng@intel.com>
Tue, 1 Dec 2020 04:50:54 +0000 (12:50 +0800)
Signed-off-by: Yingxin Cheng <yingxin.cheng@intel.com>
src/crimson/os/seastore/onode_manager/staged-fltree/stages/stage.h
src/test/crimson/seastore/onode_tree/test_staged_fltree.cc

index 2a647970602f6e2d16bd86e3664f26724a553cd1..984c6fce07a229ef59da69c9e1a9d5deb9549c71 100644 (file)
@@ -766,6 +766,16 @@ struct staged {
    *   estimate_insert(key, value) -> node_offset_t
    */
   using iterator_t = _iterator_t<CONTAINER_TYPE>;
+  /* TODO: detailed comments
+   * - trim_until(mut) -> trim_size
+   *   * keep 0 to i - 1, and remove the rest, return the size trimmed.
+   *   * if this is the end iterator, do nothing and return 0.
+   *   * if this is the start iterator, normally needs to go to the higher
+   *     stage to trim the entire container.
+   * - trim_at(mut, trimmed) -> trim_size
+   *   * trim happens inside the current iterator, causing the size reduced by
+   *     <trimmed>, return the total size trimmed.
+   */
 
   /*
    * Lookup internals (hide?)
@@ -1200,9 +1210,16 @@ struct staged {
       position_t& position, match_stage_t& stage, node_offset_t& _insert_size) {
     auto p_left_bound = container.p_left_bound();
     if (unlikely(!container.keys())) {
-      assert(position == position_t::end());
-      assert(stage == STAGE);
-      position = position_t::begin();
+      if (position == position_t::end()) {
+        position = position_t::begin();
+        assert(stage == STAGE);
+      } else if (position == position_t::begin()) {
+        // when insert into a trimmed and empty left node
+        stage = STAGE;
+        _insert_size = insert_size<KT>(key, value);
+      } else {
+        assert(false && "impossible path");
+      }
       if constexpr (IS_BOTTOM) {
         return container_t::template insert_at<KT>(
             mut, container, key, value, 0, _insert_size, p_left_bound);
@@ -1675,6 +1692,14 @@ struct staged {
     }
   }
 
+  /* TrimType:
+   *   BEFORE: remove the entire container, normally means the according higher
+   *           stage iterator needs to be trimmed as-a-whole.
+   *   AFTER: retain the entire container, normally means the trim should be
+   *          start from the next iterator at the higher stage.
+   *   AT: trim happens in the current container, and the according higher
+   *       stage iterator needs to be adjusted by the trimmed size.
+   */
   static std::tuple<TrimType, size_t>
   recursively_trim(NodeExtentMutable& mut, StagedIterator& trim_at) {
     if (!trim_at.valid()) {
@@ -1716,9 +1741,9 @@ struct staged {
 
   static void trim(NodeExtentMutable& mut, StagedIterator& trim_at) {
     auto [type, trimmed] = recursively_trim(mut, trim_at);
-    if (type == TrimType::AFTER) {
+    if (type == TrimType::BEFORE) {
+      assert(trim_at.valid());
       auto& iter = trim_at.get();
-      assert(iter.is_end());
       iter.trim_until(mut);
     }
   }
index e99ca7b55aebdad45c370cd93addf729c65fc226..c94199bf5cd6c0e4286fb3f116556a197ea18634 100644 (file)
@@ -600,8 +600,17 @@ TEST_F(c_dummy_test_t, 4_split_leaf_node)
       test.split(make_ghobj(3, 3, 3, "ns2", "oid2", 3, 4), onode4).get0();
     }
 
-    // TODO: test split at {0, 0, 0}
-    // TODO: test split at {END, END, END}
+    {
+      TestTree test;
+      test.build_tree({2, 4}, {2, 4}, {2, 4}, 232).get0();
+      auto& onode = test.create_onode(1996);
+      logger().info("\n---------------------------------------------"
+                    "\nsplit at [0, 0, 0]; insert to left front at stage 2, 1, 0\n");
+      test.split(make_ghobj(1, 1, 1, "ns3", "oid3", 3, 3), onode).get0();
+      test.split(make_ghobj(2, 2, 2, "ns1", "oid1", 3, 3), onode).get0();
+      test.split(make_ghobj(2, 2, 2, "ns2", "oid2", 1, 1), onode).get0();
+    }
+    // Impossible to split at [END, END, END]
   });
 }
 
@@ -1048,6 +1057,6 @@ TEST_F(c_dummy_test_t, 5_split_internal_node)
     }
 
     // TODO: test split at {0, 0, 0}
-    // TODO: test split at {END, END, END}
+    // Impossible to split at [END, END, END]
   });
 }