From: Kefu Chai Date: Sat, 6 Aug 2022 10:26:44 +0000 (+0800) Subject: crimson/os: rewrite ordering using std::strong_ordering X-Git-Tag: v18.0.0~324^2~1 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=a25c6e5bfb3f9b46cd2feec70e2220f5ad39d8d6;p=ceph.git crimson/os: rewrite ordering using std::strong_ordering the goals are 1. to use std::strong_ordering mechinary for better readability and maintainbility 2. to remove unnecessary abstraction 3. use concept for better error message and readability. changes: * replace MatchKindCMP with std::strong_ordering * replace compare_to() with operator<=> * introduce a concept `IsFullKey` so we can use it when developing generic facilities to operate on both materialized key or view. * use `IsFullKey` in place of `KeyT` when appropriate Signed-off-by: Kefu Chai --- 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 b35d003d360a..6a8f82feafdd 100644 --- a/src/crimson/os/seastore/onode_manager/staged-fltree/node.cc +++ b/src/crimson/os/seastore/onode_manager/staged-fltree/node.cc @@ -77,7 +77,7 @@ void tree_cursor_t::assert_next_to( } else if (is_tracked()) { auto key = get_key_view(magic); auto prv_key = prv.get_key_view(magic); - assert(key.compare_to(prv_key) == MatchKindCMP::GT); + assert(key > prv_key); if (ref_leaf_node == prv.ref_leaf_node) { position.assert_next_to(prv.position); } else { @@ -103,32 +103,32 @@ tree_cursor_t::erase(context_t, bool); template eagain_ifuture> tree_cursor_t::erase(context_t, bool); -MatchKindCMP tree_cursor_t::compare_to( +std::strong_ordering tree_cursor_t::compare_to( const tree_cursor_t& o, value_magic_t magic) const { if (!is_tracked() && !o.is_tracked()) { - return MatchKindCMP::EQ; + return std::strong_ordering::equal; } else if (!is_tracked()) { - return MatchKindCMP::GT; + return std::strong_ordering::greater; } else if (!o.is_tracked()) { - return MatchKindCMP::LT; + return std::strong_ordering::less; } assert(is_tracked() && o.is_tracked()); // all tracked cursors are singletons if (this == &o) { - return MatchKindCMP::EQ; + return std::strong_ordering::equal; } - MatchKindCMP ret; + std::strong_ordering ret = std::strong_ordering::equal; if (ref_leaf_node == o.ref_leaf_node) { - ret = position.compare_to(o.position); + ret = position <=> o.position; } else { auto key = get_key_view(magic); auto o_key = o.get_key_view(magic); - ret = key.compare_to(o_key); + ret = key <=> o_key; } - assert(ret != MatchKindCMP::EQ); + assert(ret != 0); return ret; } @@ -259,7 +259,7 @@ void tree_cursor_t::Cache::validate_is_latest(const search_position_t& pos) cons auto [_key_view, _p_value_header] = ref_leaf_node->get_kv(pos); assert(p_node_base == ref_leaf_node->read()); - assert(key_view->compare_to(_key_view) == MatchKindCMP::EQ); + assert(key_view ==_key_view); assert(p_value_header == _p_value_header); #endif } @@ -1465,7 +1465,7 @@ eagain_ifuture> InternalNode::insert_or_split( // XXX: check the insert_child is unlinked from this node #ifndef NDEBUG auto _insert_key = *insert_child->impl->get_pivot_index(); - assert(insert_key.compare_to(_insert_key) == MatchKindCMP::EQ); + assert(insert_key == _insert_key); #endif auto insert_value = insert_child->impl->laddr(); auto insert_pos = pos; @@ -1730,7 +1730,7 @@ void InternalNode::validate_child(const Node& child) const key_view_t index_key; const laddr_packed_t* p_child_addr; impl->get_slot(child_pos, &index_key, &p_child_addr); - assert(index_key.compare_to(*child.impl->get_pivot_index()) == MatchKindCMP::EQ); + assert(index_key == *child.impl->get_pivot_index()); assert(p_child_addr->value == child.impl->laddr()); } // XXX(multi-type) @@ -1752,7 +1752,7 @@ void InternalNode::validate_child_inconsistent(const Node& child) const const laddr_packed_t* p_value; impl->get_slot(child_pos, ¤t_key, &p_value); key_view_t new_key = *child.impl->get_pivot_index(); - assert(current_key.compare_to(new_key) != MatchKindCMP::EQ); + assert(current_key != new_key); assert(p_value->value == child.impl->laddr()); #endif } @@ -2184,7 +2184,7 @@ void LeafNode::validate_cursor(const tree_cursor_t& cursor) const // behaviors. auto [key, p_value_header] = get_kv(cursor.get_position()); auto magic = p_value_header->magic; - assert(key.compare_to(cursor.get_key_view(magic)) == MatchKindCMP::EQ); + assert(key == cursor.get_key_view(magic)); assert(p_value_header == cursor.read_value_header(magic)); #endif } diff --git a/src/crimson/os/seastore/onode_manager/staged-fltree/node.h b/src/crimson/os/seastore/onode_manager/staged-fltree/node.h index 51e8c54085f8..4ba1d5b5887b 100644 --- a/src/crimson/os/seastore/onode_manager/staged-fltree/node.h +++ b/src/crimson/os/seastore/onode_manager/staged-fltree/node.h @@ -3,6 +3,7 @@ #pragma once +#include #include #include #include @@ -123,7 +124,7 @@ class tree_cursor_t final template eagain_ifuture> erase(context_t, bool get_next); - MatchKindCMP compare_to(const tree_cursor_t&, value_magic_t) const; + std::strong_ordering compare_to(const tree_cursor_t&, value_magic_t) const; // public to Value @@ -274,11 +275,11 @@ class Node void validate_input_key(const key_hobj_t& key, value_magic_t magic) const { #ifndef NDEBUG if (match() == MatchKindBS::EQ) { - assert(key.compare_to(p_cursor->get_key_view(magic)) == MatchKindCMP::EQ); + assert(key == p_cursor->get_key_view(magic)); } else { assert(match() == MatchKindBS::NE); if (p_cursor->is_tracked()) { - assert(key.compare_to(p_cursor->get_key_view(magic)) == MatchKindCMP::LT); + assert(key < p_cursor->get_key_view(magic)); } else if (p_cursor->is_end()) { // good } else { 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 2433816d06d4..5f3b35de05de 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 @@ -523,7 +523,7 @@ class NodeLayoutT final : public InternalNodeImpl, public LeafNodeImpl { full_key_t index; stage_t::template get_slot( node_stage, result_raw.position, &index, nullptr); - assert(index.compare_to(*index_key) == MatchKindCMP::EQ); + assert(index == *index_key); } #endif } else { @@ -545,10 +545,10 @@ class NodeLayoutT final : public InternalNodeImpl, public LeafNodeImpl { // currently only internal node checks mstat if constexpr (NODE_TYPE == node_type_t::INTERNAL) { if (result_raw.mstat == MSTAT_LT2) { - auto cmp = compare_to( - key, node_stage[result_raw.position.index].shard_pool); - assert(cmp != MatchKindCMP::GT); - if (cmp != MatchKindCMP::EQ) { + auto cmp = + key <=> node_stage[result_raw.position.index].shard_pool; + assert(cmp != std::strong_ordering::greater); + if (cmp != 0) { result_raw.mstat = MSTAT_LT3; } } @@ -595,7 +595,7 @@ class NodeLayoutT final : public InternalNodeImpl, public LeafNodeImpl { #ifndef NDEBUG full_key_t index; get_slot(insert_pos, &index, nullptr); - assert(index.compare_to(key) == MatchKindCMP::EQ); + assert(index == key); #endif return ret; } @@ -775,14 +775,14 @@ class NodeLayoutT final : public InternalNodeImpl, public LeafNodeImpl { #ifndef NDEBUG full_key_t index; get_slot(_insert_pos, &index, nullptr); - assert(index.compare_to(key) == MatchKindCMP::EQ); + assert(index == key); #endif } else { SUBDEBUG(seastore_onode, "-- left trim ..."); #ifndef NDEBUG full_key_t index; right_impl.get_slot(_insert_pos, &index, nullptr); - assert(index.compare_to(key) == MatchKindCMP::EQ); + assert(index == key); #endif extent.split_replayable(split_at); } 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 93176a8fd404..5309e9a111b8 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 @@ -57,10 +57,7 @@ struct node_offset_packed_t { // TODO: consider alignments struct shard_pool_t { - bool operator==(const shard_pool_t& x) const { - return (shard == x.shard && pool() == x.pool()); - } - bool operator!=(const shard_pool_t& x) const { return !(*this == x); } + auto operator<=>(const shard_pool_t&) const = default; pool_t pool() const { return _pool; } @@ -73,17 +70,10 @@ struct shard_pool_t { inline std::ostream& operator<<(std::ostream& os, const shard_pool_t& sp) { return os << (int)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()); -} // Note: this is the reversed version of the object hash struct crush_t { - bool operator==(const crush_t& x) const { return crush == x.crush; } - bool operator!=(const crush_t& x) const { return !(*this == x); } + auto operator<=>(const crush_t&) const = default; template static crush_t from_key(const full_key_t& key); @@ -93,15 +83,9 @@ struct crush_t { inline std::ostream& operator<<(std::ostream& os, const crush_t& c) { return os << "0x" << std::hex << c.crush << std::dec; } -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 { - return (shard_pool == x.shard_pool && crush == x.crush); - } - bool operator!=(const shard_pool_crush_t& x) const { return !(*this == x); } + auto operator<=>(const shard_pool_crush_t&) const = default; template static shard_pool_crush_t from_key(const full_key_t& key); @@ -112,19 +96,9 @@ struct shard_pool_crush_t { inline std::ostream& operator<<(std::ostream& os, const shard_pool_crush_t& spc) { return os << spc.shard_pool << ",0x" << std::hex << spc.crush << std::dec; } -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 { - return (snap == x.snap && gen == x.gen); - } - bool operator!=(const snap_gen_t& x) const { return !(*this == x); } + auto operator<=>(const snap_gen_t&) const = default; template static snap_gen_t from_key(const full_key_t& key); @@ -135,12 +109,6 @@ 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); -} /** * string_key_view_t @@ -317,7 +285,19 @@ class string_view_masked_t { return false; return (memcmp(view.data(), x.view.data(), size()) == 0); } - bool operator!=(const string_view_masked_t& x) const { return !(*this == x); } + auto operator<=>(std::string_view rhs) const { + using Type = string_view_masked_t::Type; + assert(string_key_view_t::is_valid_size(rhs.size())); + auto lhs_type = get_type(); + if (lhs_type == Type::MIN) { + return std::strong_ordering::less; + } else if (lhs_type == Type::MAX) { + return std::strong_ordering::greater; + } else { // r_type == Type::STR + assert(string_key_view_t::is_valid_size(size())); + return to_string_view() <=> rhs; + } + } void encode(ceph::bufferlist& bl) const { if (get_type() == Type::MIN) { ceph::encode(string_key_view_t::MARKER_MIN, bl); @@ -351,38 +331,24 @@ class string_view_masked_t { Type type; std::string_view view; }; -inline MatchKindCMP compare_to(const string_view_masked_t& l, const string_view_masked_t& r) { + +inline auto operator<=>(const string_view_masked_t& l, const string_view_masked_t& r) { using Type = string_view_masked_t::Type; auto l_type = l.get_type(); auto r_type = r.get_type(); if (l_type == Type::STR && r_type == Type::STR) { assert(string_key_view_t::is_valid_size(l.size())); assert(string_key_view_t::is_valid_size(r.size())); - return toMatchKindCMP(l.to_string_view(), r.to_string_view()); + return l.to_string_view() <=> r.to_string_view(); } else if (l_type == r_type) { - return MatchKindCMP::EQ; + return std::strong_ordering::equal; } else if (l_type == Type::MIN || r_type == Type::MAX) { - return MatchKindCMP::LT; + return std::strong_ordering::less; } else { // l_type == Type::MAX || r_type == Type::MIN - return MatchKindCMP::GT; + return std::strong_ordering::greater; } } -inline MatchKindCMP compare_to(std::string_view l, const string_view_masked_t& r) { - using Type = string_view_masked_t::Type; - assert(string_key_view_t::is_valid_size(l.size())); - auto r_type = r.get_type(); - if (r_type == Type::MIN) { - return MatchKindCMP::GT; - } else if (r_type == Type::MAX) { - return MatchKindCMP::LT; - } else { // r_type == Type::STR - assert(string_key_view_t::is_valid_size(r.size())); - return toMatchKindCMP(l, r.to_string_view()); - } -} -inline MatchKindCMP compare_to(const string_view_masked_t& l, std::string_view r) { - return reverse(compare_to(r, l)); -} + inline std::ostream& operator<<(std::ostream& os, const string_view_masked_t& masked) { using Type = string_view_masked_t::Type; auto type = masked.get_type(); @@ -430,7 +396,6 @@ struct ns_oid_view_t { return (string_view_masked_t{nspace} == string_view_masked_t{x.nspace} && string_view_masked_t{oid} == string_view_masked_t{x.oid}); } - bool operator!=(const ns_oid_view_t& x) const { return !(*this == x); } void reset_to(const char* origin_base, const char* new_base, @@ -468,13 +433,11 @@ inline std::ostream& operator<<(std::ostream& os, const ns_oid_view_t& ns_oid) { return os << string_view_masked_t{ns_oid.nspace} << "," << string_view_masked_t{ns_oid.oid}; } -inline MatchKindCMP compare_to(const ns_oid_view_t& l, const ns_oid_view_t& r) { - auto ret = compare_to(string_view_masked_t{l.nspace}, - string_view_masked_t{r.nspace}); - if (ret != MatchKindCMP::EQ) +inline auto operator<=>(const ns_oid_view_t& l, const ns_oid_view_t& r) { + auto ret = (string_view_masked_t{l.nspace} <=> string_view_masked_t{r.nspace}); + if (ret != 0) return ret; - return compare_to(string_view_masked_t{l.oid}, - string_view_masked_t{r.oid}); + return string_view_masked_t{l.oid} <=> string_view_masked_t{r.oid}; } inline const ghobject_t _MIN_OID() { @@ -560,9 +523,6 @@ class key_hobj_t { return ghobj.generation; } - MatchKindCMP compare_to(const full_key_t&) const; - MatchKindCMP compare_to(const full_key_t&) const; - std::ostream& dump(std::ostream& os) const { os << "key_hobj(" << (int)shard() << "," << pool() << ",0x" << std::hex << crush() << std::dec << "; " @@ -657,9 +617,6 @@ class key_view_t { return snap_gen_packed().gen; } - MatchKindCMP compare_to(const full_key_t&) const; - MatchKindCMP compare_to(const full_key_t&) const; - /** * key_view_t specific interfaces */ @@ -787,92 +744,82 @@ void encode_key(const full_key_t& key, ceph::bufferlist& bl) { ceph::encode(key.gen(), bl); } -template -MatchKindCMP compare_full_key( - const full_key_t& l, const full_key_t& r) { - auto ret = toMatchKindCMP(l.shard(), r.shard()); - if (ret != MatchKindCMP::EQ) - return ret; - ret = toMatchKindCMP(l.pool(), r.pool()); - if (ret != MatchKindCMP::EQ) +template +concept IsFullKey = std::same_as || std::same_as; + +template +std::strong_ordering operator<=>(const LHS& lhs, const RHS& rhs) noexcept { + auto ret = lhs.shard() <=> rhs.shard(); + if (ret != 0) return ret; - ret = toMatchKindCMP(l.crush(), r.crush()); - if (ret != MatchKindCMP::EQ) + ret = lhs.pool() <=> rhs.pool(); + if (ret != 0) + return ret; + ret = lhs.crush() <=> rhs.crush(); + if (ret != 0) return ret; - ret = toMatchKindCMP(l.nspace(), r.nspace()); - if (ret != MatchKindCMP::EQ) + ret = lhs.nspace() <=> rhs.nspace(); + if (ret != 0) return ret; - ret = toMatchKindCMP(l.oid(), r.oid()); - if (ret != MatchKindCMP::EQ) + ret = lhs.oid() <=> rhs.oid(); + if (ret != 0) return ret; - ret = toMatchKindCMP(l.snap(), r.snap()); - if (ret != MatchKindCMP::EQ) + ret = lhs.snap() <=> rhs.snap(); + if (ret != 0) return ret; - return toMatchKindCMP(l.gen(), r.gen()); -} - -inline MatchKindCMP key_hobj_t::compare_to( - const full_key_t& o) const { - return compare_full_key(*this, o); -} -inline MatchKindCMP key_hobj_t::compare_to( - const full_key_t& o) const { - return compare_full_key(*this, o); -} -inline MatchKindCMP key_view_t::compare_to( - const full_key_t& o) const { - return compare_full_key(*this, o); -} -inline MatchKindCMP key_view_t::compare_to( - const full_key_t& o) const { - return compare_full_key(*this, o); + return lhs.gen() <=> rhs.gen(); } template bool is_valid_key(const full_key_t& key) { - return key.compare_to(key_hobj_t(ghobject_t())) == MatchKindCMP::GT && - key.compare_to(key_hobj_t(ghobject_t::get_max())) == MatchKindCMP::LT; + return (key > key_hobj_t(ghobject_t()) && + key < key_hobj_t(ghobject_t::get_max())); } inline std::ostream& operator<<(std::ostream& os, const key_view_t& key) { return key.dump(os); } -template -MatchKindCMP compare_to(const full_key_t& key, const shard_pool_t& target) { - auto ret = toMatchKindCMP(key.shard(), target.shard); - if (ret != MatchKindCMP::EQ) +template +auto operator<=>(const T& key, const shard_pool_t& target) { + auto ret = key.shard() <=> target.shard; + if (ret != 0) return ret; - return toMatchKindCMP(key.pool(), target.pool()); + return key.pool() <=> target.pool(); } -template -MatchKindCMP compare_to(const full_key_t& key, const crush_t& target) { - return toMatchKindCMP(key.crush(), target.crush); +template +auto operator<=>(const T& key, const crush_t& target) { + return key.crush() <=> target.crush; } -template -MatchKindCMP compare_to(const full_key_t& key, const shard_pool_crush_t& target) { - auto ret = compare_to(key, target.shard_pool); - if (ret != MatchKindCMP::EQ) +template +auto operator<=>(const T& key, const shard_pool_crush_t& target) { + auto ret = key <=> target.shard_pool; + if (ret != 0) return ret; - return compare_to(key, target.crush); + return key <=> target.crush; } -template -MatchKindCMP compare_to(const full_key_t& key, const ns_oid_view_t& target) { - auto ret = compare_to(key.nspace(), string_view_masked_t{target.nspace}); - if (ret != MatchKindCMP::EQ) +template +auto operator<=>(const T& key, const ns_oid_view_t& target) { + auto ret = key.nspace() <=> string_view_masked_t{target.nspace}; + if (ret != 0) return ret; - return compare_to(key.oid(), string_view_masked_t{target.oid}); + return key.oid() <=> string_view_masked_t{target.oid}; } -template -MatchKindCMP compare_to(const full_key_t& key, const snap_gen_t& target) { - auto ret = toMatchKindCMP(key.snap(), target.snap); - if (ret != MatchKindCMP::EQ) +template +auto operator<=>(const T& key, const snap_gen_t& target) { + auto ret = key.snap() <=> target.snap; + if (ret != 0) return ret; - return toMatchKindCMP(key.gen(), target.gen); + return key.gen() <=> target.gen; +} + +template +bool operator==(LHS lhs, RHS rhs) { + return lhs <=> rhs == 0; } 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 4ea88cadf753..0ccc4ce74dd8 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 @@ -4,6 +4,7 @@ #pragma once #include +#include #include #include #include @@ -30,10 +31,10 @@ search_result_bs_t binary_search( auto mid = total >> 1; // do not copy if return value is reference decltype(f_get_key(mid)) target = f_get_key(mid); - auto match = compare_to(key, target); - if (match == MatchKindCMP::LT) { + auto match = key <=> target; + if (match == std::strong_ordering::less) { end = mid; - } else if (match == MatchKindCMP::GT) { + } else if (match == std::strong_ordering::greater) { begin = mid + 1; } else { return {mid, MatchKindBS::EQ}; @@ -93,17 +94,17 @@ inline void assert_mstat( case MSTAT_EQ: break; case MSTAT_LT0: - assert(compare_to(key, index.snap_gen_packed()) == MatchKindCMP::LT); + assert(key < index.snap_gen_packed()); break; case MSTAT_LT1: - assert(compare_to(key, index.ns_oid_view()) == MatchKindCMP::LT); + assert(key < index.ns_oid_view()); break; case MSTAT_LT2: if (index.has_shard_pool()) { - assert(compare_to(key, shard_pool_crush_t{ - index.shard_pool_packed(), index.crush_packed()}) == MatchKindCMP::LT); + assert((key < shard_pool_crush_t{ + index.shard_pool_packed(), index.crush_packed()})); } else { - assert(compare_to(key, index.crush_packed()) == MatchKindCMP::LT); + assert(key < index.crush_packed()); } break; default: @@ -112,19 +113,19 @@ inline void assert_mstat( // key == index ... switch (mstat) { case MSTAT_EQ: - assert(compare_to(key, index.snap_gen_packed()) == MatchKindCMP::EQ); + assert(key == index.snap_gen_packed()); case MSTAT_LT0: if (!index.has_ns_oid()) break; assert(index.ns_oid_view().type() == ns_oid_view_t::Type::MAX || - compare_to(key, index.ns_oid_view()) == MatchKindCMP::EQ); + key == index.ns_oid_view()); case MSTAT_LT1: if (!index.has_crush()) break; - assert(compare_to(key, index.crush_packed()) == MatchKindCMP::EQ); + assert(key == index.crush_packed()); if (!index.has_shard_pool()) break; - assert(compare_to(key, index.shard_pool_packed()) == MatchKindCMP::EQ); + assert(key == index.shard_pool_packed()); default: break; } @@ -307,7 +308,7 @@ struct staged { if (exclude_last) { assert(end_index); --end_index; - assert(compare_to(key, container[end_index]) == MatchKindCMP::LT); + assert(key < container[end_index]); } auto ret = binary_search(key, _index, end_index, [this] (index_t index) { return container[index]; }); @@ -624,13 +625,13 @@ struct staged { assert(index() == 0); do { if (exclude_last && is_last()) { - assert(compare_to(key, get_key()) == MatchKindCMP::LT); + assert(key < get_key()); return MatchKindBS::NE; } - auto match = compare_to(key, get_key()); - if (match == MatchKindCMP::LT) { + auto match = key <=> get_key(); + if (match == std::strong_ordering::less) { return MatchKindBS::NE; - } else if (match == MatchKindCMP::EQ) { + } else if (match == std::strong_ordering::equal) { return MatchKindBS::EQ; } else { if (container.has_next()) { @@ -1058,16 +1059,16 @@ struct staged { if constexpr (STAGE == STAGE_STRING) { // TODO(cross-node string dedup) // test_key_equal = (iter.get_key().type() == ns_oid_view_t::Type::MIN); - auto cmp = compare_to(key, iter.get_key()); - assert(cmp != MatchKindCMP::GT); - test_key_equal = (cmp == MatchKindCMP::EQ); + auto cmp = key <=> iter.get_key(); + assert(cmp != std::strong_ordering::greater); + test_key_equal = (cmp == 0); } else { - auto cmp = compare_to(key, iter.get_key()); + auto cmp = key <=> iter.get_key(); // From history, key[stage] == parent[stage][index - 1] // which should be the smallest possible value for all // index[stage][*] - assert(cmp != MatchKindCMP::GT); - test_key_equal = (cmp == MatchKindCMP::EQ); + assert(cmp != std::strong_ordering::greater); + test_key_equal = (cmp == 0); } if (test_key_equal) { return nxt_lower_bound(key, iter, history, index_key); @@ -1083,9 +1084,9 @@ struct staged { if constexpr (STAGE == STAGE_STRING) { // TODO(cross-node string dedup) // assert(iter.get_key().type() == ns_oid_view_t::Type::MAX); - assert(compare_to(key, iter.get_key()) == MatchKindCMP::EQ); + assert(key == iter.get_key()); } else { - assert(compare_to(key, iter.get_key()) == MatchKindCMP::EQ); + assert(key == iter.get_key()); } if constexpr (GET_KEY) { index_key->set(iter.get_key()); @@ -1170,8 +1171,8 @@ struct staged { assert(is_valid_index(index)); // evaluate the current index iter.seek_at(index); - auto match = compare_to(key, iter.get_key()); - if (match == MatchKindCMP::EQ) { + auto match = key <=> iter.get_key(); + if (match == 0) { if constexpr (IS_BOTTOM) { ceph_abort("insert conflict at current index!"); } else { @@ -1181,7 +1182,7 @@ struct staged { nxt_container, key, value, position.nxt, false); } } else { - assert(match == MatchKindCMP::LT); + assert(match == std::strong_ordering::less); if (index == 0) { // already the first index, so insert at the current index return {STAGE, insert_size(key, value)}; @@ -1194,13 +1195,13 @@ struct staged { } // XXX(multi-type): when key is from a different type of node - auto match = compare_to(key, iter.get_key()); - if (match == MatchKindCMP::GT) { + auto match = key <=> iter.get_key(); + if (match == std::strong_ordering::greater) { // key doesn't match both indexes, so insert at the current index ++index; return {STAGE, insert_size(key, value)}; } else { - assert(match == MatchKindCMP::EQ); + assert(match == std::strong_ordering::equal); if constexpr (IS_BOTTOM) { // ceph_abort? ceph_abort("insert conflict at the previous index!"); @@ -1470,7 +1471,7 @@ struct staged { break; } else { ++iter; - assert(compare_to(key, iter.get_key()) == MatchKindCMP::LT); + assert(key < iter.get_key()); key = iter.get_key(); } } while (true); @@ -2348,8 +2349,8 @@ struct staged { auto r_iter = iterator_t(right_container); r_iter.seek_at(0); node_offset_t compensate = r_iter.header_size(); - auto cmp = compare_to(left_pivot_index, r_iter.get_key()); - if (cmp == MatchKindCMP::EQ) { + auto cmp = left_pivot_index <=> r_iter.get_key(); + if (cmp == std::strong_ordering::equal) { if constexpr (!IS_BOTTOM) { // the index is equal, compensate and look at the lower stage compensate += r_iter.size_to_nxt(); @@ -2361,7 +2362,7 @@ struct staged { } else { ceph_abort("impossible path: left_pivot_key == right_first_key"); } - } else if (cmp == MatchKindCMP::LT) { + } else if (cmp == std::strong_ordering::less) { // ok, do merge here return {STAGE, compensate}; } else { 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 94017bb60079..7480c9a051cc 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 @@ -149,21 +149,7 @@ struct staged_position_t { } } - MatchKindCMP compare_to(const me_t& o) const { - if (index > o.index) { - return MatchKindCMP::GT; - } else if (index < o.index) { - return MatchKindCMP::LT; - } else { - return nxt.compare_to(o.nxt); - } - } - bool operator>(const me_t& o) const { return (int)compare_to(o) > 0; } - bool operator>=(const me_t& o) const { return (int)compare_to(o) >= 0; } - bool operator<(const me_t& o) const { return (int)compare_to(o) < 0; } - bool operator<=(const me_t& o) const { return (int)compare_to(o) <= 0; } - bool operator==(const me_t& o) const { return (int)compare_to(o) == 0; } - bool operator!=(const me_t& o) const { return (int)compare_to(o) != 0; } + auto operator<=>(const me_t& o) const = default; void assert_next_to(const me_t& prv) const { #ifndef NDEBUG @@ -251,21 +237,7 @@ struct staged_position_t { return index; } - MatchKindCMP compare_to(const staged_position_t& o) const { - if (index > o.index) { - return MatchKindCMP::GT; - } else if (index < o.index) { - return MatchKindCMP::LT; - } else { - return MatchKindCMP::EQ; - } - } - bool operator>(const me_t& o) const { return (int)compare_to(o) > 0; } - bool operator>=(const me_t& o) const { return (int)compare_to(o) >= 0; } - bool operator<(const me_t& o) const { return (int)compare_to(o) < 0; } - bool operator<=(const me_t& o) const { return (int)compare_to(o) <= 0; } - bool operator==(const me_t& o) const { return (int)compare_to(o) == 0; } - bool operator!=(const me_t& o) const { return (int)compare_to(o) != 0; } + auto operator<=>(const me_t&) const = default; me_t& operator-=(const me_t& o) { assert(is_valid_index(o.index)); 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 73bf8c631993..2f379c7d3193 100644 --- a/src/crimson/os/seastore/onode_manager/staged-fltree/tree.h +++ b/src/crimson/os/seastore/onode_manager/staged-fltree/tree.h @@ -95,12 +95,7 @@ class Btree { *p_tree->nm, p_tree->value_builder, p_cursor); } - bool operator>(const Cursor& o) const { return (int)compare_to(o) > 0; } - bool operator>=(const Cursor& o) const { return (int)compare_to(o) >= 0; } - bool operator<(const Cursor& o) const { return (int)compare_to(o) < 0; } - bool operator<=(const Cursor& o) const { return (int)compare_to(o) <= 0; } - bool operator==(const Cursor& o) const { return (int)compare_to(o) == 0; } - bool operator!=(const Cursor& o) const { return (int)compare_to(o) != 0; } + bool operator==(const Cursor& o) const { return operator<=>(o) == 0; } eagain_ifuture get_next(Transaction& t) { assert(!is_end()); @@ -146,7 +141,7 @@ class Btree { } Cursor(Btree* p_tree) : p_tree{p_tree} {} - MatchKindCMP compare_to(const Cursor& o) const { + std::strong_ordering operator<=>(const Cursor& o) const { assert(p_tree == o.p_tree); return p_cursor->compare_to( *o.p_cursor, p_tree->value_builder.get_header_magic()); 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 a1c743bca2b7..99e60878ddac 100644 --- a/src/test/crimson/seastore/onode_tree/test_staged_fltree.cc +++ b/src/test/crimson/seastore/onode_tree/test_staged_fltree.cc @@ -1193,7 +1193,7 @@ class DummyChildPool { // erase and merge [[maybe_unused]] auto pivot_key = node_to_split->get_pivot_key(); logger().info("\n\nERASE-MERGE {}:", node_to_split->get_name()); - assert(pivot_key.compare_to(key_hobj_t(key)) == MatchKindCMP::EQ); + assert(pivot_key == key_hobj_t(key)); with_trans_intr(pool_clone.get_context().t, [&] (auto &t) { return node_to_split->merge( pool_clone.get_context(), std::move(node_to_split));