From: Yingxin Cheng Date: Fri, 25 Sep 2020 07:29:10 +0000 (+0800) Subject: crimson/onode-staged-tree: add more validations X-Git-Tag: v17.0.0~391^2~29 X-Git-Url: http://git.apps.os.sepia.ceph.com/?a=commitdiff_plain;h=8f20ef68165ff32ab06d9422f4302ae14442cae9;p=ceph-ci.git crimson/onode-staged-tree: add more validations Signed-off-by: Yingxin Cheng --- diff --git a/src/crimson/os/seastore/onode_manager/staged-fltree/node.cc b/src/crimson/os/seastore/onode_manager/staged-fltree/node.cc index bd72c8f33d2..28db24a28f4 100644 --- a/src/crimson/os/seastore/onode_manager/staged-fltree/node.cc +++ b/src/crimson/os/seastore/onode_manager/staged-fltree/node.cc @@ -593,7 +593,8 @@ node_future> LeafNode::insert_value( } #endif std::cout << "leaf insert at pos(" << pos << "), " - << key << ", " << value << std::endl; + << key << ", " << value << ", " << history + << std::endl; #if 0 std::cout << "before insert:" << std::endl; dump(std::cout) << std::endl; diff --git a/src/crimson/os/seastore/onode_manager/staged-fltree/node_impl.h b/src/crimson/os/seastore/onode_manager/staged-fltree/node_impl.h index a01e73eff01..a2027dd74c9 100644 --- a/src/crimson/os/seastore/onode_manager/staged-fltree/node_impl.h +++ b/src/crimson/os/seastore/onode_manager/staged-fltree/node_impl.h @@ -36,6 +36,7 @@ class NodeImpl { virtual std::ostream& dump(std::ostream&) const = 0; virtual std::ostream& dump_brief(std::ostream&) const = 0; + virtual void validate_layout() const = 0; virtual void test_copy_to(NodeExtentMutable&) const = 0; virtual void test_set_tail(NodeExtentMutable&) = 0; diff --git a/src/crimson/os/seastore/onode_manager/staged-fltree/node_layout.h b/src/crimson/os/seastore/onode_manager/staged-fltree/node_layout.h index e7bdadc11fb..dc98943b2e6 100644 --- a/src/crimson/os/seastore/onode_manager/staged-fltree/node_layout.h +++ b/src/crimson/os/seastore/onode_manager/staged-fltree/node_layout.h @@ -145,6 +145,12 @@ class NodeLayoutT final : public InternalNodeImpl, public LeafNodeImpl { return os; } + void validate_layout() const override { +#ifndef NDEBUG + STAGE_T::validate(extent.read()); +#endif + } + void test_copy_to(NodeExtentMutable& to) const override { extent.test_copy_to(to); } @@ -255,6 +261,7 @@ class NodeLayoutT final : public InternalNodeImpl, public LeafNodeImpl { << "), insert_stage=" << (int)insert_stage << ", insert_size=" << insert_size << std::endl << std::endl; + validate_layout(); assert(get_key_view(insert_pos) == key); return ret; } @@ -326,6 +333,7 @@ class NodeLayoutT final : public InternalNodeImpl, public LeafNodeImpl { assert(append_at.is_end()); right_appender.wrap(); right_impl.dump(std::cout) << std::endl; + right_impl.validate_layout(); // mutate left node if (is_insert_left) { @@ -341,6 +349,7 @@ class NodeLayoutT final : public InternalNodeImpl, public LeafNodeImpl { extent.split_replayable(split_at); } dump(std::cout) << std::endl; + validate_layout(); assert(p_value); auto split_pos = normalize(split_at.get_pos()); diff --git a/src/crimson/os/seastore/onode_manager/staged-fltree/stages/key_layout.h b/src/crimson/os/seastore/onode_manager/staged-fltree/stages/key_layout.h index f0e2673a8ff..2334c4c3498 100644 --- a/src/crimson/os/seastore/onode_manager/staged-fltree/stages/key_layout.h +++ b/src/crimson/os/seastore/onode_manager/staged-fltree/stages/key_layout.h @@ -54,6 +54,12 @@ struct shard_pool_t { inline std::ostream& operator<<(std::ostream& os, const shard_pool_t& sp) { return os << (unsigned)sp.shard << "," << sp.pool; } +inline MatchKindCMP compare_to(const shard_pool_t& l, const shard_pool_t& r) { + auto ret = toMatchKindCMP(l.shard, r.shard); + if (ret != MatchKindCMP::EQ) + return ret; + return toMatchKindCMP(l.pool, r.pool); +} struct crush_t { bool operator==(const crush_t& x) const { return crush == x.crush; } @@ -67,6 +73,9 @@ struct crush_t { inline std::ostream& operator<<(std::ostream& os, const crush_t& c) { return os << c.crush; } +inline MatchKindCMP compare_to(const crush_t& l, const crush_t& r) { + return toMatchKindCMP(l.crush, r.crush); +} struct shard_pool_crush_t { bool operator==(const shard_pool_crush_t& x) const { @@ -83,6 +92,13 @@ struct shard_pool_crush_t { inline std::ostream& operator<<(std::ostream& os, const shard_pool_crush_t& spc) { return os << spc.shard_pool << "," << spc.crush; } +inline MatchKindCMP compare_to( + const shard_pool_crush_t& l, const shard_pool_crush_t& r) { + auto ret = compare_to(l.shard_pool, r.shard_pool); + if (ret != MatchKindCMP::EQ) + return ret; + return compare_to(l.crush, r.crush); +} struct snap_gen_t { bool operator==(const snap_gen_t& x) const { @@ -99,6 +115,12 @@ struct snap_gen_t { inline std::ostream& operator<<(std::ostream& os, const snap_gen_t& sg) { return os << sg.snap << "," << sg.gen; } +inline MatchKindCMP compare_to(const snap_gen_t& l, const snap_gen_t& r) { + auto ret = toMatchKindCMP(l.snap, r.snap); + if (ret != MatchKindCMP::EQ) + return ret; + return toMatchKindCMP(l.gen, r.gen); +} struct string_key_view_t { enum class Type {MIN, STR, MAX}; @@ -301,6 +323,12 @@ struct ns_oid_view_t { inline std::ostream& operator<<(std::ostream& os, const ns_oid_view_t& ns_oid) { return os << ns_oid.nspace << "," << ns_oid.oid; } +inline MatchKindCMP compare_to(const ns_oid_view_t& l, const ns_oid_view_t& r) { + auto ret = compare_to(l.nspace, r.nspace); + if (ret != MatchKindCMP::EQ) + return ret; + return compare_to(l.oid, r.oid); +} class key_hobj_t { public: @@ -343,29 +371,33 @@ class key_hobj_t { return !operator==(o); } + std::ostream& dump(std::ostream& os) const { + os << "key_hobj(" << (unsigned)shard() << "," + << pool() << "," << crush() << "; "; + if (nspace().size() <= 12) { + os << "\"" << nspace() << "\","; + } else { + os << "\"" << nspace().substr(0, 4) << ".." + << nspace().substr(nspace().size() - 2, 2) + << "/" << nspace().size() << "B\","; + } + if (oid().size() <= 12) { + os << "\"" << oid() << "\"; "; + } else { + os << "\"" << oid().substr(0, 4) << ".." + << oid().substr(oid().size() - 2, 2) + << "/" << oid().size() << "B\"; "; + } + os << snap() << "," << gen() << ")"; + return os; + } + private: ns_oid_view_t::Type _dedup_type = ns_oid_view_t::Type::STR; ghobject_t ghobj; }; inline std::ostream& operator<<(std::ostream& os, const key_hobj_t& key) { - os << "key_hobj(" << (unsigned)key.shard() << "," - << key.pool() << "," << key.crush() << "; "; - if (key.nspace().size() <= 12) { - os << "\"" << key.nspace() << "\","; - } else { - os << "\"" << key.nspace().substr(0, 4) << ".." - << key.nspace().substr(key.nspace().size() - 2, 2) - << "/" << key.nspace().size() << "B\","; - } - if (key.oid().size() <= 12) { - os << "\"" << key.oid() << "\"; "; - } else { - os << "\"" << key.oid().substr(0, 4) << ".." - << key.oid().substr(key.oid().size() - 2, 2) - << "/" << key.oid().size() << "B\"; "; - } - os << key.snap() << "," << key.gen() << ")"; - return os; + return key.dump(os); } class key_view_t { @@ -471,6 +503,31 @@ class key_view_t { p_snap_gen = &key; } + std::ostream& dump(std::ostream& os) const { + os << "key_view("; + if (has_shard_pool()) { + os << (unsigned)shard() << "," << pool() << ","; + } else { + os << "X,X,"; + } + if (has_crush()) { + os << crush() << "; "; + } else { + os << "X; "; + } + if (has_ns_oid()) { + os << nspace() << "," << oid() << "; "; + } else { + os << "X,X; "; + } + if (has_snap_gen()) { + os << snap() << "," << gen() << ")"; + } else { + os << "X,X)"; + } + return os; + } + private: const shard_pool_t* p_shard_pool = nullptr; const crush_t* p_crush = nullptr; @@ -511,28 +568,7 @@ inline bool key_view_t::operator==(const full_key_t& o) const { } inline std::ostream& operator<<(std::ostream& os, const key_view_t& key) { - os << "key_view("; - if (key.has_shard_pool()) { - os << (unsigned)key.shard() << "," << key.pool() << ","; - } else { - os << "X,X,"; - } - if (key.has_crush()) { - os << key.crush() << "; "; - } else { - os << "X; "; - } - if (key.has_ns_oid()) { - os << key.nspace() << "," << key.oid() << "; "; - } else { - os << "X,X; "; - } - if (key.has_snap_gen()) { - os << key.snap() << "," << key.gen() << ")"; - } else { - os << "X,X)"; - } - return os; + return key.dump(os); } template 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 984c6fce07a..0a6ba4c25b3 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 @@ -1276,6 +1276,25 @@ struct staged { return os; } + static void validate(const container_t& container) { + auto iter = iterator_t(container); + assert(!iter.is_end()); + auto key = iter.get_key(); + do { + if constexpr (!IS_BOTTOM) { + auto nxt_container = iter.get_nxt_container(); + NXT_STAGE_T::validate(nxt_container); + } + if (iter.is_last()) { + break; + } else { + ++iter; + assert(compare_to(key, iter.get_key()) == MatchKindCMP::NE); + key = iter.get_key(); + } + } while (true); + } + struct _BaseEmpty {}; class _BaseWithNxtIterator { protected: diff --git a/src/crimson/os/seastore/onode_manager/staged-fltree/stages/stage_types.h b/src/crimson/os/seastore/onode_manager/staged-fltree/stages/stage_types.h index b900d666a79..4aef1ede1f5 100644 --- a/src/crimson/os/seastore/onode_manager/staged-fltree/stages/stage_types.h +++ b/src/crimson/os/seastore/onode_manager/staged-fltree/stages/stage_types.h @@ -69,10 +69,36 @@ struct MatchHistory { const_cast&>(get()) = match; } + std::ostream& dump(std::ostream& os) const { + os << "history("; + dump_each(os, left_match) << ", "; + dump_each(os, string_match) << ", "; + dump_each(os, right_match) << ")"; + return os; + } + + std::ostream& dump_each( + std::ostream& os, const std::optional& match) const { + if (!match.has_value()) { + return os << "--"; + } else if (*match == MatchKindCMP::NE) { + return os << "NE"; + } else if (*match == MatchKindCMP::EQ) { + return os << "EQ"; + } else if (*match == MatchKindCMP::PO) { + return os << "PO"; + } else { + assert(false && "impossble path"); + } + } + std::optional left_match; std::optional string_match; std::optional right_match; }; +inline std::ostream& operator<<(std::ostream& os, const MatchHistory& pos) { + return pos.dump(os); +} template struct _check_PO_t { 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 c94199bf5cd..6375d8bb71b 100644 --- a/src/test/crimson/seastore/onode_tree/test_staged_fltree.cc +++ b/src/test/crimson/seastore/onode_tree/test_staged_fltree.cc @@ -657,6 +657,8 @@ class DummyChildPool { assert(false && "impossible path"); } std::ostream& dump_brief(std::ostream&) const override { assert(false && "impossible path"); } + void validate_layout() const override { + assert(false && "impossible path"); } void test_copy_to(NodeExtentMutable&) const override { assert(false && "impossible path"); } void test_set_tail(NodeExtentMutable&) override {