Skip to content

Commit

Permalink
feat(trie): forward-only in-memory cursor (#9079)
Browse files Browse the repository at this point in the history
  • Loading branch information
rkrasiuk authored Jun 27, 2024
1 parent 18eef6a commit 7a82f4e
Show file tree
Hide file tree
Showing 3 changed files with 223 additions and 212 deletions.
51 changes: 51 additions & 0 deletions crates/trie/trie/src/forward_cursor.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
/// The implementation of forward-only in memory cursor over the entries.
/// The cursor operates under the assumption that the supplied collection is pre-sorted.
#[derive(Debug)]
pub struct ForwardInMemoryCursor<'a, K, V> {
/// The reference to the pre-sorted collection of entries.
entries: &'a Vec<(K, V)>,
/// The index where cursor is currently positioned.
index: usize,
}

impl<'a, K, V> ForwardInMemoryCursor<'a, K, V> {
/// Create new forward cursor positioned at the beginning of the collection.
/// The cursor expects all of the entries have been sorted in advance.
pub const fn new(entries: &'a Vec<(K, V)>) -> Self {
Self { entries, index: 0 }
}

/// Returns `true` if the cursor is empty, regardless of its position.
pub fn is_empty(&self) -> bool {
self.entries.is_empty()
}
}

impl<'a, K, V> ForwardInMemoryCursor<'a, K, V>
where
K: PartialOrd + Copy,
V: Copy,
{
/// Advances the cursor forward while `comparator` returns `true` or until the collection is
/// exhausted. Returns the first entry for which `comparator` returns `false` or `None`.
fn advance_while_false(&mut self, comparator: impl Fn(&K) -> bool) -> Option<(K, V)> {
let mut entry = self.entries.get(self.index);
while entry.map_or(false, |entry| comparator(&entry.0)) {
self.index += 1;
entry = self.entries.get(self.index);
}
entry.copied()
}

/// Returns the first entry from the current cursor position that's greater or equal to the
/// provided key. This method advances the cursor forward.
pub fn seek(&mut self, key: &K) -> Option<(K, V)> {
self.advance_while_false(|k| k < key)
}

/// Returns the first entry from the current cursor position that's greater than the provided
/// key. This method advances the cursor forward.
pub fn first_after(&mut self, key: &K) -> Option<(K, V)> {
self.advance_while_false(|k| k <= key)
}
}
Loading

0 comments on commit 7a82f4e

Please sign in to comment.