* estimate_insert(key, value) -> node_offset_t
*/
using iterator_t = _iterator_t<CONTAINER_TYPE>;
+ /* TODO: detailed comments
+ * - trim_until(mut) -> trim_size
+ * * keep 0 to i - 1, and remove the rest, return the size trimmed.
+ * * if this is the end iterator, do nothing and return 0.
+ * * if this is the start iterator, normally needs to go to the higher
+ * stage to trim the entire container.
+ * - trim_at(mut, trimmed) -> trim_size
+ * * trim happens inside the current iterator, causing the size reduced by
+ * <trimmed>, return the total size trimmed.
+ */
/*
* Lookup internals (hide?)
position_t& position, match_stage_t& stage, node_offset_t& _insert_size) {
auto p_left_bound = container.p_left_bound();
if (unlikely(!container.keys())) {
- assert(position == position_t::end());
- assert(stage == STAGE);
- position = position_t::begin();
+ if (position == position_t::end()) {
+ position = position_t::begin();
+ assert(stage == STAGE);
+ } else if (position == position_t::begin()) {
+ // when insert into a trimmed and empty left node
+ stage = STAGE;
+ _insert_size = insert_size<KT>(key, value);
+ } else {
+ assert(false && "impossible path");
+ }
if constexpr (IS_BOTTOM) {
return container_t::template insert_at<KT>(
mut, container, key, value, 0, _insert_size, p_left_bound);
}
}
+ /* TrimType:
+ * BEFORE: remove the entire container, normally means the according higher
+ * stage iterator needs to be trimmed as-a-whole.
+ * AFTER: retain the entire container, normally means the trim should be
+ * start from the next iterator at the higher stage.
+ * AT: trim happens in the current container, and the according higher
+ * stage iterator needs to be adjusted by the trimmed size.
+ */
static std::tuple<TrimType, size_t>
recursively_trim(NodeExtentMutable& mut, StagedIterator& trim_at) {
if (!trim_at.valid()) {
static void trim(NodeExtentMutable& mut, StagedIterator& trim_at) {
auto [type, trimmed] = recursively_trim(mut, trim_at);
- if (type == TrimType::AFTER) {
+ if (type == TrimType::BEFORE) {
+ assert(trim_at.valid());
auto& iter = trim_at.get();
- assert(iter.is_end());
iter.trim_until(mut);
}
}
test.split(make_ghobj(3, 3, 3, "ns2", "oid2", 3, 4), onode4).get0();
}
- // TODO: test split at {0, 0, 0}
- // TODO: test split at {END, END, END}
+ {
+ TestTree test;
+ test.build_tree({2, 4}, {2, 4}, {2, 4}, 232).get0();
+ auto& onode = test.create_onode(1996);
+ logger().info("\n---------------------------------------------"
+ "\nsplit at [0, 0, 0]; insert to left front at stage 2, 1, 0\n");
+ test.split(make_ghobj(1, 1, 1, "ns3", "oid3", 3, 3), onode).get0();
+ test.split(make_ghobj(2, 2, 2, "ns1", "oid1", 3, 3), onode).get0();
+ test.split(make_ghobj(2, 2, 2, "ns2", "oid2", 1, 1), onode).get0();
+ }
+ // Impossible to split at [END, END, END]
});
}
}
// TODO: test split at {0, 0, 0}
- // TODO: test split at {END, END, END}
+ // Impossible to split at [END, END, END]
});
}