Skip to content

fix(b+tree): lower_bound past the last key returns end(), and end() is a valid insert hint - #154

Merged
psiha merged 1 commit into
masterfrom
bt/2-lower-bound
Sep 9, 2026
Merged

fix(b+tree): lower_bound past the last key returns end(), and end() is a valid insert hint#154
psiha merged 1 commit into
masterfrom
bt/2-lower-bound

Conversation

@psiha

@psiha psiha commented Sep 9, 2026

Copy link
Copy Markdown
Owner

lower_bound expressed "one past the end of a leaf" as the first value of the following leaf. Past the last leaf there is no following leaf, so it built an iterator from a null node slot — while end() is the last leaf at its num_vals offset.

On a non-empty tree, for a key greater than every key present:

tree.lower_bound( k ) == tree.end()        // was false — they compared unequal
tree.insert( tree.lower_bound( k ), k )    // access-violated

So the ordinary sorted-container maintenance idiom failed for every append.

end() is now accepted as the append hint. It already worked structurally — it is the last leaf at its num_vals offset, which insert() appends to; only the debug hint assertions dereferenced the hint unconditionally. The returned iterator now goes through make_iter( insert_pos_t ), which steps back from the next-insert position and so stays correct across a split that moved the value into the new node.

Witness: TEST( bp_tree, hinted_insert_boundaries ).

Stacked on #153.

@psiha
psiha force-pushed the bt/2-lower-bound branch 2 times, most recently from 89b0981 to ecbe4dc Compare September 9, 2026 10:56
Base automatically changed from bt/1-split to master September 9, 2026 11:57
…s a valid insert hint

lower_bound expressed 'one past the end of a leaf' as the first value of the
FOLLOWING leaf.  Past the LAST leaf there is no following leaf, so it built an
iterator from a null node slot - while end() is the last leaf at its num_vals
offset.  On a non-empty tree, for a key greater than every key present:

  tree.lower_bound( k ) == tree.end()   was false, and
  tree.insert( tree.lower_bound( k ), k )   access-violated.

So the ordinary sorted-container idiom failed for every append.

end() is accepted as the append hint: it already works structurally - it is
the last leaf at its num_vals offset, which insert() appends to - only the
debug hint assertions dereferenced the hint unconditionally.  The returned
iterator now goes through make_iter( insert_pos_t ), which steps back from the
next-insert position and so stays correct across a split that moved the value
into the new node.
@psiha
psiha merged commit 5db7795 into master Sep 9, 2026
10 checks passed
@psiha
psiha deleted the bt/2-lower-bound branch September 9, 2026 13:06
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.

1 participant