Skip to main content

embed_collections/btree/
entry.rs

1use super::iter::{IterBackward, IterForward};
2use super::*;
3use core::fmt;
4
5/// Entry for an existing key-value pair in the tree
6pub struct OccupiedEntry<'a, K: Ord + Clone + Sized, V: Sized> {
7    pub(super) tree: &'a mut BTreeMap<K, V>,
8    pub(super) leaf: LeafNode<K, V>,
9    pub(super) idx: u32,
10}
11
12/// Entry for a vacant key position in the tree
13pub struct VacantEntry<'a, K: Ord + Clone + Sized, V: Sized> {
14    pub(super) tree: &'a mut BTreeMap<K, V>,
15    pub(super) leaf: Option<LeafNode<K, V>>,
16    pub(super) key: K,
17    pub(super) idx: u32,
18}
19
20/// Entry into a BTreeMap for in-place manipulation
21pub enum Entry<'a, K: Ord + Clone + Sized, V: Sized> {
22    Occupied(OccupiedEntry<'a, K, V>),
23    Vacant(VacantEntry<'a, K, V>),
24}
25
26impl<'a, K: Ord + Clone + Sized, V: Sized> Entry<'a, K, V> {
27    #[inline]
28    pub fn exists(&self) -> bool {
29        matches!(self, Entry::Occupied(_))
30    }
31
32    /// Ensures a value is in the entry by inserting the default if empty,
33    /// and returns a mutable reference to the value in the entry.
34    #[inline]
35    pub fn or_insert(self, default: V) -> &'a mut V
36    where
37        K: Ord,
38    {
39        match self {
40            Entry::Occupied(entry) => entry.into_mut(),
41            Entry::Vacant(entry) => entry.insert(default),
42        }
43    }
44
45    /// Ensures a value is in the entry by inserting the result of the default function if empty,
46    /// and returns a mutable reference to the value in the entry.
47    #[inline]
48    pub fn or_insert_with<F>(self, default: F) -> &'a mut V
49    where
50        F: FnOnce() -> V,
51        K: Ord,
52    {
53        match self {
54            Entry::Occupied(entry) => entry.into_mut(),
55            Entry::Vacant(entry) => entry.insert(default()),
56        }
57    }
58
59    /// Returns a reference to this entry's key.
60    #[inline]
61    pub fn key(&self) -> &K {
62        match self {
63            Entry::Occupied(entry) => entry.key(),
64            Entry::Vacant(entry) => &entry.key,
65        }
66    }
67
68    /// Provides in-place mutable access to an occupied entry before any
69    /// potential inserts into the tree.
70    #[inline]
71    pub fn and_modify<F>(self, f: F) -> Self
72    where
73        F: FnOnce(&mut V),
74    {
75        match self {
76            Entry::Occupied(mut entry) => {
77                f(entry.get_mut());
78                Entry::Occupied(entry)
79            }
80            Entry::Vacant(entry) => Entry::Vacant(entry),
81        }
82    }
83
84    // NOTE: Since rust does not alloc multiple mutable borrow, the moving api should assume ownership
85
86    /// Move to previous OccupiedEntry
87    ///
88    /// When reaching the front, return the original entry in Err()
89    #[inline]
90    pub fn move_backward(self) -> Result<OccupiedEntry<'a, K, V>, Self> {
91        match self {
92            Entry::Occupied(ent) => match ent.move_backward() {
93                Ok(_ent) => Ok(_ent),
94                Err(_ent) => Err(Entry::Occupied(_ent)),
95            },
96            Entry::Vacant(ent) => match ent.move_backward() {
97                Ok(_ent) => Ok(_ent),
98                Err(_ent) => Err(Entry::Vacant(_ent)),
99            },
100        }
101    }
102
103    /// Move to next OccupiedEntry
104    ///
105    /// When reaching the end, return the original entry in Err()
106    #[inline]
107    pub fn move_forward(self) -> Result<OccupiedEntry<'a, K, V>, Self> {
108        match self {
109            Entry::Occupied(ent) => match ent.move_forward() {
110                Ok(_ent) => Ok(_ent),
111                Err(_ent) => Err(Entry::Occupied(_ent)),
112            },
113            Entry::Vacant(ent) => match ent.move_forward() {
114                Ok(_ent) => Ok(_ent),
115                Err(_ent) => Err(Entry::Vacant(_ent)),
116            },
117        }
118    }
119
120    /// Peak previous OccupiedEntry
121    #[inline(always)]
122    pub fn peak_backward(&self) -> Option<(&'a K, &'a V)> {
123        match self {
124            Entry::Occupied(ent) => ent.peak_backward(),
125            Entry::Vacant(ent) => ent.peak_backward(),
126        }
127    }
128
129    /// Peak the next OccupiedEntry
130    #[inline(always)]
131    pub fn peak_forward(&self) -> Option<(&'a K, &'a V)> {
132        match self {
133            Entry::Occupied(ent) => ent.peak_forward(),
134            Entry::Vacant(ent) => ent.peak_forward(),
135        }
136    }
137}
138
139impl<'a, K: Ord + Clone + Sized + fmt::Debug, V: Sized + fmt::Debug> fmt::Debug
140    for OccupiedEntry<'a, K, V>
141{
142    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
143        f.debug_struct("OccupiedEntry").field("key", self.key()).field("value", self.get()).finish()
144    }
145}
146
147impl<'a, K: Ord + Clone + Sized + fmt::Debug, V: Sized + fmt::Debug> fmt::Debug
148    for VacantEntry<'a, K, V>
149{
150    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
151        f.debug_struct("VacantEntry").field("key", &self.key).finish()
152    }
153}
154
155impl<'a, K: Ord + Clone + Sized + fmt::Debug, V: Sized + fmt::Debug> fmt::Debug
156    for Entry<'a, K, V>
157{
158    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
159        match self {
160            Entry::Occupied(ent) => f.debug_tuple("Occupied").field(ent).finish(),
161            Entry::Vacant(ent) => f.debug_tuple("Vacant").field(ent).finish(),
162        }
163    }
164}
165
166impl<'a, K: Ord + Clone + Sized, V: Sized> OccupiedEntry<'a, K, V> {
167    /// Get a reference to the key
168    #[inline]
169    pub fn key(&self) -> &K {
170        unsafe {
171            let key_ptr = self.leaf.key_ptr(self.idx);
172            (*key_ptr).assume_init_ref()
173        }
174    }
175
176    /// Remove the key-value pair from the tree and return the value
177    #[inline(always)]
178    pub fn remove(self) -> V {
179        self.remove_entry().1
180    }
181
182    /// Remove the key-value pair from the tree and return the key and value
183    #[inline]
184    pub fn remove_entry(self) -> (K, V) {
185        self._remove_entry(true)
186    }
187
188    /// Remove the key-value pair from the tree and return the key and value
189    #[inline(always)]
190    pub(crate) fn _remove_entry(mut self, merge: bool) -> (K, V) {
191        let (key, val) = self.leaf.remove_pair_no_borrow(self.idx);
192        self.tree.len -= 1;
193        // Check for underflow and handle merge
194        let new_count = self.leaf.key_count();
195        let min_count = LeafNode::<K, V>::cap() >> 1;
196        if new_count < min_count && self.tree.root_is_inter() {
197            // The cache should already contain the path from the entry lookup
198            self.tree.handle_leaf_underflow(self.leaf, merge);
199        }
200        (key, val)
201    }
202
203    /// Get a reference to the value
204    #[inline]
205    pub fn get(&self) -> &V {
206        unsafe {
207            let val_ptr = self.leaf.value_ptr(self.idx);
208            (*val_ptr).assume_init_ref()
209        }
210    }
211
212    /// Get a mutable reference to the value
213    #[inline]
214    pub fn get_mut(&mut self) -> &mut V {
215        unsafe {
216            let val_ptr = self.leaf.value_ptr(self.idx);
217            (*val_ptr).assume_init_mut()
218        }
219    }
220
221    /// Convert the OccupiedEntry into a mutable reference bounded by
222    /// the tree's lifetime
223    #[inline]
224    pub fn into_mut(self) -> &'a mut V {
225        unsafe {
226            let val_ptr = self.leaf.value_ptr(self.idx);
227            (*val_ptr).assume_init_mut()
228        }
229    }
230
231    /// replace a value into the tree and return the old value
232    #[inline]
233    pub fn insert(&mut self, value: V) -> V {
234        self.leaf.replace(self.idx, value)
235    }
236
237    /// Peak previous OccupiedEntry
238    #[inline(always)]
239    pub fn peak_backward(&self) -> Option<(&'a K, &'a V)> {
240        let mut cursor = IterBackward { back_leaf: self.leaf.clone(), back_idx: self.idx };
241        unsafe {
242            if let Some((k, v)) = cursor.prev_pair() {
243                return Some((&*k, &*v));
244            }
245        }
246        None
247    }
248
249    /// Peak the next OccupiedEntry
250    #[inline(always)]
251    pub fn peak_forward(&self) -> Option<(&'a K, &'a V)> {
252        let mut cursor = IterForward { front_leaf: self.leaf.clone(), idx: self.idx + 1 };
253        unsafe {
254            if let Some((k, v)) = cursor.next_pair() {
255                return Some((&*k, &*v));
256            }
257        }
258        None
259    }
260
261    /// Move to previous OccupiedEntry
262    ///
263    /// When reaching the front, return the original entry in Err()
264    #[inline]
265    pub fn move_backward(self) -> Result<Self, Self> {
266        if self.idx > 0 {
267            return Ok(Self { tree: self.tree, leaf: self.leaf, idx: self.idx - 1 });
268        } else if let Some(leaf) = self.leaf.get_left_node() {
269            if let Some(info) = self.tree._get_info().as_mut() {
270                info.move_left();
271            }
272            let count = leaf.key_count();
273            debug_assert!(count > 0);
274            return Ok(Self { tree: self.tree, leaf, idx: count - 1 });
275        } else {
276            Err(self)
277        }
278    }
279
280    /// Move to next OccupiedEntry
281    ///
282    /// When reaching the end, return the original entry in Err()
283    #[inline]
284    pub fn move_forward(self) -> Result<Self, Self> {
285        let next_idx = self.idx + 1;
286        if self.leaf.key_count() > next_idx {
287            return Ok(Self { tree: self.tree, leaf: self.leaf, idx: next_idx });
288        } else if let Some(right) = self.leaf.get_right_node() {
289            if let Some(info) = self.tree._get_info().as_mut() {
290                info.move_right();
291            }
292            debug_assert!(right.key_count() > 0);
293            return Ok(Self { tree: self.tree, leaf: right, idx: 0 });
294        } else {
295            Err(self)
296        }
297    }
298
299    /// Try to alter the key of this entry
300    ///
301    /// On successful returns  Ok() ;
302    /// If key is not in strict order among the neighbors, return  Err() .
303    #[inline]
304    pub fn alter_key(&mut self, k: K) -> Result<(), ()> {
305        if let Some((_k, _v)) = self.peak_backward() {
306            if _k >= &k {
307                return Err(());
308            }
309        }
310        if let Some((_k, _v)) = self.peak_forward() {
311            if _k <= &k {
312                return Err(());
313            }
314        }
315        unsafe {
316            let k_ref = (*self.leaf.key_ptr(self.idx)).assume_init_mut();
317            if self.idx == 0 {
318                self.tree.update_ancestor_sep_key::<false>(k.clone());
319            }
320            *k_ref = k;
321            Ok(())
322        }
323    }
324
325    #[cfg(test)]
326    pub(crate) fn validate_cache_path(&self) {
327        let k = self.leaf.get_keys()[self.idx as usize].clone();
328        if let Some(info) = self.tree._get_info().as_mut() {
329            info.fix_center();
330            let backup = info.to_vec();
331            let mut _info = TreeInfo::new(info.leaf_count(), info.inter_count());
332            let _leaf = self
333                .tree
334                .search_leaf_with(|inter| inter.find_leaf_with_cache(&mut _info, &k))
335                .unwrap();
336            assert_eq!(self.leaf, _leaf);
337            assert_eq!(backup, _info.to_vec());
338        } else {
339            return;
340        }
341    }
342}
343
344impl<'a, K: Ord + Clone + Sized, V: Sized> VacantEntry<'a, K, V> {
345    /// Get a reference to the key
346    #[inline]
347    pub fn key(&self) -> &K {
348        &self.key
349    }
350
351    /// Take ownership of the key
352    #[inline]
353    pub fn into_key(self) -> K {
354        self.key
355    }
356
357    /// Insert a value into the tree
358    #[inline]
359    pub fn insert(self, value: V) -> &'a mut V {
360        let (key, tree, idx) = (self.key, self.tree, self.idx);
361        if tree.root.is_none() {
362            return tree.init_empty(key, value);
363        }
364        tree.len += 1;
365        // Get the leaf node where we should insert
366        let mut leaf = self.leaf.expect("VacantEntry should have a node when root is not None");
367        let count = leaf.key_count();
368        // Check if leaf has space
369        let value_p = if count < LeafNode::<K, V>::cap() {
370            leaf.insert_no_split_with_idx(idx, key, value)
371        } else {
372            // Leaf is full, need to split
373            tree.insert_with_split(key, value, leaf, idx)
374            // NOTE: the PathCache might be a different path with the one inserted,
375            // because borrowing on inter node might happen, and the cache is consumed during
376            // propagate_split moves upwards.
377            // It's too complex to provide returning OccupiedEntry because the subsequence operation
378            // relies on a correct PathCache
379        };
380        unsafe { &mut *value_p }
381    }
382
383    /// Peak previous OccupiedEntry
384    #[inline(always)]
385    pub fn peak_backward(&self) -> Option<(&'a K, &'a V)> {
386        if let Some(leaf) = self.leaf.as_ref() {
387            // The key of previous pos is always smaller than self.key ;
388            // the key at current idx (if exists) must larger than self.key.
389            let mut cursor = IterBackward { back_leaf: leaf.clone(), back_idx: self.idx };
390            unsafe {
391                if let Some((k, v)) = cursor.prev_pair() {
392                    return Some((&*k, &*v));
393                }
394            }
395        }
396        None
397    }
398
399    /// Peak the next OccupiedEntry
400    #[inline(always)]
401    pub fn peak_forward(&self) -> Option<(&'a K, &'a V)> {
402        if let Some(leaf) = self.leaf.as_ref() {
403            unsafe {
404                if let Some((k, v)) = leaf.get_raw_pair(self.idx) {
405                    // get_raw_pair will validate idx
406                    return Some((&*k, &*v));
407                }
408                if let Some(right) = leaf.get_right_node() {
409                    if let Some((k, v)) = right.get_raw_pair(0) {
410                        return Some((&*k, &*v));
411                    }
412                }
413            }
414        }
415        None
416    }
417
418    /// Move to previous OccupiedEntry
419    ///
420    /// When reaching the front return the original entry in Err()
421    #[inline]
422    pub fn move_backward(self) -> Result<OccupiedEntry<'a, K, V>, Self> {
423        if let Some(leaf) = self.leaf.as_ref() {
424            // The key of previous pos is always smaller than self.key ;
425            // the key at current idx (if exists) must larger than self.key.
426            // It's possible the leaf.idx may be == leaf.key_count(), but it's the same.
427            if self.idx > 0 {
428                return Ok(OccupiedEntry {
429                    tree: self.tree,
430                    leaf: leaf.clone(),
431                    idx: self.idx - 1,
432                });
433            }
434            if let Some(left) = leaf.get_left_node() {
435                let count = left.key_count();
436                debug_assert!(count > 0);
437                if let Some(info) = self.tree._get_info().as_mut() {
438                    info.move_left();
439                }
440                return Ok(OccupiedEntry { tree: self.tree, leaf: left, idx: count - 1 });
441            }
442        }
443        Err(self)
444    }
445
446    /// Move to next OccupiedEntry
447    ///
448    /// When reaching the end, return the original entry in Err()
449    #[inline]
450    pub fn move_forward(self) -> Result<OccupiedEntry<'a, K, V>, Self> {
451        if let Some(leaf) = self.leaf.as_ref() {
452            if leaf.key_count() > self.idx {
453                // the key at current idx (if exists) must larger than self.key, no need to move
454                return Ok(OccupiedEntry { tree: self.tree, leaf: leaf.clone(), idx: self.idx });
455            } else if let Some(right) = leaf.get_right_node() {
456                debug_assert!(right.key_count() > 0);
457                if let Some(info) = self.tree._get_info().as_mut() {
458                    info.move_right();
459                }
460                return Ok(OccupiedEntry { tree: self.tree, leaf: right, idx: 0 });
461            }
462        }
463        Err(self)
464    }
465}