reth_trie/
forward_cursor.rs
1#[derive(Debug)]
5pub struct ForwardInMemoryCursor<'a, K, V> {
6 entries: std::slice::Iter<'a, (K, V)>,
8 is_empty: bool,
9}
10
11impl<'a, K, V> ForwardInMemoryCursor<'a, K, V> {
12 #[inline]
16 pub fn new(entries: &'a [(K, V)]) -> Self {
17 Self { entries: entries.iter(), is_empty: entries.is_empty() }
18 }
19
20 #[inline]
22 pub fn is_empty(&self) -> bool {
23 self.is_empty
24 }
25
26 #[inline]
27 fn peek(&self) -> Option<&(K, V)> {
28 self.entries.clone().next()
29 }
30
31 #[inline]
32 fn next(&mut self) -> Option<&(K, V)> {
33 self.entries.next()
34 }
35}
36
37impl<K, V> ForwardInMemoryCursor<'_, K, V>
38where
39 K: PartialOrd + Clone,
40 V: Clone,
41{
42 pub fn seek(&mut self, key: &K) -> Option<(K, V)> {
45 self.advance_while(|k| k < key)
46 }
47
48 pub fn first_after(&mut self, key: &K) -> Option<(K, V)> {
51 self.advance_while(|k| k <= key)
52 }
53
54 fn advance_while(&mut self, predicate: impl Fn(&K) -> bool) -> Option<(K, V)> {
60 let mut entry;
61 loop {
62 entry = self.peek();
63 if entry.is_some_and(|(k, _)| predicate(k)) {
64 self.next();
65 } else {
66 break;
67 }
68 }
69 entry.cloned()
70 }
71}
72
73#[cfg(test)]
74mod tests {
75 use super::*;
76
77 #[test]
78 fn test_cursor() {
79 let mut cursor = ForwardInMemoryCursor::new(&[(1, ()), (2, ()), (3, ()), (4, ()), (5, ())]);
80
81 assert_eq!(cursor.seek(&0), Some((1, ())));
82 assert_eq!(cursor.peek(), Some(&(1, ())));
83
84 assert_eq!(cursor.seek(&3), Some((3, ())));
85 assert_eq!(cursor.peek(), Some(&(3, ())));
86
87 assert_eq!(cursor.seek(&3), Some((3, ())));
88 assert_eq!(cursor.peek(), Some(&(3, ())));
89
90 assert_eq!(cursor.seek(&4), Some((4, ())));
91 assert_eq!(cursor.peek(), Some(&(4, ())));
92
93 assert_eq!(cursor.seek(&6), None);
94 assert_eq!(cursor.peek(), None);
95 }
96}