mirror of
https://github.com/aljazceru/turso.git
synced 2025-12-26 20:44:23 +01:00
Closes #1714 This PR enables the use of an index as the iteration cursor for a point or range deletion operation. Main changes: - Use `Delete` opcode for the index that is iterating the rows - avoids unnecessary seeking on that index, since it's already positioned correctly - Fix delete balancing; details below: ### current state - a deletion may cause a btree rebalancing operation - to get the cursor back to the right place after a rebalancing, we must remember what the deleted key was and seek to it - right now we are using `SeekOp::LT` to move to one slot BEFORE the deleted key, so that if we delete rows in a loop, the following `Next()` call will put us back into the right place ### problem - When we delete multiple rows, we always iterate forwards. Using `SeekOp::LT` implies backwards iteration, but it works OK for table btrees since the cursor never remains on an internal node, because table internal cells do not have payloads. However: this behavior is problematic for indexes because we can effectively end up skipping visiting a page entirely. Honestly: despite spending some debugging the _old_ code, I still don't remember what exactly causes this to happen. :) It's one of the `iter_dir` specific behaviors in `indexbtree_move_to` or `get_prev_record()`, but I'm too tired to spend more time figuring it out. I had the reason in my head before going on vacation, but it was evicted from the cache it seems... ### solution use `SeekOp::GE { eq_only: true }` instead and make the next call to `Next()` a no-op instead. This has the same effect as SeekOp::LT + next(), but without introducing bugs due to `LT` being implied backwards iteration. Reviewed-by: Nikita Sivukhin (@sivukhin) Closes #2981