Skip to main content

dbsp/trace/cursor/
reverse.rs

1use std::marker::PhantomData;
2
3use crate::{
4    dynamic::{Factory, WeightTrait},
5    trace::cursor::Position,
6};
7
8use super::Cursor;
9
10/// Cursor that reverses the direction of keys in the underlying
11/// cursor.
12///
13/// WARNING: This cursor iterates over keys in descending order,
14/// and thus will not work correctly with code that assumes
15/// monotonically growing keys.
16pub struct ReverseKeyCursor<'a, C: ?Sized, K: ?Sized, V: ?Sized, R: ?Sized> {
17    cursor: &'a mut C,
18    _phantom: PhantomData<fn(&K, &V, &R)>,
19}
20
21impl<'a, C, K: ?Sized, V: ?Sized, R: ?Sized> ReverseKeyCursor<'a, C, K, V, R>
22where
23    C: Cursor<K, V, (), R> + ?Sized,
24{
25    pub fn new(cursor: &'a mut C) -> Self {
26        cursor.fast_forward_keys();
27
28        Self {
29            cursor,
30            _phantom: PhantomData,
31        }
32    }
33}
34
35impl<C, K: ?Sized, V: ?Sized, R: WeightTrait + ?Sized> Cursor<K, V, (), R>
36    for ReverseKeyCursor<'_, C, K, V, R>
37where
38    C: Cursor<K, V, (), R> + ?Sized,
39{
40    fn weight_factory(&self) -> &'static dyn Factory<R> {
41        self.cursor.weight_factory()
42    }
43
44    fn key_valid(&self) -> bool {
45        self.cursor.key_valid()
46    }
47
48    fn val_valid(&self) -> bool {
49        self.cursor.val_valid()
50    }
51
52    fn key(&self) -> &K {
53        self.cursor.key()
54    }
55
56    fn val(&self) -> &V {
57        self.cursor.val()
58    }
59
60    fn get_key(&self) -> Option<&K> {
61        self.cursor.get_key()
62    }
63
64    fn get_val(&self) -> Option<&V> {
65        self.cursor.get_val()
66    }
67
68    fn map_times(&mut self, logic: &mut dyn FnMut(&(), &R)) {
69        self.cursor.map_times(logic)
70    }
71
72    fn map_times_through(&mut self, upper: &(), logic: &mut dyn FnMut(&(), &R)) {
73        self.cursor.map_times_through(upper, logic);
74    }
75
76    fn weight(&mut self) -> &R {
77        self.cursor.weight()
78    }
79
80    fn weight_checked(&mut self) -> &R {
81        self.cursor.weight_checked()
82    }
83
84    fn map_values(&mut self, logic: &mut dyn FnMut(&V, &R)) {
85        self.cursor.map_values(logic)
86    }
87
88    fn step_key(&mut self) {
89        self.cursor.step_key_reverse()
90    }
91
92    fn step_key_reverse(&mut self) {
93        self.cursor.step_key()
94    }
95
96    fn seek_key(&mut self, key: &K) {
97        self.cursor.seek_key_reverse(key)
98    }
99
100    fn seek_key_exact(&mut self, _key: &K, _hash: Option<u64>) -> bool {
101        todo!()
102    }
103
104    fn seek_key_with(&mut self, predicate: &dyn Fn(&K) -> bool) {
105        self.cursor.seek_key_with_reverse(predicate)
106    }
107
108    fn seek_key_with_reverse(&mut self, predicate: &dyn Fn(&K) -> bool) {
109        self.cursor.seek_key_with(predicate)
110    }
111
112    fn seek_key_reverse(&mut self, key: &K) {
113        self.cursor.seek_key(key)
114    }
115
116    fn step_val(&mut self) {
117        self.cursor.step_val()
118    }
119
120    fn step_val_reverse(&mut self) {
121        self.cursor.step_val_reverse()
122    }
123
124    fn seek_val(&mut self, val: &V) {
125        self.cursor.seek_val(val)
126    }
127
128    fn seek_val_reverse(&mut self, val: &V) {
129        self.cursor.seek_val_reverse(val)
130    }
131
132    fn seek_val_with(&mut self, predicate: &dyn Fn(&V) -> bool) {
133        self.cursor.seek_val_with(predicate)
134    }
135
136    fn seek_val_with_reverse(&mut self, predicate: &dyn Fn(&V) -> bool) {
137        self.cursor.seek_val_with_reverse(predicate)
138    }
139
140    fn rewind_keys(&mut self) {
141        self.cursor.fast_forward_keys()
142    }
143
144    fn fast_forward_keys(&mut self) {
145        self.cursor.rewind_keys()
146    }
147
148    fn rewind_vals(&mut self) {
149        self.cursor.rewind_vals()
150    }
151
152    fn fast_forward_vals(&mut self) {
153        self.cursor.fast_forward_vals()
154    }
155
156    fn position(&self) -> Option<Position> {
157        let position = self.cursor.position().unwrap();
158
159        Some(Position {
160            total: position.total,
161            offset: position.total - position.offset,
162        })
163    }
164}