Repository navigation
Snapshot Deletions #38
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from 6 commits
a37ab3e
daaaa13
1999497
05862dd
4c67f21
247230d
d2ad742
dcff272
4f83530
e575e7a
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -205,37 +205,42 @@ StatusOr<std::unique_ptr<CheckpointJob>> CheckpointGenerator::finalize_checkpoin | |
| checkpoint_job->edit_offset_upper_bound = edit_offset_upper_bound; | ||
| checkpoint_job->batch_count = batch_count; | ||
|
|
||
| this->active_checkpoints_.push_back(PackedCheckpoint{ | ||
| .edit_offset_upper_bound = this->base_checkpoint_.edit_offset_upper_bound().value(), | ||
| .new_tree_root = llfs::PackedPageId::from(this->base_checkpoint_.root_id()), | ||
| }); | ||
| { | ||
| std::lock_guard<std::mutex> lock{this->checkpoint_mutex_}; | ||
|
|
||
| checkpoint_job->active_checkpoints.emplace( | ||
| llfs::PackAsVariant<CheckpointLogEvent, PackedActiveCheckpoints>{ | ||
| this->active_checkpoints_, | ||
| }); | ||
| this->active_checkpoints_.push_back(PackedCheckpoint{ | ||
| .edit_offset_upper_bound = this->base_checkpoint_.edit_offset_upper_bound().value(), | ||
| .new_tree_root = llfs::PackedPageId::from(this->base_checkpoint_.root_id()), | ||
| }); | ||
|
|
||
| // Package the job up with a PackedActiveCheckpoints event record so we can append it to the Volume. | ||
| // | ||
| StatusOr<llfs::AppendableJob> appendable_job = | ||
| llfs::make_appendable_job(std::move(this->job_), | ||
| llfs::PackableRef{*checkpoint_job->active_checkpoints}); | ||
| checkpoint_job->active_checkpoints.emplace( | ||
| llfs::PackAsVariant<CheckpointLogEvent, PackedActiveCheckpoints>{ | ||
| this->active_checkpoints_, | ||
| }); | ||
|
|
||
| BATT_REQUIRE_OK(appendable_job); | ||
| // Package the job up with a PackedActiveCheckpoints event record so we can append it to the | ||
| // Volume. | ||
| // | ||
| StatusOr<llfs::AppendableJob> appendable_job = | ||
| llfs::make_appendable_job(std::move(this->job_), | ||
| llfs::PackableRef{*checkpoint_job->active_checkpoints}); | ||
|
|
||
| // Reserve slot grant for the current checkpoint in checkpoint-log. | ||
| // | ||
| auto grant_size = appendable_job->calculate_grant_size(); | ||
| StatusOr<batt::Grant> checkpoint_grant = this->reserve_slot_grant_for_checkpoints(grant_size); | ||
| BATT_REQUIRE_OK(appendable_job); | ||
|
|
||
| BATT_REQUIRE_OK(checkpoint_grant); | ||
| // Reserve slot grant for the current checkpoint in checkpoint-log. | ||
| // | ||
| auto grant_size = appendable_job->calculate_grant_size(); | ||
| StatusOr<batt::Grant> checkpoint_grant = this->reserve_slot_grant_for_checkpoints(grant_size); | ||
|
|
||
| checkpoint_job->append_job_grant.emplace(std::move(*checkpoint_grant)); | ||
| checkpoint_job->appendable_job.emplace(std::move(*appendable_job)); | ||
| checkpoint_job->prepare_slot_sequencer.emplace(this->slot_sequencer_); | ||
| BATT_REQUIRE_OK(checkpoint_grant); | ||
|
|
||
| this->base_job_ = checkpoint_job->appendable_job->job.finalized_job(); | ||
| this->slot_sequencer_ = this->slot_sequencer_.get_next(); | ||
| checkpoint_job->append_job_grant.emplace(std::move(*checkpoint_grant)); | ||
| checkpoint_job->appendable_job.emplace(std::move(*appendable_job)); | ||
| checkpoint_job->prepare_slot_sequencer.emplace(this->slot_sequencer_); | ||
|
|
||
| this->base_job_ = checkpoint_job->appendable_job->job.finalized_job(); | ||
| this->slot_sequencer_ = this->slot_sequencer_.get_next(); | ||
| } | ||
|
|
||
| BATT_CHECK_EQ(this->job_, nullptr); | ||
|
|
||
|
|
@@ -244,4 +249,29 @@ StatusOr<std::unique_ptr<CheckpointJob>> CheckpointGenerator::finalize_checkpoin | |
| return {std::move(checkpoint_job)}; | ||
| } | ||
|
|
||
| //==#==========+==+=+=++=+++++++++++-+-+--+----- --- -- - - - - | ||
| // | ||
| Status CheckpointGenerator::delete_checkpoint( | ||
| EditOffset edit_offset, | ||
| PackedActiveCheckpoints& active_checkpoints_out) noexcept | ||
| { | ||
| std::lock_guard<std::mutex> lock{this->checkpoint_mutex_}; | ||
|
|
||
| if (this->active_checkpoints_.num_active_checkpoints == 0) { | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Re: your comment in |
||
| return {batt::StatusCode::kNotFound}; | ||
| } | ||
|
|
||
| if (edit_offset.value() == this->active_checkpoints_.newest().edit_offset_upper_bound) { | ||
| return {batt::StatusCode::kFailedPrecondition}; | ||
| } | ||
|
|
||
| if (!this->active_checkpoints_.erase(edit_offset.value())) { | ||
| return {batt::StatusCode::kNotFound}; | ||
| } | ||
|
|
||
| active_checkpoints_out = this->active_checkpoints_; | ||
|
|
||
| return OkStatus(); | ||
| } | ||
|
|
||
| } // namespace turtle_kv | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -1055,6 +1055,20 @@ StatusOr<Snapshot> KVStore::get_snapshot(EditOffset checkpoint_edit_offset) noex | |
| }; | ||
| } | ||
|
|
||
| //==#==========+==+=+=++=+++++++++++-+-+--+----- --- -- - - - - | ||
| // | ||
| StatusOr<Snapshot> KVStore::create_snapshot() noexcept | ||
| { | ||
| BATT_ASSIGN_OK_RESULT(EditOffset checkpoint_edit_offset, this->force_checkpoint()); | ||
|
|
||
| // force_checkpoint only finalizes the active MemTable; the checkpoint itself is committed | ||
| // asynchronously, so wait for it to become active before looking it up. | ||
| // | ||
| BATT_REQUIRE_OK(this->wait_for_checkpoint(checkpoint_edit_offset)); | ||
|
gabrielbornstein marked this conversation as resolved.
Resolved
|
||
|
|
||
| return this->get_snapshot(checkpoint_edit_offset); | ||
| } | ||
|
|
||
| //==#==========+==+=+=++=+++++++++++-+-+--+----- --- -- - - - - | ||
| // | ||
| StatusOr<std::vector<Snapshot>> KVStore::get_active_snapshots() noexcept | ||
|
|
@@ -1092,6 +1106,32 @@ StatusOr<std::vector<Snapshot>> KVStore::get_active_snapshots() noexcept | |
| return snapshots; | ||
| } | ||
|
|
||
| //==#==========+==+=+=++=+++++++++++-+-+--+----- --- -- - - - - | ||
| // | ||
| Status KVStore::delete_snapshot(EditOffset checkpoint_edit_offset) noexcept | ||
| { | ||
| // TODO: [Gabe Bornstein 10/12/26] commit_checkpoint does this. Do we need delete_snapshot to do | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think we could replace this with |
||
| // it too? | ||
| // | ||
| BATT_REQUIRE_OK(this->wait_for_recovery()); | ||
|
|
||
| PackedActiveCheckpoints updated_active_checkpoints; | ||
| BATT_REQUIRE_OK(this->checkpoint_generator_->delete_checkpoint(checkpoint_edit_offset, | ||
| updated_active_checkpoints)); | ||
| { | ||
| batt::Toggle<State>::Writer state_writer{this->state_}; | ||
| const State& old_state = state_writer.old_value(); | ||
| State& new_state = state_writer.new_value(); | ||
|
|
||
| new_state.mem_table_ = old_state.mem_table_; | ||
| new_state.deltas_ = old_state.deltas_; | ||
| new_state.base_checkpoint_ = old_state.base_checkpoint_; | ||
| new_state.active_checkpoints_ = updated_active_checkpoints; | ||
| } | ||
|
|
||
| return OkStatus(); | ||
| } | ||
|
|
||
| //==#==========+==+=+=++=+++++++++++-+-+--+----- --- -- - - - - | ||
| // | ||
| StatusOr<usize> KVStore::scan( | ||
|
|
@@ -1484,9 +1524,9 @@ void KVStore::mem_table_batch_scanner_thread_main() | |
| //==#==========+==+=+=++=+++++++++++-+-+--+----- --- -- - - - - | ||
| // | ||
| template <typename Fn> | ||
| requires std::invocable<Fn, std::unique_ptr<DeltaBatch>> Status | ||
| KVStore::scan_mem_table_to_build_batches(boost::intrusive_ptr<MemTable>&& mem_table, | ||
| Fn&& consume_fn) | ||
| requires std::invocable<Fn, std::unique_ptr<DeltaBatch>> | ||
| Status KVStore::scan_mem_table_to_build_batches(boost::intrusive_ptr<MemTable>&& mem_table, | ||
| Fn&& consume_fn) | ||
| { | ||
| MemTable::BatchCompactor batch_compactor{*mem_table, | ||
| /*byte_size_limit=*/this->tree_options_.flush_size()}; | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.