Skip to content

Conversation

@cffls
Copy link
Contributor

@cffls cffls commented Jan 6, 2026

When merging a branch node with its only remaining child on a different page, the child node was read and cached early in merge_branch_with_only_child. If the child's page had < 200 free bytes, split_page was called which moved some grandchildren to new pages and updated the child node's pointers at index 0. However, the stale cached node was then written back, overwriting split_page's pointer updates.

Fix: Defer reading the child node until after split_page completes. The helper functions now receive only the prefix to prepend, and read the child node fresh before modifying and writing it back. This ensures any pointer updates from split_page are preserved.

@cb-heimdall
Copy link
Collaborator

cb-heimdall commented Jan 6, 2026

✅ Heimdall Review Status

Requirement Status More Info
Reviews 1/1
Denominator calculation
Show calculation
1 if user is bot 0
1 if user is external 0
2 if repo is sensitive 0
From .codeflow.yml 1
Additional review requirements
Show calculation
Max 0
0
From CODEOWNERS 0
Global minimum 0
Max 1
1
1 if commit is unverified 0
Sum 1

Copy link
Collaborator

@BrianBland BrianBland left a comment

Choose a reason for hiding this comment

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

Thanks, just had a minor request for more consistent argument naming to improve readability.

fn merge_with_child_on_same_page(
&self,
slotted_page: &mut SlottedPageMut<'_>,
page_index: u8,
Copy link
Collaborator

Choose a reason for hiding this comment

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

Recommend renaming this to parent_cell_index for consistency with the new child_cell_index

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done.

Comment on lines 1121 to 1130
// Delete both nodes and insert the merged one
slotted_page.delete_value(child_cell_index)?;
slotted_page.delete_value(page_index)?;

let only_child_node_index = slotted_page.insert_value(&only_child_node)?;
let new_cell_index = slotted_page.insert_value(&child_node)?;

// If we are the root of the page, we must insert at index 0
if page_index == 0 {
assert_eq!(only_child_node_index, page_index);
assert_eq!(new_cell_index, page_index);
}
Copy link
Collaborator

Choose a reason for hiding this comment

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

This is more a comment about the existing implementation, and not a critique of this changeset:

Ideally we should not be assuming and asserting the implementation details of the slotted page, specifically on insertion. It would be preferable to delete the child and then replace the parent's slot with the new node. For example:

slotted_page.delete_value(child_cell_index)?;
slotted_page.set_value(page_index, &child_node)?;

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It seems like this is addressed in this PR: https://github.com/base/triedb/pull/183/changes . To avoid conflicts, I guess it is better to leave this one as it is.

@cffls
Copy link
Contributor Author

cffls commented Jan 12, 2026

Thanks @BrianBland for the feedbacks.

@BrianBland
Copy link
Collaborator

@cffls Could you rebase your change to resolve merge conflicts with #183?

cffls added 2 commits January 13, 2026 14:45
When merging a branch node with its only remaining child on a different page, the child node was read and cached early in `merge_branch_with_only_child`. If the child's page had < 200 free bytes, `split_page` was called which moved some grandchildren to new pages and updated the child node's pointers at index 0. However, the stale cached node was then written back, overwriting `split_page`'s pointer updates.

Fix: Defer reading the child node until after `split_page` completes. The helper functions now receive only the prefix to prepend, and read the child node fresh before modifying and writing it back. This ensures any pointer updates from `split_page` are preserved.
@cffls
Copy link
Contributor Author

cffls commented Jan 13, 2026

@BrianBland rebased and resolved the conflicts.

@BrianBland BrianBland self-requested a review January 13, 2026 23:01
Copy link
Collaborator

@BrianBland BrianBland left a comment

Choose a reason for hiding this comment

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

It looks like this PR is currently failing some linter checks. Could you please address these issues?

@BrianBland BrianBland merged commit 86a74c2 into base:main Jan 14, 2026
17 checks passed
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.

3 participants