} 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 {
template eagain_ifuture<Ref<tree_cursor_t>>
tree_cursor_t::erase<false>(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;
}
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
}
// 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;
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)
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
}
// 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
}
#pragma once
+#include <compare>
#include <map>
#include <memory>
#include <ostream>
template <bool FORCE_MERGE = false>
eagain_ifuture<Ref<tree_cursor_t>> 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
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 {
full_key_t<KeyT::VIEW> index;
stage_t::template get_slot<true, false>(
node_stage, result_raw.position, &index, nullptr);
- assert(index.compare_to(*index_key) == MatchKindCMP::EQ);
+ assert(index == *index_key);
}
#endif
} else {
// currently only internal node checks mstat
if constexpr (NODE_TYPE == node_type_t::INTERNAL) {
if (result_raw.mstat == MSTAT_LT2) {
- auto cmp = compare_to<KeyT::HOBJ>(
- 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;
}
}
#ifndef NDEBUG
full_key_t<KeyT::VIEW> index;
get_slot(insert_pos, &index, nullptr);
- assert(index.compare_to(key) == MatchKindCMP::EQ);
+ assert(index == key);
#endif
return ret;
}
#ifndef NDEBUG
full_key_t<KeyT::VIEW> 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<KeyT::VIEW> 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);
}
// 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; }
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 <KeyT KT>
static crush_t from_key(const full_key_t<KT>& key);
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 <KeyT KT>
static shard_pool_crush_t from_key(const full_key_t<KT>& key);
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 <KeyT KT>
static snap_gen_t from_key(const full_key_t<KT>& key);
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
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);
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();
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,
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() {
return ghobj.generation;
}
- MatchKindCMP compare_to(const full_key_t<KeyT::VIEW>&) const;
- MatchKindCMP compare_to(const full_key_t<KeyT::HOBJ>&) const;
-
std::ostream& dump(std::ostream& os) const {
os << "key_hobj(" << (int)shard() << ","
<< pool() << ",0x" << std::hex << crush() << std::dec << "; "
return snap_gen_packed().gen;
}
- MatchKindCMP compare_to(const full_key_t<KeyT::VIEW>&) const;
- MatchKindCMP compare_to(const full_key_t<KeyT::HOBJ>&) const;
-
/**
* key_view_t specific interfaces
*/
ceph::encode(key.gen(), bl);
}
-template <KeyT TypeL, KeyT TypeR>
-MatchKindCMP compare_full_key(
- const full_key_t<TypeL>& l, const full_key_t<TypeR>& 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<typename T>
+concept IsFullKey = std::same_as<T, key_hobj_t> || std::same_as<T, key_view_t>;
+
+template<IsFullKey LHS, IsFullKey RHS>
+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<KeyT::VIEW>& o) const {
- return compare_full_key<KeyT::HOBJ, KeyT::VIEW>(*this, o);
-}
-inline MatchKindCMP key_hobj_t::compare_to(
- const full_key_t<KeyT::HOBJ>& o) const {
- return compare_full_key<KeyT::HOBJ, KeyT::HOBJ>(*this, o);
-}
-inline MatchKindCMP key_view_t::compare_to(
- const full_key_t<KeyT::VIEW>& o) const {
- return compare_full_key<KeyT::VIEW, KeyT::VIEW>(*this, o);
-}
-inline MatchKindCMP key_view_t::compare_to(
- const full_key_t<KeyT::HOBJ>& o) const {
- return compare_full_key<KeyT::VIEW, KeyT::HOBJ>(*this, o);
+ return lhs.gen() <=> rhs.gen();
}
template <KeyT KT>
bool is_valid_key(const full_key_t<KT>& 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 <KeyT Type>
-MatchKindCMP compare_to(const full_key_t<Type>& key, const shard_pool_t& target) {
- auto ret = toMatchKindCMP(key.shard(), target.shard);
- if (ret != MatchKindCMP::EQ)
+template <IsFullKey T>
+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 <KeyT Type>
-MatchKindCMP compare_to(const full_key_t<Type>& key, const crush_t& target) {
- return toMatchKindCMP(key.crush(), target.crush);
+template <IsFullKey T>
+auto operator<=>(const T& key, const crush_t& target) {
+ return key.crush() <=> target.crush;
}
-template <KeyT Type>
-MatchKindCMP compare_to(const full_key_t<Type>& key, const shard_pool_crush_t& target) {
- auto ret = compare_to<Type>(key, target.shard_pool);
- if (ret != MatchKindCMP::EQ)
+template <IsFullKey T>
+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<Type>(key, target.crush);
+ return key <=> target.crush;
}
-template <KeyT Type>
-MatchKindCMP compare_to(const full_key_t<Type>& key, const ns_oid_view_t& target) {
- auto ret = compare_to(key.nspace(), string_view_masked_t{target.nspace});
- if (ret != MatchKindCMP::EQ)
+template <IsFullKey T>
+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 <KeyT Type>
-MatchKindCMP compare_to(const full_key_t<Type>& key, const snap_gen_t& target) {
- auto ret = toMatchKindCMP(key.snap(), target.snap);
- if (ret != MatchKindCMP::EQ)
+template <IsFullKey T>
+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 <IsFullKey LHS, typename RHS>
+bool operator==(LHS lhs, RHS rhs) {
+ return lhs <=> rhs == 0;
}
template <KeyT KT>
#pragma once
#include <cassert>
+#include <compare>
#include <optional>
#include <ostream>
#include <sstream>
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<KeyT::HOBJ>(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};
case MSTAT_EQ:
break;
case MSTAT_LT0:
- assert(compare_to<KeyT::HOBJ>(key, index.snap_gen_packed()) == MatchKindCMP::LT);
+ assert(key < index.snap_gen_packed());
break;
case MSTAT_LT1:
- assert(compare_to<KeyT::HOBJ>(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<KeyT::HOBJ>(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<KeyT::HOBJ>(key, index.crush_packed()) == MatchKindCMP::LT);
+ assert(key < index.crush_packed());
}
break;
default:
// key == index ...
switch (mstat) {
case MSTAT_EQ:
- assert(compare_to<KeyT::HOBJ>(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<KeyT::HOBJ>(key, index.ns_oid_view()) == MatchKindCMP::EQ);
+ key == index.ns_oid_view());
case MSTAT_LT1:
if (!index.has_crush())
break;
- assert(compare_to<KeyT::HOBJ>(key, index.crush_packed()) == MatchKindCMP::EQ);
+ assert(key == index.crush_packed());
if (!index.has_shard_pool())
break;
- assert(compare_to<KeyT::HOBJ>(key, index.shard_pool_packed()) == MatchKindCMP::EQ);
+ assert(key == index.shard_pool_packed());
default:
break;
}
if (exclude_last) {
assert(end_index);
--end_index;
- assert(compare_to<KeyT::HOBJ>(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]; });
assert(index() == 0);
do {
if (exclude_last && is_last()) {
- assert(compare_to<KeyT::HOBJ>(key, get_key()) == MatchKindCMP::LT);
+ assert(key < get_key());
return MatchKindBS::NE;
}
- auto match = compare_to<KeyT::HOBJ>(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()) {
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<KeyT::HOBJ>(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<KeyT::HOBJ>(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<GET_KEY>(key, iter, history, index_key);
if constexpr (STAGE == STAGE_STRING) {
// TODO(cross-node string dedup)
// assert(iter.get_key().type() == ns_oid_view_t::Type::MAX);
- assert(compare_to<KeyT::HOBJ>(key, iter.get_key()) == MatchKindCMP::EQ);
+ assert(key == iter.get_key());
} else {
- assert(compare_to<KeyT::HOBJ>(key, iter.get_key()) == MatchKindCMP::EQ);
+ assert(key == iter.get_key());
}
if constexpr (GET_KEY) {
index_key->set(iter.get_key());
assert(is_valid_index(index));
// evaluate the current index
iter.seek_at(index);
- auto match = compare_to<KeyT::VIEW>(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 {
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<KeyT::VIEW>(key, value)};
}
// XXX(multi-type): when key is from a different type of node
- auto match = compare_to<KeyT::VIEW>(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<KeyT::VIEW>(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!");
break;
} else {
++iter;
- assert(compare_to(key, iter.get_key()) == MatchKindCMP::LT);
+ assert(key < iter.get_key());
key = iter.get_key();
}
} while (true);
auto r_iter = iterator_t(right_container);
r_iter.seek_at(0);
node_offset_t compensate = r_iter.header_size();
- auto cmp = compare_to<KeyT::VIEW>(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();
} 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 {
}
}
- 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
return index;
}
- MatchKindCMP compare_to(const staged_position_t<STAGE_BOTTOM>& 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));
*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<Cursor> get_next(Transaction& t) {
assert(!is_end());
}
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());
// 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));