Skip to content

fsync Implementation#23

Open
vidyasilai wants to merge 15 commits into
mathworks:mainfrom
vidyasilai:fsync_impl
Open

fsync Implementation#23
vidyasilai wants to merge 15 commits into
mathworks:mainfrom
vidyasilai:fsync_impl

Conversation

@vidyasilai

@vidyasilai vidyasilai commented May 26, 2026

Copy link
Copy Markdown
Collaborator

This PR adds an fsync like blocking call functionality for clients to ensure updates are durable in the write ahead log.

@vidyasilai vidyasilai requested a review from tonyastolfi May 26, 2026 15:02
Comment thread src/turtle_kv/kv_store.cpp
Comment thread src/turtle_kv/kv_store.cpp Outdated

//==#==========+==+=+=++=+++++++++++-+-+--+----- --- -- - - - -
//
Status KVStore::sync(Optional<i64> upper_bound) noexcept

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Optional<i64> -> Optional<EditOffset>?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

Comment thread src/turtle_kv/mem_table/mem_table.ipp Outdated
EditOffsetDelta{(i64)packed_key_value_slot_size(key, value)};
}

return OkStatus();

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unreachable code?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed

Comment thread src/turtle_kv/mem_table/mem_table.ipp Outdated
BATT_REQUIRE_OK(this->art_index_.insert(key, inserter));
BATT_CHECK_NOT_NULLPTR(inserter.entry_out);

return inserter.entry_out->edit_offset() +

@tonyastolfi tonyastolfi May 26, 2026

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Data race: we should add a data member edit_offset_out(either edit_offset_upper_bound_out or Interval<EditOffset> edit_range_out) to MemTableValueEntryInserter

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done, added edit_range_out.

}
}();

this->sync_upper_bound_.close();

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use batt::finally

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As per our conversation earlier, I added this to ChangeLogWriter::halt.

// Insert this block's slots into the sync upper bound hash map.
//
for (usize i = 0; i < next_block->slot_count(); ++i) {
const i64 slot_start = next_block->slot_edit_offset(i).value();

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can use ChangeLogBlock::edit_offset_range() here

@vidyasilai vidyasilai self-assigned this May 26, 2026
@vidyasilai vidyasilai marked this pull request as ready for review May 29, 2026 20:40
*
* \return The new edit_offset_start value after walking.
*/
template <typename SlotFn>

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's use concepts/type requirements here to specify the signature of the Fn.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done (see src/turtle_kv/change_log/change_log_blocks_visitor.hpp).

* \return The new edit_offset_start value after walking.
*/
template <typename SlotFn>
i64 walk_change_log_blocks(i64 edit_offset_start,

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i64 -> EditOffset

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

pending_blocks.erase(it);

do {
slot_fn(block_iter.block.get(), block_iter.next_slot_i, EditOffset{edit_offset_start});

@tonyastolfi tonyastolfi Jun 2, 2026

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The slot fn should probably have a 'this-is-the-first-visit' arg. Also good to have it optionally return Status; there are break-loop and continue-loop enum values we can use here: https://gitlab.com/batteriescpp/batteries/-/blob/main/src/batteries/seq/loop_control.hpp?ref_type=heads#L123 (BATT_INVOKE_LOOP_FN)

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

do {
slot_fn(block_iter.block.get(), block_iter.next_slot_i, EditOffset{edit_offset_start});

edit_offset_start += (i64)(block_iter.block->slot_size(block_iter.next_slot_i) -

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be great to add a function like ChangeLogBlock::next_edit_offset_of_slot(usize slot_index) that hides this implementation detail.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

//
if ((force_sleep || prepared.empty()) && this->halt_requested_.load() == false) {
if ((force_sleep || prepared.empty()) && this->halt_requested_.load() == false &&
this->sync_upper_bound_.get_value() >= this->next_edit_offset_.load()) {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This expression would make a great public member function on ChangeLogWriter: i64 unflushed_byte_count()/bool has_unflushed_bytes() or similar.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

//
if ((force_sleep || prepared.empty()) && this->halt_requested_.load() == false) {
if ((force_sleep || prepared.empty()) && this->halt_requested_.load() == false &&
this->sync_upper_bound_.get_value() >= this->next_edit_offset_.load()) {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We probably don't want to prevent sleeping any time there is unflushed data; only when in "urgent" mode.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants