From: Yingxin Cheng Date: Fri, 15 Jan 2021 05:19:31 +0000 (+0800) Subject: crimson/onode-staged-tree: merge tree.cc with tree.h X-Git-Tag: v17.1.0~3086^2~4 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=36541d842de1132ed8c346b08605fd01bd2ae219;p=ceph.git crimson/onode-staged-tree: merge tree.cc with tree.h In preparation to templatize the tree for value implementation. Signed-off-by: Yingxin Cheng --- diff --git a/src/crimson/os/seastore/CMakeLists.txt b/src/crimson/os/seastore/CMakeLists.txt index ceffe209b4a4..988aed2e19ad 100644 --- a/src/crimson/os/seastore/CMakeLists.txt +++ b/src/crimson/os/seastore/CMakeLists.txt @@ -25,7 +25,6 @@ add_library(crimson-seastore STATIC onode_manager/staged-fltree/stages/node_stage.cc onode_manager/staged-fltree/stages/sub_items_stage.cc onode_manager/staged-fltree/super.cc - onode_manager/staged-fltree/tree.cc extentmap_manager.cc extentmap_manager/btree/extentmap_btree_node_impl.cc extentmap_manager/btree/btree_extentmap_manager.cc diff --git a/src/crimson/os/seastore/onode_manager/staged-fltree/tree.cc b/src/crimson/os/seastore/onode_manager/staged-fltree/tree.cc deleted file mode 100644 index 2c8c21652265..000000000000 --- a/src/crimson/os/seastore/onode_manager/staged-fltree/tree.cc +++ /dev/null @@ -1,235 +0,0 @@ -// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:nil -*- -// vim: ts=8 sw=2 smarttab - -#include "tree.h" - -#include "node.h" -#include "node_extent_manager.h" -#include "stages/key_layout.h" -#include "super.h" - -namespace crimson::os::seastore::onode { - -using btree_ertr = Btree::btree_ertr; -template -using btree_future = Btree::btree_future; -using Cursor = Btree::Cursor; - -Cursor::Cursor(Btree* p_tree, Ref _p_cursor) - : p_tree(p_tree) { - if (_p_cursor->is_end()) { - // no need to hold the leaf node - } else { - p_cursor = _p_cursor; - } -} -Cursor::Cursor(Btree* p_tree) : p_tree{p_tree} {} -Cursor::Cursor(const Cursor&) = default; -Cursor::Cursor(Cursor&&) noexcept = default; -Cursor& Cursor::operator=(const Cursor&) = default; -Cursor& Cursor::operator=(Cursor&&) = default; -Cursor::~Cursor() = default; - -bool Cursor::is_end() const { - if (p_cursor) { - assert(!p_cursor->is_end()); - return false; - } else { - return true; - } -} - -ghobject_t Cursor::get_ghobj() const { - return p_cursor->get_key_view().to_ghobj(); -} - -const onode_t* Cursor::value() const { - return p_cursor->get_p_value(); -} - -bool Cursor::operator==(const Cursor& x) const { - return p_cursor == x.p_cursor; -} - -Cursor& Cursor::operator++() { - // TODO - return *this; -} - -Cursor Cursor::operator++(int) { - Cursor tmp = *this; - ++*this; - return tmp; -} - -Cursor Cursor::make_end(Btree* p_tree) { - return {p_tree}; -} - -Btree::Btree(NodeExtentManagerURef&& _nm) - : nm{std::move(_nm)}, - root_tracker{RootNodeTracker::create(nm->is_read_isolated())} {} - -Btree::~Btree() { assert(root_tracker->is_clean()); } - -btree_future<> Btree::mkfs(Transaction& t) { - return Node::mkfs(get_context(t), *root_tracker); -} - -btree_future Btree::begin(Transaction& t) { - return get_root(t).safe_then([this, &t](auto root) { - return root->lookup_smallest(get_context(t)); - }).safe_then([this](auto cursor) { - return Cursor{this, cursor}; - }); -} - -btree_future Btree::last(Transaction& t) { - return get_root(t).safe_then([this, &t](auto root) { - return root->lookup_largest(get_context(t)); - }).safe_then([this](auto cursor) { - return Cursor(this, cursor); - }); -} - -Cursor Btree::end() { - return Cursor::make_end(this); -} - -btree_future -Btree::contains(Transaction& t, const ghobject_t& obj) { - return seastar::do_with( - full_key_t(obj), - [this, &t](auto& key) -> btree_future { - return get_root(t).safe_then([this, &t, &key](auto root) { - // TODO: improve lower_bound() - return root->lower_bound(get_context(t), key); - }).safe_then([](auto result) { - return MatchKindBS::EQ == result.match(); - }); - } - ); -} - -btree_future -Btree::find(Transaction& t, const ghobject_t& obj) { - return seastar::do_with( - full_key_t(obj), - [this, &t](auto& key) -> btree_future { - return get_root(t).safe_then([this, &t, &key](auto root) { - // TODO: improve lower_bound() - return root->lower_bound(get_context(t), key); - }).safe_then([this](auto result) { - if (result.match() == MatchKindBS::EQ) { - return Cursor(this, result.p_cursor); - } else { - return Cursor::make_end(this); - } - }); - } - ); -} - -btree_future -Btree::lower_bound(Transaction& t, const ghobject_t& obj) { - return seastar::do_with( - full_key_t(obj), - [this, &t](auto& key) -> btree_future { - return get_root(t).safe_then([this, &t, &key](auto root) { - return root->lower_bound(get_context(t), key); - }).safe_then([this](auto result) { - return Cursor(this, result.p_cursor); - }); - } - ); -} - -btree_future> -Btree::insert(Transaction& t, const ghobject_t& obj, const onode_t& value) { - return seastar::do_with( - full_key_t(obj), - [this, &t, &value](auto& key) -> btree_future> { - return get_root(t).safe_then([this, &t, &key, &value](auto root) { - return root->insert(get_context(t), key, value); - }).safe_then([this](auto ret) { - auto& [cursor, success] = ret; - return std::make_pair(Cursor(this, cursor), success); - }); - } - ); -} - -btree_future Btree::erase(Transaction& t, const ghobject_t& obj) { - // TODO - return btree_ertr::make_ready_future(0u); -} - -btree_future Btree::erase(Cursor& pos) { - // TODO - return btree_ertr::make_ready_future( - Cursor::make_end(this)); -} - -btree_future -Btree::erase(Cursor& first, Cursor& last) { - // TODO - return btree_ertr::make_ready_future( - Cursor::make_end(this)); -} - -btree_future Btree::height(Transaction& t) { - return get_root(t).safe_then([](auto root) { - return size_t(root->level() + 1); - }); -} - -btree_future Btree::get_stats_slow(Transaction& t) { - return get_root(t).safe_then([this, &t](auto root) { - unsigned height = root->level() + 1; - return root->get_tree_stats(get_context(t) - ).safe_then([height](auto stats) { - stats.height = height; - return btree_ertr::make_ready_future(stats); - }); - }); -} - -std::ostream& Btree::dump(Transaction& t, std::ostream& os) { - auto root = root_tracker->get_root(t); - if (root) { - root->dump(os); - } else { - os << "empty tree!"; - } - return os; -} - -std::ostream& Btree::print(std::ostream& os) const { - return os << "BTree-" << *nm; -} - -btree_future> Btree::get_root(Transaction& t) { - auto root = root_tracker->get_root(t); - if (root) { - return btree_ertr::make_ready_future>(root); - } else { - return Node::load_root(get_context(t), *root_tracker); - } -} - -bool Btree::test_is_clean() const { - return root_tracker->is_clean(); -} - -btree_future<> Btree::test_clone_from( - Transaction& t, Transaction& t_from, Btree& from) { - // Note: assume the tree to clone is tracked correctly in memory. - // In some unit tests, parts of the tree are stubbed out that they - // should not be loaded from NodeExtentManager. - return from.get_root(t_from - ).safe_then([this, &t](auto root_from) { - return root_from->test_clone_root(get_context(t), *root_tracker); - }); -} - -} diff --git a/src/crimson/os/seastore/onode_manager/staged-fltree/tree.h b/src/crimson/os/seastore/onode_manager/staged-fltree/tree.h index 7ee618cb3ff5..6cab27f47eaa 100644 --- a/src/crimson/os/seastore/onode_manager/staged-fltree/tree.h +++ b/src/crimson/os/seastore/onode_manager/staged-fltree/tree.h @@ -9,6 +9,10 @@ #include "crimson/common/type_helpers.h" #include "fwd.h" +#include "node.h" +#include "node_extent_manager.h" +#include "stages/key_layout.h" +#include "super.h" #include "tree_types.h" /** @@ -27,6 +31,8 @@ namespace crimson::os::seastore::onode { class Node; +class tree_cursor_t; + class Btree { public: using btree_ertr = crimson::errorator< @@ -37,45 +43,258 @@ class Btree { template using btree_future = btree_ertr::future; - Btree(NodeExtentManagerURef&& nm); + Btree(NodeExtentManagerURef&& _nm) + : nm{std::move(_nm)}, + root_tracker{RootNodeTracker::create(nm->is_read_isolated())} {} + ~Btree() { assert(root_tracker->is_clean()); } + Btree(const Btree&) = delete; Btree(Btree&&) = delete; Btree& operator=(const Btree&) = delete; Btree& operator=(Btree&&) = delete; - ~Btree(); - btree_future<> mkfs(Transaction&); + btree_future<> mkfs(Transaction& t) { + return Node::mkfs(get_context(t), *root_tracker); + } + + class Cursor { + public: + Cursor(const Cursor&) = default; + Cursor(Cursor&&) noexcept = default; + Cursor& operator=(const Cursor&) = default; + Cursor& operator=(Cursor&&) = default; + ~Cursor() = default; + + bool is_end() const { + if (p_cursor) { + assert(!p_cursor->is_end()); + return false; + } else { + return true; + } + } + + // XXX: return key_view_t to avoid unecessary ghobject_t constructions + ghobject_t get_ghobj() const { + assert(!is_end()); + return p_cursor->get_key_view().to_ghobj(); + } + + const onode_t* value() const { + assert(!is_end()); + return p_cursor->get_p_value(); + } + + bool operator==(const Cursor& x) const { + return p_cursor == x.p_cursor; + } + bool operator!=(const Cursor& x) const { + return !(*this == x); + } + + Cursor& operator++() { + // TODO + return *this; + } + Cursor operator++(int) { + Cursor tmp = *this; + ++*this; + return tmp; + } + + private: + Cursor(Btree* p_tree, Ref _p_cursor) : p_tree(p_tree) { + if (_p_cursor->is_end()) { + // no need to hold the leaf node + } else { + p_cursor = _p_cursor; + } + } + Cursor(Btree* p_tree) : p_tree{p_tree} {} + + static Cursor make_end(Btree* p_tree) { + return {p_tree}; + } + + Btree* p_tree; + Ref p_cursor; + + friend class Btree; + }; + + /* + * lookup + */ + + btree_future begin(Transaction& t) { + return get_root(t).safe_then([this, &t](auto root) { + return root->lookup_smallest(get_context(t)); + }).safe_then([this](auto cursor) { + return Cursor{this, cursor}; + }); + } + + btree_future last(Transaction& t) { + return get_root(t).safe_then([this, &t](auto root) { + return root->lookup_largest(get_context(t)); + }).safe_then([this](auto cursor) { + return Cursor(this, cursor); + }); + } + + Cursor end() { + return Cursor::make_end(this); + } + + btree_future contains(Transaction& t, const ghobject_t& obj) { + return seastar::do_with( + full_key_t(obj), + [this, &t](auto& key) -> btree_future { + return get_root(t).safe_then([this, &t, &key](auto root) { + // TODO: improve lower_bound() + return root->lower_bound(get_context(t), key); + }).safe_then([](auto result) { + return MatchKindBS::EQ == result.match(); + }); + } + ); + } + + btree_future find(Transaction& t, const ghobject_t& obj) { + return seastar::do_with( + full_key_t(obj), + [this, &t](auto& key) -> btree_future { + return get_root(t).safe_then([this, &t, &key](auto root) { + // TODO: improve lower_bound() + return root->lower_bound(get_context(t), key); + }).safe_then([this](auto result) { + if (result.match() == MatchKindBS::EQ) { + return Cursor(this, result.p_cursor); + } else { + return Cursor::make_end(this); + } + }); + } + ); + } + + btree_future lower_bound(Transaction& t, const ghobject_t& obj) { + return seastar::do_with( + full_key_t(obj), + [this, &t](auto& key) -> btree_future { + return get_root(t).safe_then([this, &t, &key](auto root) { + return root->lower_bound(get_context(t), key); + }).safe_then([this](auto result) { + return Cursor(this, result.p_cursor); + }); + } + ); + } - class Cursor; - // lookup - btree_future begin(Transaction&); - btree_future last(Transaction&); - Cursor end(); - btree_future contains(Transaction&, const ghobject_t&); - btree_future find(Transaction&, const ghobject_t&); - btree_future lower_bound(Transaction&, const ghobject_t&); + /* + * modifiers + */ - // modifiers // TODO: replace onode_t btree_future> - insert(Transaction&, const ghobject_t&, const onode_t&); - btree_future erase(Transaction&, const ghobject_t& key); - btree_future erase(Cursor& pos); - btree_future erase(Cursor& first, Cursor& last); + insert(Transaction& t, const ghobject_t& obj, const onode_t& value) { + return seastar::do_with( + full_key_t(obj), + [this, &t, &value](auto& key) -> btree_future> { + return get_root(t).safe_then([this, &t, &key, &value](auto root) { + return root->insert(get_context(t), key, value); + }).safe_then([this](auto ret) { + auto& [cursor, success] = ret; + return std::make_pair(Cursor(this, cursor), success); + }); + } + ); + } - // stats - btree_future height(Transaction&); - btree_future get_stats_slow(Transaction&); - std::ostream& dump(Transaction&, std::ostream&); - std::ostream& print(std::ostream& os) const; + btree_future erase(Transaction& t, const ghobject_t& obj) { + // TODO + return btree_ertr::make_ready_future(0u); + } - // test_only - bool test_is_clean() const; - btree_future<> test_clone_from(Transaction& t, Transaction& t_from, Btree& from); + btree_future erase(Cursor& pos) { + // TODO + return btree_ertr::make_ready_future( + Cursor::make_end(this)); + } + + btree_future erase(Cursor& first, Cursor& last) { + // TODO + return btree_ertr::make_ready_future( + Cursor::make_end(this)); + } + + /* + * stats + */ + + btree_future height(Transaction& t) { + return get_root(t).safe_then([](auto root) { + return size_t(root->level() + 1); + }); + } + + btree_future get_stats_slow(Transaction& t) { + return get_root(t).safe_then([this, &t](auto root) { + unsigned height = root->level() + 1; + return root->get_tree_stats(get_context(t) + ).safe_then([height](auto stats) { + stats.height = height; + return btree_ertr::make_ready_future(stats); + }); + }); + } + + std::ostream& dump(Transaction& t, std::ostream& os) { + auto root = root_tracker->get_root(t); + if (root) { + root->dump(os); + } else { + os << "empty tree!"; + } + return os; + } + + std::ostream& print(std::ostream& os) const { + return os << "BTree-" << *nm; + } + + /* + * test_only + */ + + bool test_is_clean() const { + return root_tracker->is_clean(); + } + + btree_future<> test_clone_from( + Transaction& t, Transaction& t_from, Btree& from) { + // Note: assume the tree to clone is tracked correctly in memory. + // In some unit tests, parts of the tree are stubbed out that they + // should not be loaded from NodeExtentManager. + return from.get_root(t_from + ).safe_then([this, &t](auto root_from) { + return root_from->test_clone_root(get_context(t), *root_tracker); + }); + } private: - context_t get_context(Transaction& t) { return {*nm, t}; } - btree_future> get_root(Transaction& t); + context_t get_context(Transaction& t) { + return {*nm, t}; + } + + btree_future> get_root(Transaction& t) { + auto root = root_tracker->get_root(t); + if (root) { + return btree_ertr::make_ready_future>(root); + } else { + return Node::load_root(get_context(t), *root_tracker); + } + } NodeExtentManagerURef nm; RootNodeTrackerURef root_tracker; @@ -86,34 +305,4 @@ inline std::ostream& operator<<(std::ostream& os, const Btree& tree) { return tree.print(os); } -class tree_cursor_t; -class Btree::Cursor { - public: - Cursor(const Cursor&); - Cursor(Cursor&&) noexcept; - Cursor& operator=(const Cursor&); - Cursor& operator=(Cursor&&); - ~Cursor(); - - bool is_end() const; - // XXX: return key_view_t to avoid unecessary ghobject_t constructions - ghobject_t get_ghobj() const; - const onode_t* value() const; - bool operator==(const Cursor& x) const; - bool operator!=(const Cursor& x) const { return !(*this == x); } - Cursor& operator++(); - Cursor operator++(int); - - private: - Cursor(Btree*, Ref); - Cursor(Btree*); - - static Cursor make_end(Btree*); - - Btree* p_tree; - Ref p_cursor; - - friend class Btree; -}; - }