embed_collections/btree/cursor.rs
1use super::iter::{IterBackward, IterForward};
2use super::*;
3use core::marker::PhantomData;
4
5/// A read-only cursor for navigating through entries in a BTreeMap.
6///
7/// The cursor provides bidirectional navigation using leaf node sibling pointers,
8/// you can change where the direction goes at any time.
9///
10/// `Cursor` is lighter than [Iter] (without the cost of DoubleEndedIterator trait) and more customizable.
11///
12/// # Example
13///
14/// ```
15/// use embed_collections::BTreeMap;
16///
17/// let mut map = BTreeMap::new();
18/// map.insert(1, "a");
19/// map.insert(3, "b");
20/// map.insert(5, "c");
21///
22/// // Create cursor at key 2
23/// let mut cursor = map.cursor(&1);
24/// assert_eq!(cursor.next(), Some((&1, &"a")));
25/// assert_eq!(cursor.next(), Some((&3, &"b")));
26/// assert_eq!(cursor.next(), Some((&5, &"c")));
27/// assert_eq!(cursor.next(), None);
28///
29/// let mut cursor = map.cursor(&2);
30/// // return next existing key
31/// assert_eq!(cursor.next(), Some((&3, &"b")));
32/// assert_eq!(cursor.next(), Some((&5, &"c")));
33///
34/// // Peek without moving
35/// assert_eq!(cursor.peek_forward(), None);
36/// assert_eq!(cursor.peek_backward(), Some((&5, &"c")));
37/// assert_eq!(cursor.next(), None);
38///
39/// // Rewind
40/// assert_eq!(cursor.previous(), Some((&5, &"c")));
41///
42/// // Iterate from the back
43/// let mut cursor = map.last_cursor();
44/// assert_eq!(cursor.previous(), Some((&5, &"c")));
45/// assert_eq!(cursor.previous(), Some((&3, &"b")));
46/// assert_eq!(cursor.previous(), Some((&1, &"a")));
47/// assert_eq!(cursor.previous(), None);
48/// ```
49pub struct Cursor<'a, K: Ord + Clone + Sized, V: Sized> {
50 pub(super) leaf: Option<LeafNode<K, V>>,
51 pub(super) idx: u32,
52 pub(super) is_exist: bool,
53 pub(super) _marker: PhantomData<&'a ()>,
54}
55
56impl<'a, K: Ord + Clone + Sized + 'a, V: Sized + 'a> Iterator for Cursor<'a, K, V> {
57 type Item = (&'a K, &'a V);
58
59 /// Returns the key-value pair at current position, then move the cursor forward.
60 ///
61 /// # Example
62 ///
63 /// ```
64 /// use embed_collections::btree::BTreeMap;
65 /// let mut map = BTreeMap::new();
66 /// map.insert(1, "a");
67 /// map.insert(3, "b");
68 /// map.insert(5, "c");
69 ///
70 /// let mut cursor = map.first_cursor();
71 /// assert_eq!(cursor.next(), Some((&1, &"a")));
72 /// assert_eq!(cursor.next(), Some((&3, &"b")));
73 /// assert_eq!(cursor.next(), Some((&5, &"c")));
74 /// assert_eq!(cursor.next(), None);
75 ///
76 /// // existing key
77 /// let mut cursor = map.cursor(&3);
78 /// assert_eq!(cursor.next(), Some((&3, &"b")));
79 /// assert_eq!(cursor.next(), Some((&5, &"c")));
80 /// assert_eq!(cursor.next(), None);
81 ///
82 /// // non existing key
83 /// let mut cursor = map.cursor(&2);
84 /// assert_eq!(cursor.next(), Some((&3, &"b")));
85 /// assert_eq!(cursor.next(), Some((&5, &"c")));
86 /// assert_eq!(cursor.next(), None);
87 /// ```
88 #[inline]
89 fn next(&mut self) -> Option<(&'a K, &'a V)> {
90 unsafe {
91 loop {
92 let leaf = self.leaf.as_ref()?;
93 let idx = self.idx;
94 if self.is_exist {
95 let (_k, _v) = leaf.get_raw_pair_unchecked(idx);
96 let res = Some((&*_k, &*_v));
97 if idx + 1 < leaf.key_count() {
98 self.idx = idx + 1;
99 } else {
100 if let Some(right) = leaf.get_right_node() {
101 self.leaf.replace(right);
102 self.idx = 0;
103 } else {
104 self.is_exist = false;
105 self.idx = idx + 1;
106 }
107 }
108 return res;
109 } else {
110 if self.idx < leaf.key_count() {
111 self.is_exist = true;
112 } else if let Some(right) = leaf.get_right_node() {
113 _ = leaf;
114 self.leaf.replace(right);
115 self.idx = 0;
116 self.is_exist = true;
117 } else {
118 return None;
119 }
120 }
121 }
122 }
123 }
124}
125
126impl<'a, K: Ord + Clone + Sized, V: Sized> Cursor<'a, K, V> {
127 #[inline(always)]
128 pub fn is_exist(&self) -> bool {
129 self.is_exist
130 }
131
132 /// returns the key-value pair and move the cursor to previous position
133 /// Returns `None` if already at the beginning.
134 ///
135 /// # Example
136 ///
137 /// ```
138 /// use embed_collections::btree::BTreeMap;
139 ///
140 /// let mut map = BTreeMap::new();
141 /// map.insert(1, "a");
142 /// map.insert(3, "b");
143 /// map.insert(5, "c");
144 ///
145 /// // Iterate from the back
146 /// let mut cursor = map.last_cursor();
147 /// assert_eq!(cursor.previous(), Some((&5, &"c")));
148 /// assert_eq!(cursor.previous(), Some((&3, &"b")));
149 /// assert_eq!(cursor.previous(), Some((&1, &"a")));
150 ///
151 /// // non-existing key
152 /// let mut cursor = map.cursor(&4);
153 /// assert_eq!(cursor.previous(), Some((&3, &"b")));
154 /// assert_eq!(cursor.previous(), Some((&1, &"a")));
155 ///
156 /// // existing key
157 ///
158 /// let mut cursor = map.cursor(&3);
159 /// assert_eq!(cursor.previous(), Some((&3, &"b")));
160 /// assert_eq!(cursor.previous(), Some((&1, &"a")));
161 /// ```
162 #[inline]
163 pub fn previous(&mut self) -> Option<(&K, &V)> {
164 let leaf = self.leaf.as_ref()?;
165 let idx = self.idx;
166 unsafe {
167 if self.idx > 0 {
168 self.idx -= 1;
169 if self.is_exist && idx < leaf.key_count() {
170 let (_k, _v) = leaf.get_raw_pair_unchecked(idx);
171 return Some((&*_k, &*_v));
172 } else {
173 let (_k, _v) = leaf.get_raw_pair_unchecked(self.idx);
174 return Some((&*_k, &*_v));
175 }
176 }
177 if self.is_exist {
178 let (_k, _v) = leaf.get_raw_pair_unchecked(0);
179 let res = Some((&*_k, &*_v));
180 if let Some(prev) = leaf.get_left_node() {
181 let count = prev.key_count();
182 debug_assert!(count > 0);
183 self.idx = count - 1;
184 self.leaf.replace(prev);
185 } else {
186 self.is_exist = false;
187 }
188 return res;
189 }
190 if let Some(prev) = leaf.get_left_node() {
191 let count = prev.key_count();
192 debug_assert!(count > 0);
193 self.leaf.replace(prev.clone());
194 if count > 1 {
195 self.idx = count - 2;
196 self.is_exist = true;
197 } else {
198 self.idx = 0;
199 self.is_exist = false;
200 }
201 let (_k, _v) = prev.get_raw_pair_unchecked(count - 1);
202 Some((&*_k, &*_v))
203 } else {
204 None
205 }
206 }
207 }
208
209 /// Peeks at the previous entry without moving the cursor.
210 /// Returns `None` if there is no previous entry.
211 ///
212 /// # Example
213 ///
214 /// ```
215 /// use embed_collections::BTreeMap;
216 ///
217 /// let mut map = BTreeMap::new();
218 /// map.insert(1, "a");
219 /// map.insert(3, "b");
220 /// map.insert(5, "c");
221 ///
222 /// // non-existing key
223 /// let mut cursor = map.cursor(&2);
224 /// assert_eq!(cursor.peek_backward(), Some((&1, &"a")));
225 ///
226 /// // existing key
227 /// let mut cursor = map.cursor(&3);
228 /// assert_eq!(cursor.peek_backward(), Some((&1, &"a")));
229 #[inline]
230 pub fn peek_backward(&self) -> Option<(&K, &V)> {
231 let leaf = self.leaf.as_ref()?;
232 let mut cursor = IterBackward { back_leaf: leaf.clone(), back_idx: self.idx };
233 unsafe {
234 if let Some((k, v)) = cursor.prev_pair() {
235 return Some((&*k, &*v));
236 }
237 }
238 None
239 }
240
241 /// Peeks at the next entry without moving the cursor.
242 /// Returns `None` if there is no next entry.
243 ///
244 /// # Example
245 ///
246 /// ```
247 /// use embed_collections::BTreeMap;
248 ///
249 /// let mut map = BTreeMap::new();
250 /// map.insert(1, "a");
251 /// map.insert(3, "b");
252 /// map.insert(5, "c");
253 /// // non-existing key
254 /// let cursor = map.cursor(&2);
255 /// assert_eq!(cursor.peek_forward(), Some((&3, &"b")));
256 ///
257 /// // existing key
258 /// let cursor = map.cursor(&1);
259 /// assert_eq!(cursor.peek_forward(), Some((&3, &"b")));
260 ///
261 /// #[inline]
262 pub fn peek_forward(&self) -> Option<(&K, &V)> {
263 let leaf = self.leaf.as_ref()?;
264 unsafe {
265 if self.is_exist {
266 let mut cursor = IterForward { front_leaf: leaf.clone(), idx: self.idx + 1 };
267 if let Some((k, v)) = cursor.next_pair() {
268 return Some((&*k, &*v));
269 }
270 } else {
271 if let Some((k, v)) = leaf.get_raw_pair(self.idx) {
272 // get_raw_pair will validate idx
273 return Some((&*k, &*v));
274 }
275 if let Some(right) = leaf.get_right_node()
276 && let Some((k, v)) = right.get_raw_pair(0)
277 {
278 return Some((&*k, &*v));
279 }
280 }
281 }
282 None
283 }
284}
285
286/*
287impl<'a, K: Ord + Clone + Sized + fmt::Debug, V: Sized + fmt::Debug> fmt::Debug
288 for Cursor<'a, K, V>
289{
290 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
291 if let Some((k, v)) = self.peek_forward() {
292 f.debug_struct("Cursor").field("key", k).field("value", v).finish()
293 } else {
294 f.debug_struct("Cursor").field("key", &"<end>").field("value", &"<end>").finish()
295 }
296 }
297}
298*/