Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 39 additions & 3 deletions crates/state/src/bal/writes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,11 +40,15 @@ impl<T: PartialEq + Clone> BalWrites<T> {
return self.get_linear_search(bal_index);
}
// else do binary search.
let index = self
let i = match self
.writes
.binary_search_by_key(&bal_index, |(index, _)| *index)
.ok()?;
Some(self.writes[index].1.clone())
{
Ok(i) => i,
Err(i) => i,
};
// only if i is not zero, we return the previous value.
(i != 0).then(|| self.writes[i - 1].1.clone())
}

/// Extend the builder with another builder.
Expand Down Expand Up @@ -145,4 +149,36 @@ mod tests {
assert_eq!(bal_writes.get(3), Some(3));
assert_eq!(bal_writes.get(4), Some(3));
}

fn get_binary_search(threshold: BalIndex) {
// Construct test data up to (threshold - 1), skipping one key to simulate a gap.
let entries: Vec<_> = (0..threshold - 1)
.map(|i| (i, i + 1))
.chain(std::iter::once((threshold, threshold + 1)))
.collect();

let bal_writes = BalWrites::new(entries);

// Case 1: lookup before any entries
assert_eq!(bal_writes.get(0), None);

// Case 2: lookups for existing keys before the gap
for i in 1..threshold - 1 {
assert_eq!(bal_writes.get(i), Some(i));
}

// Case 3: lookup at the skipped key — should return the previous value
assert_eq!(bal_writes.get(threshold), Some(threshold - 1));

// Case 4: lookup after the skipped key — should return the next valid value
assert_eq!(bal_writes.get(threshold + 1), Some(threshold + 1));
}

#[test]
fn test_get_binary_search() {
get_binary_search(4);
get_binary_search(5);
get_binary_search(6);
get_binary_search(7);
}
}