KVStore::remove Implementation Part 2#4
Conversation
|
|
||
| // If the root is a leaf and there are no items in the leaf, set the root to be an empty subtree. | ||
| // | ||
| if (batt::is_case<std::unique_ptr<InMemoryLeaf>>(this->impl_)) { |
There was a problem hiding this comment.
Looks right, but maybe it should be in try_shrink instead..?
| // | ||
| Status Subtree::try_merge(BatchUpdateContext& context, Subtree&& sibling) noexcept | ||
| { | ||
| BATT_CHECK(!this->locked_.load()); |
There was a problem hiding this comment.
Maybe assert/check that this height and sibling height are equal?
| // | ||
| i32 sibling_i = pivot_i; | ||
|
|
||
| if (pivot_i == 0) { |
There was a problem hiding this comment.
Should just be 2 cases.
src/turtle_kv/tree/subtree.cpp
Outdated
| [&](auto& in_memory) -> Status { | ||
| using PtrT = std::decay_t<decltype(in_memory)>; | ||
|
|
||
| BATT_CHECK(batt::is_case<PtrT>(sibling.impl_)); |
There was a problem hiding this comment.
Would be good to add a message that interprets what this panic means.
src/turtle_kv/tree/subtree.cpp
Outdated
|
|
||
| BATT_CHECK(batt::is_case<PtrT>(sibling.impl_)); | ||
| auto& sibling_ptr = std::get<PtrT>(sibling.impl_); | ||
| BATT_CHECK(sibling_ptr); |
There was a problem hiding this comment.
nit: BATT_CHECK_NOT_NULLPTR
| update_context.page_loader, | ||
| update_context.overcommit) | ||
| .merge_pivots(left_pivot_i, right_pivot_i); | ||
| } |
There was a problem hiding this comment.
Maybe comment why we don't care about the other cases?
Should probably be a batt::case_of
| this->pending_bytes[left_pivot_i] += this->pending_bytes[right_pivot_i]; | ||
| this->pending_bytes.erase(this->pending_bytes.begin() + right_pivot_i); | ||
|
|
||
| bool is_pending_bytes_exact = get_bit(this->pending_bytes_is_exact, left_pivot_i) & |
| BATT_CHECK(sibling->result_set); | ||
|
|
||
| if (sibling->result_set->empty()) { | ||
| BATT_CHECK(batt::is_case<Viable>(this->get_viability())); |
There was a problem hiding this comment.
Message would be helpful here.
| this->edit_size_totals = std::move(sibling->edit_size_totals); | ||
| return OkStatus(); | ||
| } | ||
|
|
There was a problem hiding this comment.
We should probably retain a pin on the sibling's leaf page in this; that means we may need to change InMemoryLeaf::pinned_leaf_page_ into pinned_leaf_pages_.
There was a problem hiding this comment.
In regard to turning pinned_leaf_page_ into a vector of pinned pages, what are your thoughts on keeping pinned_leaf_page_ as is and adding another member variable to InMemoryLeaf that is of type std::vector<PinnedPage> that holds pins on sibling pages as a result of merges? My reason for suggesting this is due to the logic in InMemoryLeaf::apply_batch_update, where we check the state of pinned_leaf_page_ to determine how to extract result_set.
| if (flush_status == batt::StatusCode::kUnavailable) { | ||
| BATT_REQUIRE_OK(this->try_shrink()); | ||
| } | ||
|
|
There was a problem hiding this comment.
After a successful flush, we should do something here to see if the root object has changed; if it has, then we should reset the retries counter, since limiting to kMaxPivots is based on the assumption of a single node.
| return false; | ||
| }, | ||
| [](const NeedsMerge& needs_merge) { | ||
| return !needs_merge.single_pivot; |
There was a problem hiding this comment.
&& !needs_merge.no_items
| @@ -441,6 +441,9 @@ inline usize PackedLeafLayoutPlan::compute_trie_step_size() const | |||
| step_size = 1; | |||
| } else if (this->key_count < 256) { | |||
| step_size = this->key_count / 16; | |||
There was a problem hiding this comment.
Consider rounding up instead..?
|
|
||
| /** \brief Removes the specified number (`count`) pivots from the end of the bit set. | ||
| */ | ||
| BATT_ALWAYS_INLINE void pop_back_pivots(i32 count) |
There was a problem hiding this comment.
maybe push_front_pivots?
|
|
||
| // Erase potential duplicate segments that have resulted from a previous split. | ||
| // | ||
| this->segments.erase(std::unique(this->segments.begin(), |
There was a problem hiding this comment.
We do need to do this de-duplication step, but we need to calculate:
- union of the active pivots set
- "joining" of the portions of the piecewise-filter that correspond to each sibling's "side."
| { | ||
| bool left_is_active = this->segment_.is_pivot_active(left_pivot); | ||
| bool right_is_active = this->segment_.is_pivot_active(right_pivot); | ||
| this->segment_.set_pivot_active(left_pivot, left_is_active | right_is_active); |
This PR contains the tree algorithm code related to deletions:
InMemoryNodeupdate buffer level typeHybridLevel