MatchHistory(), [this, c, &key, &value](auto& history) {
return lower_bound_tracked(c, key, history
).safe_then([c, &key, &value, &history](auto result) {
- if (result.match == MatchKindBS::EQ) {
+ if (result.match() == MatchKindBS::EQ) {
return node_ertr::make_ready_future<std::pair<Ref<tree_cursor_t>, bool>>(
std::make_pair(result.p_cursor, false));
} else {
auto leaf_node = result.p_cursor->get_leaf_node();
return leaf_node->insert_value(
- c, key, value, result.p_cursor->get_position(), history
+ c, key, value, result.p_cursor->get_position(), history, result.mstat
).safe_then([](auto p_cursor) {
return node_ertr::make_ready_future<std::pair<Ref<tree_cursor_t>, bool>>(
std::make_pair(p_cursor, true));
cursor = get_or_track_cursor(result.position, index_key, result.p_value);
}
return node_ertr::make_ready_future<search_result_t>(
- search_result_t{cursor, result.match()});
+ search_result_t{cursor, result.mstat});
}
node_future<> LeafNode::test_clone_root(
node_future<Ref<tree_cursor_t>> LeafNode::insert_value(
context_t c, const key_hobj_t& key, const onode_t& value,
- const search_position_t& pos, const MatchHistory& history) {
+ const search_position_t& pos, const MatchHistory& history,
+ match_stat_t mstat) {
#ifndef NDEBUG
if (pos.is_end()) {
assert(impl->is_level_tail());
#endif
std::cout << "leaf insert at pos(" << pos << "), "
<< key << ", " << value << ", " << history
+ << ", mstat(" << (int)mstat << ")"
<< std::endl;
#if 0
std::cout << "before insert:" << std::endl;
search_position_t insert_pos = pos;
auto [insert_stage, insert_size] = impl->evaluate_insert(
- key, value, history, insert_pos);
+ key, value, history, mstat, insert_pos);
auto free_size = impl->free_size();
if (free_size >= insert_size) {
// insert
struct search_result_t {
bool is_end() const { return p_cursor->is_end(); }
Ref<tree_cursor_t> p_cursor;
- MatchKindBS match;
+ match_stat_t mstat;
+
+ MatchKindBS match() const {
+ assert(mstat >= MSTAT_MIN && mstat <= MSTAT_MAX);
+ return (mstat == MSTAT_EQ ? MatchKindBS::EQ : MatchKindBS::NE);
+ }
};
virtual ~Node();
LeafNode(LeafNodeImpl*, NodeImplURef&&);
node_future<Ref<tree_cursor_t>> insert_value(
context_t, const key_hobj_t&, const onode_t&,
- const search_position_t&, const MatchHistory&);
+ const search_position_t&, const MatchHistory&,
+ match_stat_t mstat);
static node_future<Ref<LeafNode>> allocate_root(context_t, RootNodeTracker&);
friend class Node;
search_position_t&, key_view_t&, const onode_t**) const = 0;
virtual std::tuple<match_stage_t, node_offset_t> evaluate_insert(
const key_hobj_t&, const onode_t&,
- const MatchHistory&, search_position_t&) const = 0;
+ const MatchHistory&, match_stat_t, search_position_t&) const = 0;
struct fresh_impl_t {
LeafNodeImplURef impl;
}
std::tuple<match_stage_t, node_offset_t> evaluate_insert(
- const key_hobj_t& key, const onode_t& value, const MatchHistory& history,
+ const key_hobj_t& key, const onode_t& value,
+ const MatchHistory& history, match_stat_t mstat,
search_position_t& insert_pos) const override {
if constexpr (NODE_TYPE == node_type_t::LEAF) {
return STAGE_T::evaluate_insert(
- key, value, history, cast_down<STAGE>(insert_pos));
+ key, value, history, mstat, cast_down<STAGE>(insert_pos));
} else {
assert(false && "impossible path");
}
laddr_t value;
} __attribute__((packed));
+using match_stat_t = int8_t;
+constexpr match_stat_t MSTAT_END = -2; // index is search_position_t::end()
+constexpr match_stat_t MSTAT_EQ = -1; // key == index
+constexpr match_stat_t MSTAT_NE0 = 0; // key == index [pool/shard crush ns/oid]; key < index [snap/gen]
+constexpr match_stat_t MSTAT_NE1 = 1; // key == index [pool/shard crush]; key < index [ns/oid]
+constexpr match_stat_t MSTAT_NE2 = 2; // key < index [pool/shard crush ns/oid] ||
+ // key == index [pool/shard]; key < index [crush]
+constexpr match_stat_t MSTAT_NE3 = 3; // key < index [pool/shard]
+constexpr match_stat_t MSTAT_MIN = MSTAT_END;
+constexpr match_stat_t MSTAT_MAX = MSTAT_NE3;
+
}
template <typename T = std::tuple<match_stage_t, node_offset_t>>
static std::enable_if_t<NODE_TYPE == node_type_t::LEAF, T> evaluate_insert(
const full_key_t<KeyT::HOBJ>& key, const onode_t& value,
- const MatchHistory& history, position_t& position) {
+ const MatchHistory& history, match_stat_t mstat, position_t& position) {
match_stage_t insert_stage = STAGE_TOP;
while (*history.get_by_stage(insert_stage) == MatchKindCMP::EQ) {
assert(insert_stage != STAGE_BOTTOM && "insert conflict!");
assert(insert_stage <= STAGE && "impossible insert stage");
} else if (position == position_t::begin()) {
// I must be short-circuited by staged::smallest_result()
- // in staged::lower_bound()
-
+ // in staged::lower_bound(), so we need to rely on mstat instead
+ assert(mstat >= MSTAT_NE0 && mstat <= MSTAT_NE3);
+ if (mstat == MSTAT_NE0) {
+ insert_stage = STAGE_RIGHT;
+ } else if (mstat == MSTAT_NE1) {
+ insert_stage = STAGE_STRING;
+ } else {
+ insert_stage = STAGE_LEFT;
+ }
// XXX(multi-type): need to upgrade node type before inserting an
// incompatible index at front.
assert(insert_stage <= STAGE && "incompatible insert");
-
- // insert at begin and at the top stage
- insert_stage = STAGE;
} else {
assert(insert_stage <= STAGE && "impossible insert stage");
bool ret = compensate_insert_position_at(insert_stage, position);
template <node_type_t NODE_TYPE>
using value_type_t = typename value_type<NODE_TYPE>::type;
-using match_stat_t = int8_t;
-constexpr match_stat_t MSTAT_END = -2; // index is search_position_t::end()
-constexpr match_stat_t MSTAT_EQ = -1; // key == index
-constexpr match_stat_t MSTAT_NE0 = 0; // key == index [pool/shard crush ns/oid]; key < index [snap/gen]
-constexpr match_stat_t MSTAT_NE1 = 1; // key == index [pool/shard crush]; key < index [ns/oid]
-constexpr match_stat_t MSTAT_NE2 = 2; // key < index [pool/shard crush ns/oid] ||
- // key == index [pool/shard]; key < index [crush]
-constexpr match_stat_t MSTAT_NE3 = 3; // key < index [pool/shard]
-constexpr match_stat_t MSTAT_MIN = MSTAT_END;
-constexpr match_stat_t MSTAT_MAX = MSTAT_NE3;
-
template <node_type_t NODE_TYPE, match_stage_t STAGE>
struct staged_result_t {
using me_t = staged_result_t<NODE_TYPE, STAGE>;
bool is_end() const { return position.is_end(); }
- MatchKindBS match() const {
- assert(mstat >= MSTAT_MIN && mstat <= MSTAT_MAX);
- return (mstat == MSTAT_EQ ? MatchKindBS::EQ : MatchKindBS::NE);
- }
static me_t end() {
return {staged_position_t<STAGE>::end(), nullptr, MSTAT_END};
// TODO: improve lower_bound()
return root->lower_bound(get_context(t), key);
}).safe_then([](auto result) {
- return MatchKindBS::EQ == result.match;
+ return MatchKindBS::EQ == result.match();
});
}
);
// TODO: improve lower_bound()
return root->lower_bound(get_context(t), key);
}).safe_then([this](auto result) {
- if (result.match == MatchKindBS::EQ) {
+ if (result.match() == MatchKindBS::EQ) {
return Cursor(this, result.p_cursor);
} else {
return Cursor::make_end(this);