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 ///
77 /// // existing key
78 /// let mut cursor = map.cursor(&3);
79 /// assert_eq!(cursor.next(), Some((&3, &"b")));
80 /// assert_eq!(cursor.next(), Some((&5, &"c")));
81 /// assert_eq!(cursor.next(), None);
82 ///
83 /// // non existing key
84 /// let mut cursor = map.cursor(&2);
85 /// assert_eq!(cursor.next(), Some((&3, &"b")));
86 /// assert_eq!(cursor.next(), Some((&5, &"c")));
87 /// assert_eq!(cursor.next(), None);
88 /// ```
89 #[inline]
90 fn next(&mut self) -> Option<(&'a K, &'a V)> {
91 unsafe {
92 loop {
93 let leaf = self.leaf.as_ref()?;
94 let idx = self.idx;
95 if self.is_exist {
96 let (_k, _v) = leaf.get_raw_pair_unchecked(idx);
97 let res = Some((&*_k, &*_v));
98 if idx + 1 < leaf.key_count() {
99 self.idx = idx + 1;
100 } else {
101 if let Some(right) = leaf.get_right_node() {
102 self.leaf.replace(right);
103 self.idx = 0;
104 } else {
105 self.is_exist = false;
106 self.idx = idx + 1;
107 }
108 }
109 return res;
110 } else {
111 if self.idx < leaf.key_count() {
112 self.is_exist = true;
113 } else if let Some(right) = leaf.get_right_node() {
114 _ = leaf;
115 self.leaf.replace(right);
116 self.idx = 0;
117 self.is_exist = true;
118 } else {
119 return None;
120 }
121 }
122 }
123 }
124 }
125}
126
127impl<'a, K: Ord + Clone + Sized, V: Sized> Cursor<'a, K, V> {
128 #[inline(always)]
129 pub fn is_exist(&self) -> bool {
130 self.is_exist
131 }
132
133 /// returns the key-value pair and move the cursor to previous position
134 /// Returns `None` if already at the beginning.
135 ///
136 /// # Example
137 ///
138 /// ```
139 /// use embed_collections::btree::BTreeMap;
140 ///
141 /// let mut map = BTreeMap::new();
142 /// map.insert(1, "a");
143 /// map.insert(3, "b");
144 /// map.insert(5, "c");
145 ///
146 /// // Iterate from the back
147 /// let mut cursor = map.last_cursor();
148 /// assert_eq!(cursor.previous(), Some((&5, &"c")));
149 /// assert_eq!(cursor.previous(), Some((&3, &"b")));
150 /// assert_eq!(cursor.previous(), Some((&1, &"a")));
151 ///
152 /// // non-existing key
153 /// let mut cursor = map.cursor(&4);
154 /// assert_eq!(cursor.previous(), Some((&3, &"b")));
155 /// assert_eq!(cursor.previous(), Some((&1, &"a")));
156 ///
157 /// // existing key
158 ///
159 /// let mut cursor = map.cursor(&3);
160 /// assert_eq!(cursor.previous(), Some((&3, &"b")));
161 /// assert_eq!(cursor.previous(), Some((&1, &"a")));
162 /// ```
163 #[inline]
164 pub fn previous(&mut self) -> Option<(&K, &V)> {
165 let leaf = self.leaf.as_ref()?;
166 let idx = self.idx;
167 unsafe {
168 if self.idx > 0 {
169 self.idx -= 1;
170 if self.is_exist && idx < leaf.key_count() {
171 let (_k, _v) = leaf.get_raw_pair_unchecked(idx);
172 return Some((&*_k, &*_v));
173 } else {
174 let (_k, _v) = leaf.get_raw_pair_unchecked(self.idx);
175 return Some((&*_k, &*_v));
176 }
177 }
178 if self.is_exist {
179 let (_k, _v) = leaf.get_raw_pair_unchecked(0);
180 let res = Some((&*_k, &*_v));
181 if let Some(prev) = leaf.get_left_node() {
182 let count = prev.key_count();
183 debug_assert!(count > 0);
184 self.idx = count - 1;
185 self.leaf.replace(prev);
186 } else {
187 self.is_exist = false;
188 }
189 return res;
190 }
191 if let Some(prev) = leaf.get_left_node() {
192 let count = prev.key_count();
193 debug_assert!(count > 0);
194 self.leaf.replace(prev.clone());
195 if count > 1 {
196 self.idx = count - 2;
197 self.is_exist = true;
198 } else {
199 self.idx = 0;
200 self.is_exist = false;
201 }
202 let (_k, _v) = prev.get_raw_pair_unchecked(count - 1);
203 Some((&*_k, &*_v))
204 } else {
205 None
206 }
207 }
208 }
209
210 /// Peeks at the previous entry without moving the cursor.
211 /// Returns `None` if there is no previous entry.
212 ///
213 /// # Example
214 ///
215 /// ```
216 /// use embed_collections::BTreeMap;
217 ///
218 /// let mut map = BTreeMap::new();
219 /// map.insert(1, "a");
220 /// map.insert(3, "b");
221 /// map.insert(5, "c");
222 ///
223 /// // non-existing key
224 /// let mut cursor = map.cursor(&2);
225 /// assert_eq!(cursor.peek_backward(), Some((&1, &"a")));
226 ///
227 /// // existing key
228 /// let mut cursor = map.cursor(&3);
229 /// assert_eq!(cursor.peek_backward(), Some((&1, &"a")));
230 #[inline]
231 pub fn peek_backward(&self) -> Option<(&K, &V)> {
232 let leaf = self.leaf.as_ref()?;
233 let mut cursor = IterBackward { back_leaf: leaf.clone(), back_idx: self.idx };
234 unsafe {
235 if let Some((k, v)) = cursor.prev_pair() {
236 return Some((&*k, &*v));
237 }
238 }
239 None
240 }
241
242 /// Peeks at the next entry without moving the cursor.
243 /// Returns `None` if there is no next entry.
244 ///
245 /// # Example
246 ///
247 /// ```
248 /// use embed_collections::BTreeMap;
249 ///
250 /// let mut map = BTreeMap::new();
251 /// map.insert(1, "a");
252 /// map.insert(3, "b");
253 /// map.insert(5, "c");
254 /// // non-existing key
255 /// let cursor = map.cursor(&2);
256 /// assert_eq!(cursor.peek_forward(), Some((&3, &"b")));
257 ///
258 /// // existing key
259 /// let cursor = map.cursor(&1);
260 /// assert_eq!(cursor.peek_forward(), Some((&3, &"b")));
261 ///
262 /// #[inline]
263 pub fn peek_forward(&self) -> Option<(&K, &V)> {
264 let leaf = self.leaf.as_ref()?;
265 unsafe {
266 if self.is_exist {
267 let mut cursor = IterForward { front_leaf: leaf.clone(), idx: self.idx + 1 };
268 if let Some((k, v)) = cursor.next_pair() {
269 return Some((&*k, &*v));
270 }
271 } else {
272 if let Some((k, v)) = leaf.get_raw_pair(self.idx) {
273 // get_raw_pair will validate idx
274 return Some((&*k, &*v));
275 }
276 if let Some(right) = leaf.get_right_node() {
277 if let Some((k, v)) = right.get_raw_pair(0) {
278 return Some((&*k, &*v));
279 }
280 }
281 }
282 }
283 None
284 }
285}
286
287/*
288impl<'a, K: Ord + Clone + Sized + fmt::Debug, V: Sized + fmt::Debug> fmt::Debug
289 for Cursor<'a, K, V>
290{
291 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
292 if let Some((k, v)) = self.peek_forward() {
293 f.debug_struct("Cursor").field("key", k).field("value", v).finish()
294 } else {
295 f.debug_struct("Cursor").field("key", &"<end>").field("value", &"<end>").finish()
296 }
297 }
298}
299*/