mirror of
https://github.com/aljazceru/turso.git
synced 2025-12-18 00:54:19 +01:00
Closes #2241 ## What When an index interior cell is deleted, it steals the leaf cell with the largest key in its left subtree, deletes the old interior cell and then replaces it with the stolen cell. This ensures the binary-search-tree aspect of the btree remains correct. However, this can cause a situation where both are true: 1. The leaf page is now UNDERFULL and must be rebalanced 2. The leaf's IMMEDIATE parent page is now OVERFULL and must be rebalanced ## Why is this a problem We simply didn't support the case where: - Leaf page P is unbalanced and rebalancing starts on it - Its immediate parent is ALSO unbalanced and _overflows_. We had an assertion against this happening (see #2241) ## The fix Allow exactly 1 overflow cell in the parent under very particular conditions: 1. The parent page must be an index interior page 2. The parent must be positioned exactly at the divider cell whose left child page underflows This is the _only_ case where the immediate parent of a page about to undergo rebalancing can have overflow cells. ## Implementation details The parent overflow cell is folded into `cell_array` fairly early on and `parent.overflow_cells` is cleared. However we need to be careful with `cell_idx` for dividers other than the overflow cell because they get shifted left on the page in `drop_cell()`. I've added a long comment about this. ## Testing Adds fuzz test that does inserts and deletes on an index btree and asserts that all the expected keys are found at the end in the right order. This test runs into this case quite frequently so I was able to verify it. Reviewed-by: Pere Diaz Bou <pere-altea@homail.com> Closes #2243