sweep_bptree/tree/
leaf_node.rs

1use super::*;
2use std::{
3    alloc::{alloc, Layout},
4    borrow::Borrow,
5    mem::{self, MaybeUninit},
6    slice::SliceIndex,
7};
8
9const N: usize = super::consts::LEAF_N;
10
11#[derive(Debug)]
12pub struct LeafNode<K, V> {
13    /// how many data items
14    size: u16,
15    slot_key: [MaybeUninit<K>; N],
16    slot_value: [MaybeUninit<V>; N],
17
18    prev: Option<LeafNodeId>,
19    next: Option<LeafNodeId>,
20}
21
22impl<K: Key, V> Clone for LeafNode<K, V>
23where
24    V: Clone,
25{
26    fn clone(&self) -> Self {
27        // SAFETY: An uninitialized `[MaybeUninit<_>; LEN]` is valid.
28        let mut new_key = unsafe { MaybeUninit::<[MaybeUninit<K>; N]>::uninit().assume_init() };
29
30        for i in 0..self.len() {
31            unsafe {
32                *new_key.get_unchecked_mut(i) =
33                    MaybeUninit::new(self.key_area(i).assume_init_ref().clone());
34            };
35        }
36
37        // SAFETY: An uninitialized `[MaybeUninit<_>; LEN]` is valid.
38        let mut new_value = unsafe { MaybeUninit::<[MaybeUninit<V>; N]>::uninit().assume_init() };
39
40        for i in 0..self.len() {
41            unsafe {
42                *new_value.get_unchecked_mut(i) =
43                    MaybeUninit::new(self.value_area(i).assume_init_ref().clone());
44            };
45        }
46
47        Self {
48            size: self.size.clone(),
49            slot_key: new_key,
50            slot_value: new_value,
51            prev: self.prev.clone(),
52            next: self.next.clone(),
53        }
54    }
55}
56
57impl<K: Key, V> LeafNode<K, V> {
58    pub fn new() -> Box<Self> {
59        let layout = Layout::new::<mem::MaybeUninit<Self>>();
60        let ptr: *mut Self = unsafe { alloc(layout).cast() };
61        let mut this = unsafe { Box::from_raw(ptr) };
62
63        this.prev = None;
64        this.next = None;
65        this.size = 0;
66
67        this
68    }
69
70    pub fn len(&self) -> usize {
71        self.size as usize
72    }
73
74    const fn split_origin_size() -> u16 {
75        (N / 2) as u16
76    }
77
78    /// Returns the maximum capacity of the leaf node
79    pub const fn max_capacity() -> u16 {
80        N as u16
81    }
82
83    /// the minimum size for Leaf Node, if the node size lower than this, then
84    /// it is under sized
85    const fn minimum_size() -> u16 {
86        let s = (N / 4) as u16;
87        if s == 0 {
88            1
89        } else {
90            s
91        }
92    }
93
94    pub fn is_full(&self) -> bool {
95        self.size == N as u16
96    }
97
98    pub fn able_to_lend(&self) -> bool {
99        self.size > Self::minimum_size()
100    }
101
102    pub fn in_range<Q: ?Sized>(&self, k: &Q) -> bool
103    where
104        Q: Ord,
105        K: std::borrow::Borrow<Q>,
106    {
107        let is_lt_start = match self.prev {
108            Some(_) => k.lt(unsafe { self.key_area(0).assume_init_ref().borrow() }),
109            None => false,
110        };
111        if is_lt_start {
112            return false;
113        }
114        let is_gt_end = match self.next {
115            Some(_) => k.gt(unsafe { self.key_area(self.len() - 1).assume_init_ref().borrow() }),
116            None => false,
117        };
118        !is_gt_end
119    }
120
121    pub fn key_range(&self) -> (Option<K>, Option<K>) {
122        debug_assert!(self.len() > 0);
123        let start = match self.prev {
124            Some(_) => Some(unsafe { self.key_area(0).assume_init_ref().clone() }),
125            None => None,
126        };
127        let end = match self.next {
128            Some(_) => Some(unsafe { self.key_area(self.len() - 1).assume_init_ref().clone() }),
129            None => None,
130        };
131        (start, end)
132    }
133
134    pub fn is_size_minimum(&self) -> bool {
135        self.size == Self::minimum_size()
136    }
137
138    pub fn set_prev(&mut self, id: Option<LeafNodeId>) {
139        self.prev = id;
140    }
141
142    pub fn prev(&self) -> Option<LeafNodeId> {
143        self.prev
144    }
145
146    pub fn set_next(&mut self, id: Option<LeafNodeId>) {
147        self.next = id;
148    }
149
150    pub fn next(&self) -> Option<LeafNodeId> {
151        self.next
152    }
153
154    pub fn set_data(&mut self, mut data: impl Iterator<Item = (K, V)>) {
155        for i in 0..N {
156            if let Some((k, v)) = data.next() {
157                unsafe {
158                    *self.key_area_mut(i) = MaybeUninit::new(k);
159                    *self.value_area_mut(i) = MaybeUninit::new(v);
160                }
161                self.size += 1;
162            } else {
163                break;
164            }
165        }
166    }
167
168    pub fn data_at(&self, slot: usize) -> (&K, &V) {
169        unsafe {
170            (
171                self.key_area(slot).assume_init_ref(),
172                self.value_area(slot).assume_init_ref(),
173            )
174        }
175    }
176
177    /// Get mut ref for value at slot
178    pub fn value_at_mut(&mut self, slot: usize) -> &mut V {
179        unsafe { self.value_area_mut(slot).assume_init_mut() }
180    }
181
182    pub fn try_data_at(&self, idx: usize) -> Option<(&K, &V)> {
183        if idx >= self.size as usize {
184            return None;
185        }
186        Some(unsafe {
187            (
188                self.key_area(idx).assume_init_ref(),
189                self.value_area(idx).assume_init_ref(),
190            )
191        })
192    }
193
194    #[cfg(test)]
195    fn iter(&self) -> impl Iterator<Item = (&K, &V)> {
196        unsafe { self.key_area(..self.size as usize) }
197            .iter()
198            .zip(unsafe { self.value_area(..self.size as usize) })
199            .map(|item| unsafe { (item.0.assume_init_ref(), item.1.assume_init_ref()) })
200    }
201
202    #[cfg(test)]
203    pub(crate) fn data_vec(&self) -> Vec<(K, V)>
204    where
205        V: Clone,
206    {
207        self.iter().map(|(k, v)| (k.clone(), v.clone())).collect()
208    }
209
210    /// insert / update (k, v), if node is full, then returns `LeafUpsertResult::IsFull`
211    pub(crate) fn try_upsert(&mut self, k: K, v: V) -> LeafUpsertResult<K, V> {
212        match self.locate_slot(&k) {
213            Ok(idx) => {
214                // update existing item
215                let prev_v =
216                    std::mem::replace(unsafe { self.value_area_mut(idx) }, MaybeUninit::new(v));
217                LeafUpsertResult::Updated(unsafe { prev_v.assume_init() })
218            }
219
220            Err(idx) => {
221                if !self.is_full() {
222                    let new_len = self.len() + 1;
223                    unsafe { slice_utils::slice_insert(self.key_area_mut(..new_len), idx, k) };
224                    unsafe { slice_utils::slice_insert(self.value_area_mut(..new_len), idx, v) };
225                    self.size = new_len as u16;
226                    LeafUpsertResult::Inserted
227                } else {
228                    LeafUpsertResult::IsFull(idx, k, v)
229                }
230            }
231        }
232    }
233
234    pub(crate) fn split_new_leaf(
235        &mut self,
236        insert_idx: usize,
237        item: (K, V),
238        new_leaf_id: LeafNodeId,
239        self_leaf_id: LeafNodeId,
240    ) -> Box<Self> {
241        let split_origin_size = Self::split_origin_size() as usize;
242        let split_new_size = N - split_origin_size as usize;
243
244        let mut new_node = Self::new();
245        new_node.prev = Some(self_leaf_id);
246        new_node.next = self.next;
247
248        unsafe {
249            slice_utils::move_to_slice(
250                self.key_area_mut(split_origin_size..N),
251                new_node.key_area_mut(..split_new_size as usize),
252            );
253            slice_utils::move_to_slice(
254                self.value_area_mut(split_origin_size..N),
255                new_node.value_area_mut(..split_new_size as usize),
256            );
257        };
258
259        if insert_idx < split_origin_size {
260            let new_size = split_origin_size as usize + 1;
261            unsafe {
262                slice_utils::slice_insert(self.key_area_mut(..new_size), insert_idx, item.0);
263                slice_utils::slice_insert(self.value_area_mut(..new_size), insert_idx, item.1);
264            };
265            self.size = new_size as u16;
266
267            new_node.size = split_new_size as u16;
268        } else {
269            // data insert to new/right
270            let insert_idx = insert_idx - split_origin_size;
271
272            unsafe {
273                slice_utils::slice_insert(
274                    new_node.key_area_mut(..split_new_size + 1),
275                    insert_idx,
276                    item.0,
277                );
278                slice_utils::slice_insert(
279                    new_node.value_area_mut(..split_new_size + 1),
280                    insert_idx,
281                    item.1,
282                );
283            }
284
285            self.size = split_origin_size as u16;
286            new_node.size = split_new_size as u16 + 1;
287        };
288
289        self.next = Some(new_leaf_id);
290
291        new_node
292    }
293
294    pub(crate) fn try_delete_at(&mut self, idx: usize) -> LeafDeleteResult<K, V> {
295        if self.able_to_lend() {
296            let result = unsafe {
297                let k = slice_utils::slice_remove(self.key_area_mut(..self.size as usize), idx);
298                let v = slice_utils::slice_remove(self.value_area_mut(..self.size as usize), idx);
299                (k, v)
300            };
301            self.size -= 1;
302            LeafDeleteResult::Done(result)
303        } else {
304            LeafDeleteResult::UnderSize(idx)
305        }
306    }
307
308    #[inline]
309    pub fn locate_slot<Q: ?Sized>(&self, k: &Q) -> Result<usize, usize>
310    where
311        Q: Ord,
312        K: std::borrow::Borrow<Q>,
313    {
314        self.keys().binary_search_by_key(&k, |f| f.borrow())
315    }
316
317    #[inline(always)]
318    pub fn locate_slot_with_value<Q: ?Sized>(&self, k: &Q) -> (usize, Option<&V>)
319    where
320        Q: Ord,
321        K: Borrow<Q>,
322    {
323        match self.locate_slot(k) {
324            Ok(idx) => {
325                // exact match, go to right child.
326                // if the child split, then the new key should inserted idx + 1
327                (idx, {
328                    let v = unsafe { self.value_area(idx).assume_init_ref() };
329                    Some(&v)
330                })
331            }
332
333            Err(idx) => {
334                // the idx is the place where a matching element could be inserted while maintaining
335                // sorted order. go to left child
336                (idx, None)
337            }
338        }
339    }
340
341    pub(crate) fn locate_slot_mut<Q: ?Sized>(&mut self, k: &Q) -> (usize, Option<&mut V>)
342    where
343        Q: Ord,
344        K: Borrow<Q>,
345    {
346        match self.locate_slot(k) {
347            Ok(idx) => {
348                // exact match, go to right child.
349                // if the child split, then the new key should inserted idx + 1
350                (
351                    idx,
352                    Some(unsafe { self.value_area_mut(idx).assume_init_mut() }),
353                )
354            }
355
356            Err(idx) => {
357                // the idx is the place where a matching element could be inserted while maintaining
358                // sorted order. go to left child
359                (idx, None)
360            }
361        }
362    }
363
364    /// pop the last item, this is used when next sibling undersize
365    pub(crate) fn pop(&mut self) -> (K, V) {
366        debug_assert!(self.able_to_lend());
367        let last_idx = self.size as usize - 1;
368        let result = unsafe {
369            let k = slice_utils::slice_remove(self.key_area_mut(..self.len()), last_idx);
370            let v = slice_utils::slice_remove(self.value_area_mut(..self.len()), last_idx);
371            (k, v)
372        };
373        self.size -= 1;
374        result
375    }
376
377    pub(crate) fn pop_front(&mut self) -> (K, V) {
378        debug_assert!(self.able_to_lend());
379        let result = unsafe {
380            let k = slice_utils::slice_remove(self.key_area_mut(..self.size as usize), 0);
381            let v = slice_utils::slice_remove(self.value_area_mut(..self.size as usize), 0);
382            (k, v)
383        };
384        self.size -= 1;
385        result
386    }
387
388    // delete the item at idx and append the item to last
389    pub(crate) fn delete_with_push(&mut self, idx: usize, item: (K, V)) -> (K, V) {
390        let result = unsafe {
391            let k = slice_utils::slice_remove(self.key_area_mut(..self.size as usize), idx);
392            let v = slice_utils::slice_remove(self.value_area_mut(..self.size as usize), idx);
393            (k, v)
394        };
395        unsafe {
396            *self.key_area_mut(self.size as usize - 1) = MaybeUninit::new(item.0);
397            *self.value_area_mut(self.size as usize - 1) = MaybeUninit::new(item.1);
398        }
399        result
400    }
401
402    // delete the item at idx and append the item to last
403    pub(crate) fn delete_with_push_front(&mut self, idx: usize, item: (K, V)) -> (K, V) {
404        let k = std::mem::replace(&mut self.slot_key[idx], MaybeUninit::uninit());
405        let v = std::mem::replace(&mut self.slot_value[idx], MaybeUninit::uninit());
406
407        unsafe {
408            slice_utils::slice_insert(self.key_area_mut(..idx + 1), 0, item.0);
409            slice_utils::slice_insert(self.value_area_mut(..idx + 1), 0, item.1);
410        }
411
412        unsafe { (k.assume_init_read(), v.assume_init_read()) }
413    }
414
415    /// Delete the item at idx, then merge with right
416    pub(crate) fn merge_right_delete_first(
417        &mut self,
418        delete_idx: usize,
419        right: &mut Self,
420    ) -> (K, V) {
421        let k = std::mem::replace(
422            unsafe { right.key_area_mut(delete_idx) },
423            MaybeUninit::uninit(),
424        );
425        let v = std::mem::replace(
426            unsafe { right.value_area_mut(delete_idx) },
427            MaybeUninit::uninit(),
428        );
429
430        {
431            let head = unsafe {
432                (
433                    right
434                        .slot_key
435                        .as_mut_slice()
436                        .get_unchecked_mut(..delete_idx),
437                    right
438                        .slot_value
439                        .as_mut_slice()
440                        .get_unchecked_mut(..delete_idx),
441                )
442            };
443            self.extend(head);
444        }
445
446        {
447            let right_len = right.len();
448            let tail = unsafe {
449                (
450                    right
451                        .slot_key
452                        .as_mut_slice()
453                        .get_unchecked_mut(delete_idx + 1..right_len),
454                    right
455                        .slot_value
456                        .as_mut_slice()
457                        .get_unchecked_mut(delete_idx + 1..right_len),
458                )
459            };
460            self.extend(tail);
461        }
462
463        self.next = right.next;
464        right.size = 0;
465
466        unsafe { (k.assume_init_read(), v.assume_init_read()) }
467    }
468
469    /// Delete the item at idx, then merge with right
470    pub(crate) fn merge_right(&mut self, right: &mut Self) {
471        let right_len = right.len();
472        let data = unsafe {
473            // safety: right.len() is checked against right.len()
474            (
475                right.slot_key.as_mut_slice().get_unchecked_mut(..right_len),
476                right
477                    .slot_value
478                    .as_mut_slice()
479                    .get_unchecked_mut(..right_len),
480            )
481        };
482        self.extend(data);
483
484        self.next = right.next;
485        right.size = 0;
486    }
487
488    /// This should never called with same slot
489    pub unsafe fn take_data(&mut self, slot: usize) -> (K, V) {
490        debug_assert!(slot < self.len());
491
492        // safety: slot is checked against self.len()
493        unsafe {
494            let k = std::mem::replace(self.key_area_mut(slot), MaybeUninit::uninit());
495            let v = std::mem::replace(self.value_area_mut(slot), MaybeUninit::uninit());
496            // special care must be taken to avoid double drop
497            (k.assume_init_read(), v.assume_init_read())
498        }
499    }
500
501    fn extend(&mut self, (keys, values): (&mut [MaybeUninit<K>], &mut [MaybeUninit<V>])) {
502        unsafe {
503            slice_utils::move_to_slice(
504                keys,
505                self.key_area_mut(self.len()..self.len() + keys.len()),
506            );
507            slice_utils::move_to_slice(
508                values,
509                self.value_area_mut(self.len()..self.len() + values.len()),
510            );
511        }
512        self.size += keys.len() as u16;
513    }
514
515    pub(crate) fn delete_at(&mut self, idx: usize) -> (K, V) {
516        let result = unsafe {
517            let k = slice_utils::slice_remove(self.key_area_mut(..self.size as usize), idx);
518            let v = slice_utils::slice_remove(self.value_area_mut(..self.size as usize), idx);
519            (k, v)
520        };
521        self.size -= 1;
522        result
523    }
524
525    pub fn keys(&self) -> &[K] {
526        unsafe {
527            {
528                let slice: &[MaybeUninit<K>] =
529                    self.slot_key.get_unchecked(..usize::from(self.size));
530                // SAFETY: casting `slice` to a `*const [T]` is safe since the caller guarantees that
531                // `slice` is initialized, and `MaybeUninit` is guaranteed to have the same layout as `T`.
532                // The pointer obtained is valid since it refers to memory owned by `slice` which is a
533                // reference and thus guaranteed to be valid for reads.
534                &*(slice as *const [MaybeUninit<K>] as *const [K])
535            }
536        }
537    }
538
539    pub fn values(&self) -> &[V] {
540        unsafe {
541            {
542                let slice: &[MaybeUninit<V>] =
543                    self.slot_value.get_unchecked(..usize::from(self.size));
544                // SAFETY: casting `slice` to a `*const [T]` is safe since the caller guarantees that
545                // `slice` is initialized, and `MaybeUninit` is guaranteed to have the same layout as `T`.
546                // The pointer obtained is valid since it refers to memory owned by `slice` which is a
547                // reference and thus guaranteed to be valid for reads.
548                &*(slice as *const [MaybeUninit<V>] as *const [V])
549            }
550        }
551    }
552
553    unsafe fn key_area_mut<I, Output: ?Sized>(&mut self, index: I) -> &mut Output
554    where
555        I: SliceIndex<[MaybeUninit<K>], Output = Output>,
556    {
557        // SAFETY: the caller will not be able to call further methods on self
558        // until the key slice reference is dropped, as we have unique access
559        // for the lifetime of the borrow.
560        unsafe { self.slot_key.as_mut_slice().get_unchecked_mut(index) }
561    }
562
563    unsafe fn key_area<I, Output: ?Sized>(&self, index: I) -> &Output
564    where
565        I: SliceIndex<[MaybeUninit<K>], Output = Output>,
566    {
567        // SAFETY: the caller will not be able to call further methods on self
568        // until the key slice reference is dropped, as we have unique access
569        // for the lifetime of the borrow.
570        unsafe { self.slot_key.as_slice().get_unchecked(index) }
571    }
572
573    unsafe fn value_area_mut<I, Output: ?Sized>(&mut self, index: I) -> &mut Output
574    where
575        I: SliceIndex<[MaybeUninit<V>], Output = Output>,
576    {
577        // SAFETY: the caller will not be able to call further methods on self
578        // until the value slice reference is dropped, as we have unique access
579        // for the lifetime of the borrow.
580        unsafe { self.slot_value.as_mut_slice().get_unchecked_mut(index) }
581    }
582
583    unsafe fn value_area<I, Output: ?Sized>(&self, index: I) -> &Output
584    where
585        I: SliceIndex<[MaybeUninit<V>], Output = Output>,
586    {
587        // SAFETY: the caller will not be able to call further methods on self
588        // until the value slice reference is dropped, as we have unique access
589        // for the lifetime of the borrow.
590        unsafe { self.slot_value.as_slice().get_unchecked(index) }
591    }
592}
593
594pub enum LeafUpsertResult<K, V> {
595    Inserted,
596    Updated(V),
597    IsFull(usize, K, V),
598}
599
600pub enum LeafDeleteResult<K, V> {
601    /// Succeeded deleted
602    Done((K, V)),
603    /// Item exists, but not able to delete because a merge is required
604    UnderSize(usize),
605}
606
607#[cfg(test)]
608mod tests {
609    use super::*;
610
611    /// create a leaf with data [2, 4, 6..]
612    fn test_leaf() -> Box<LeafNode<i64, i64>> {
613        let mut leaf = LeafNode::<i64, i64>::new();
614        leaf.set_data(
615            (0..N as i64)
616                .map(|i| ((i + 1) * 2, 0))
617                .collect::<Vec<_>>()
618                .into_iter(),
619        );
620        leaf
621    }
622
623    fn assert_ascend(data: Vec<(i64, i64)>) {
624        for i in 0..data.len() - 1 {
625            assert!(data[i].0 < data[i + 1].0);
626        }
627    }
628
629    fn assert_ascend_2(mut data_0: Vec<(i64, i64)>, data_1: Vec<(i64, i64)>) {
630        data_0.extend(data_1);
631        assert_ascend(data_0);
632    }
633
634    #[test]
635    fn test_split_leaf() {
636        let split_left_size = LeafNode::<i64, i64>::split_origin_size() as usize;
637
638        {
639            let mut leaf = test_leaf();
640            let new_leaf = leaf.split_new_leaf(0, (0, 0), LeafNodeId(2), LeafNodeId(1));
641
642            assert_eq!(leaf.data_vec().len(), N / 2 + 1);
643            assert_eq!(new_leaf.data_vec().len(), N / 2);
644            assert_ascend_2(leaf.data_vec(), new_leaf.data_vec());
645        }
646
647        {
648            let mut leaf = test_leaf();
649            let new_leaf = leaf.split_new_leaf(1, (3, 0), LeafNodeId(2), LeafNodeId(1));
650
651            assert_eq!(leaf.data_vec().len(), N / 2 + 1);
652            assert_eq!(new_leaf.data_vec().len(), N / 2);
653            assert_ascend_2(leaf.data_vec(), new_leaf.data_vec());
654        }
655
656        {
657            let mut leaf = test_leaf();
658            let new_leaf = leaf.split_new_leaf(
659                split_left_size,
660                (split_left_size as i64 * 2 + 1, 0),
661                LeafNodeId(2),
662                LeafNodeId(1),
663            );
664
665            assert_eq!(leaf.data_vec().len(), N / 2);
666            assert_eq!(new_leaf.data_vec().len(), N / 2 + 1);
667            assert_ascend_2(leaf.data_vec(), new_leaf.data_vec());
668        }
669
670        {
671            // split at left half's last element
672            let mut leaf = test_leaf();
673            let new_leaf = leaf.split_new_leaf(
674                split_left_size - 1,
675                ((split_left_size - 1) as i64 * 2 + 1, 0),
676                LeafNodeId(2),
677                LeafNodeId(1),
678            );
679
680            assert_eq!(leaf.data_vec().len(), N / 2 + 1);
681            assert_eq!(new_leaf.data_vec().len(), N / 2);
682            assert_ascend_2(leaf.data_vec(), new_leaf.data_vec());
683        }
684
685        {
686            // split at last
687            let mut leaf = test_leaf();
688            let new_leaf = leaf.split_new_leaf(
689                N - 1,
690                ((N as i64 - 1) * 2 + 1, 0),
691                LeafNodeId(2),
692                LeafNodeId(1),
693            );
694
695            assert_eq!(leaf.data_vec().len(), N / 2);
696            assert_eq!(new_leaf.data_vec().len(), N / 2 + 1);
697            assert_ascend_2(leaf.data_vec(), new_leaf.data_vec());
698        }
699    }
700    #[test]
701    fn test_in_range() {
702        let mut leaf = test_leaf();
703        // prev and next both none, so all keys should considered in range
704        assert!(leaf.in_range(&0));
705        assert!(leaf.in_range(&(129)));
706
707        leaf.set_prev(Some(LeafNodeId(1)));
708        // now had prev, so all keys less than min should be out of range
709        assert!(!leaf.in_range(&0));
710        assert!(leaf.in_range(&129));
711
712        leaf.set_next(Some(LeafNodeId(2)));
713        assert!(!leaf.in_range(&0));
714        assert!(!leaf.in_range(&129));
715    }
716}