From 2e0d051a787fa04f7e59ea14798a458533b059cf Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Thu, 27 Jul 2023 12:34:03 +0200 Subject: [PATCH] Maintain cursor stack's position correctly when ascending the tree This fixes a bug that could cause the cursor to incorrectly report its start when using `slice` or `seek_forward`, and then calling `prev`. We didn't notice this because we were not testing those three methods together. I suppose this could explain some of the panics we've observed because we do use `slice`/`seek_forward` followed by `prev` calls in production. --- crates/sum_tree/src/cursor.rs | 1 + crates/sum_tree/src/sum_tree.rs | 8 +++++--- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/crates/sum_tree/src/cursor.rs b/crates/sum_tree/src/cursor.rs index 59165283f6..efd6ac145e 100644 --- a/crates/sum_tree/src/cursor.rs +++ b/crates/sum_tree/src/cursor.rs @@ -438,6 +438,7 @@ where } => { if ascending { entry.index += 1; + entry.position = self.position.clone(); } for (child_tree, child_summary) in child_trees[entry.index..] diff --git a/crates/sum_tree/src/sum_tree.rs b/crates/sum_tree/src/sum_tree.rs index 8d219ca021..24a443051a 100644 --- a/crates/sum_tree/src/sum_tree.rs +++ b/crates/sum_tree/src/sum_tree.rs @@ -738,7 +738,7 @@ mod tests { for _ in 0..num_operations { let splice_end = rng.gen_range(0..tree.extent::(&()).0 + 1); let splice_start = rng.gen_range(0..splice_end + 1); - let count = rng.gen_range(0..3); + let count = rng.gen_range(0..10); let tree_end = tree.extent::(&()); let new_items = rng .sample_iter(distributions::Standard) @@ -805,10 +805,12 @@ mod tests { } assert_eq!(filter_cursor.item(), None); - let mut pos = rng.gen_range(0..tree.extent::(&()).0 + 1); let mut before_start = false; let mut cursor = tree.cursor::(); - cursor.seek(&Count(pos), Bias::Right, &()); + let start_pos = rng.gen_range(0..=reference_items.len()); + cursor.seek(&Count(start_pos), Bias::Right, &()); + let mut pos = rng.gen_range(start_pos..=reference_items.len()); + cursor.seek_forward(&Count(pos), Bias::Right, &()); for i in 0..10 { assert_eq!(cursor.start().0, pos);