From: Yingxin Cheng Date: Fri, 25 Sep 2020 07:17:10 +0000 (+0800) Subject: crimson/onode-staged-tree: fix trim related issue when insert front X-Git-Tag: v16.1.0~359^2~30 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=8492f01458c21393c89a978fe298f3a3bb1621ee;p=ceph.git crimson/onode-staged-tree: fix trim related issue when insert front Signed-off-by: Yingxin Cheng --- diff --git a/src/crimson/os/seastore/onode_manager/staged-fltree/stages/stage.h b/src/crimson/os/seastore/onode_manager/staged-fltree/stages/stage.h index 2a647970602f..984c6fce07a2 100644 --- a/src/crimson/os/seastore/onode_manager/staged-fltree/stages/stage.h +++ b/src/crimson/os/seastore/onode_manager/staged-fltree/stages/stage.h @@ -766,6 +766,16 @@ struct staged { * estimate_insert(key, value) -> node_offset_t */ using iterator_t = _iterator_t; + /* 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 + * , 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(key, value); + } else { + assert(false && "impossible path"); + } if constexpr (IS_BOTTOM) { return container_t::template insert_at( 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 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); } } diff --git a/src/test/crimson/seastore/onode_tree/test_staged_fltree.cc b/src/test/crimson/seastore/onode_tree/test_staged_fltree.cc index e99ca7b55aeb..c94199bf5cd6 100644 --- a/src/test/crimson/seastore/onode_tree/test_staged_fltree.cc +++ b/src/test/crimson/seastore/onode_tree/test_staged_fltree.cc @@ -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] }); }