Skip to main content

scc/tree_index/
node.rs

1use std::convert::AsRef;
2use std::fmt;
3use std::ops::RangeBounds;
4use std::sync::atomic::Ordering::{AcqRel, Acquire, Relaxed, Release};
5
6use sdd::{AtomicRaw, Owned, RawPtr};
7
8use super::internal_node::InternalNode;
9use super::internal_node::Locker as InternalNodeLocker;
10use super::leaf::{InsertResult, Iter, Leaf, RemoveResult, RevIter};
11use super::leaf_node::LeafNode;
12use crate::utils::{LockPager, deref_unchecked, get_owned, undefined};
13use crate::{Comparable, Guard};
14
15/// [`Node`] is either [`Self::Internal`] or [`Self::Leaf`].
16#[repr(align(64))]
17pub enum Node<K, V> {
18    /// Internal node.
19    Internal(InternalNode<K, V>),
20    /// Leaf node.
21    Leaf(LeafNode<K, V>),
22}
23
24impl<K, V> Node<K, V> {
25    /// Creates a new [`InternalNode`].
26    #[inline]
27    pub(super) fn new_internal_node() -> Self {
28        Self::Internal(InternalNode::new())
29    }
30
31    /// Creates a new [`InternalNode`] in a frozen state.
32    #[inline]
33    pub(super) fn new_internal_node_frozen() -> Self {
34        Self::Internal(InternalNode::new_frozen())
35    }
36
37    /// Creates a new [`LeafNode`] in a frozen state.
38    #[inline]
39    pub(super) fn new_leaf_node_frozen() -> Self {
40        Self::Leaf(LeafNode::new_frozen())
41    }
42
43    /// Clears the node.
44    #[inline]
45    pub(super) fn clear<const DROP: bool>(&self, guard: &Guard) {
46        match self {
47            Self::Internal(internal_node) => internal_node.clear::<DROP>(guard),
48            Self::Leaf(leaf_node) => leaf_node.clear::<DROP>(guard),
49        }
50    }
51
52    /// Returns the depth of the node.
53    #[inline]
54    pub(super) fn depth(&self, depth: usize, guard: &Guard) -> usize {
55        match &self {
56            Self::Internal(internal_node) => internal_node.depth(depth, guard),
57            Self::Leaf(_) => depth,
58        }
59    }
60
61    /// Checks if the node has retired.
62    #[inline]
63    pub(super) fn is_retired(&self) -> bool {
64        match &self {
65            Self::Internal(internal_node) => internal_node.is_retired(),
66            Self::Leaf(leaf_node) => leaf_node.is_retired(),
67        }
68    }
69
70    /// Returns `true` if a clean is needed.
71    #[inline]
72    pub(super) fn cleanup_needed(&self) -> bool {
73        if let Self::Internal(internal_node) = &self {
74            internal_node.children.is_empty()
75        } else {
76            false
77        }
78    }
79}
80
81impl<K, V> Node<K, V>
82where
83    K: 'static + Clone + Ord,
84    V: 'static,
85{
86    /// Creates a new [`LeafNode`].
87    #[inline]
88    pub(super) fn new_leaf_node() -> Self {
89        Self::Leaf(LeafNode::new())
90    }
91
92    /// Searches for an entry containing the specified key.
93    #[inline]
94    pub(super) fn search_entry<'g, Q>(&self, key: &Q, guard: &'g Guard) -> Option<(&'g K, &'g V)>
95    where
96        K: 'g,
97        Q: Comparable<K> + ?Sized,
98    {
99        match &self {
100            Self::Internal(internal_node) => internal_node.search_entry(key, guard),
101            Self::Leaf(leaf_node) => leaf_node.search_entry(key, guard),
102        }
103    }
104
105    /// Searches for the value associated with the specified key.
106    #[inline]
107    pub(super) fn search_value<'g, Q>(&self, key: &Q, guard: &'g Guard) -> Option<&'g V>
108    where
109        K: 'g,
110        Q: Comparable<K> + ?Sized,
111    {
112        match &self {
113            Self::Internal(internal_node) => internal_node.search_value(key, guard),
114            Self::Leaf(leaf_node) => leaf_node.search_value(key, guard),
115        }
116    }
117
118    /// Reads an entry using the supplied closure.
119    #[inline]
120    pub fn read_entry<Q, R, F: FnOnce(&K, &V) -> R, P: LockPager>(
121        &self,
122        key: &Q,
123        reader: F,
124        pager: &mut P,
125        guard: &Guard,
126    ) -> Result<Option<R>, F>
127    where
128        Q: Comparable<K> + ?Sized,
129    {
130        match &self {
131            Self::Internal(internal_node) => internal_node.read_entry(key, reader, pager, guard),
132            Self::Leaf(leaf_node) => leaf_node.read_entry(key, reader, pager, guard),
133        }
134    }
135
136    /// Returns the minimum key entry in the entire tree.
137    #[inline]
138    pub(super) fn min<'g>(&self, guard: &'g Guard) -> Option<Iter<'g, K, V>> {
139        match &self {
140            Self::Internal(internal_node) => internal_node.min(guard),
141            Self::Leaf(leaf_node) => leaf_node.min(guard),
142        }
143    }
144
145    /// Returns a [`RevIter`] pointing to the right-most leaf in the entire tree.
146    #[inline]
147    pub(super) fn max<'g>(&self, guard: &'g Guard) -> Option<RevIter<'g, K, V>> {
148        match &self {
149            Self::Internal(internal_node) => internal_node.max(guard),
150            Self::Leaf(leaf_node) => leaf_node.max(guard),
151        }
152    }
153
154    /// Returns a [`Iter`] pointing to an entry that is close enough to the specified key.
155    ///
156    /// If `LE == true`, the returned [`Iter`] does not contain any keys larger than the specified
157    /// key. If not, the returned [`Iter`] does not contain any keys smaller than the specified key.
158    #[inline]
159    pub(super) fn approximate<'g, Q, const LE: bool>(
160        &self,
161        key: &Q,
162        guard: &'g Guard,
163    ) -> Option<Iter<'g, K, V>>
164    where
165        K: 'g,
166        Q: Comparable<K> + ?Sized,
167    {
168        match &self {
169            Self::Internal(internal_node) => internal_node.approximate::<_, LE>(key, guard),
170            Self::Leaf(leaf_node) => leaf_node.approximate::<_, LE>(key, guard),
171        }
172    }
173
174    /// Inserts a key-value pair.
175    #[inline]
176    pub(super) fn insert<P: LockPager, const UPSERT: bool>(
177        &self,
178        key: K,
179        val: V,
180        pager: &mut P,
181        guard: &Guard,
182    ) -> Result<InsertResult<K, V>, (K, V)> {
183        match &self {
184            Self::Internal(internal_node) => {
185                internal_node.insert::<P, UPSERT>(key, val, pager, guard)
186            }
187            Self::Leaf(leaf_node) => leaf_node.insert::<P, UPSERT>(key, val, pager, guard),
188        }
189    }
190
191    /// Removes an entry associated with the given key.
192    #[inline]
193    pub(super) fn remove_if<Q, F: FnMut(&V) -> bool, P>(
194        &self,
195        key: &Q,
196        condition: &mut F,
197        pager: &mut P,
198        guard: &Guard,
199    ) -> Result<RemoveResult, ()>
200    where
201        Q: Comparable<K> + ?Sized,
202        P: LockPager,
203    {
204        match &self {
205            Self::Internal(internal_node) => internal_node.remove_if(key, condition, pager, guard),
206            Self::Leaf(leaf_node) => leaf_node.remove_if(key, condition, pager, guard),
207        }
208    }
209
210    /// Removes a range of entries.
211    ///
212    /// Returns the number of remaining children.
213    #[inline]
214    pub(super) fn remove_range<'g, Q, R: RangeBounds<Q>, P: LockPager>(
215        &self,
216        range: &R,
217        start_unbounded: bool,
218        valid_lower_max_leaf: Option<&'g Leaf<K, V>>,
219        valid_upper_min_node: Option<&'g Node<K, V>>,
220        pager: &mut P,
221        guard: &'g Guard,
222    ) -> Result<usize, ()>
223    where
224        Q: Comparable<K> + ?Sized,
225    {
226        match &self {
227            Self::Internal(internal_node) => internal_node.remove_range(
228                range,
229                start_unbounded,
230                valid_lower_max_leaf,
231                valid_upper_min_node,
232                pager,
233                guard,
234            ),
235            Self::Leaf(leaf_node) => leaf_node.remove_range(
236                range,
237                start_unbounded,
238                valid_lower_max_leaf,
239                valid_upper_min_node,
240                pager,
241                guard,
242            ),
243        }
244    }
245
246    /// Splits the current root node.
247    pub(super) fn split_root<P: LockPager>(
248        root_ptr: RawPtr<Node<K, V>>,
249        root: &AtomicRaw<Node<K, V>>,
250        pager: &mut P,
251        guard: &Guard,
252    ) {
253        if let Some(old_root) = deref_unchecked(root_ptr) {
254            let new_root = if old_root.is_retired() {
255                Owned::new_with(Node::new_leaf_node)
256            } else {
257                let internal_node = Owned::new_with(Node::new_internal_node);
258                let Node::Internal(node) = internal_node.as_ref() else {
259                    undefined();
260                };
261                node.unbounded_child.store(root_ptr, Relaxed);
262                internal_node
263            };
264            // Updates the pointer before unlocking the root.
265            let new_root_ptr = new_root.into_raw();
266            if root
267                .compare_exchange(root_ptr, new_root_ptr, Release, Relaxed, guard)
268                .is_err()
269            {
270                if let Some(Node::Internal(new_internal_node)) =
271                    get_owned(new_root_ptr).as_ref().map(AsRef::as_ref)
272                {
273                    // Reset the pointer to prevent double-free.
274                    new_internal_node
275                        .unbounded_child
276                        .store(RawPtr::null(), Relaxed);
277                }
278            } else if let Some(Node::Internal(new_internal_node)) = deref_unchecked(new_root_ptr) {
279                let _: Result<bool, ()> = new_internal_node.split_node(
280                    root_ptr,
281                    &new_internal_node.unbounded_child,
282                    pager,
283                    guard,
284                );
285            } else {
286                drop(get_owned(root_ptr));
287            }
288        }
289    }
290
291    /// Cleans up or removes the current root node.
292    ///
293    /// If the root is empty, the root is removed from the tree, or if the root has only a single
294    /// child, the root is replaced with the child.
295    ///
296    /// Returns `false` if a conflict is detected.
297    pub(super) fn cleanup_root<P: LockPager>(
298        root: &AtomicRaw<Node<K, V>>,
299        pager: &mut P,
300        guard: &Guard,
301    ) -> bool {
302        let mut root_ptr = root.load(Acquire, guard);
303        while let Some(root_ref) = deref_unchecked(root_ptr) {
304            if root_ref.is_retired() {
305                if let Err(new_root_ptr) =
306                    root.compare_exchange(root_ptr, RawPtr::null(), AcqRel, Acquire, guard)
307                {
308                    root_ptr = new_root_ptr;
309                    continue;
310                }
311                // The entire tree was truncated.
312                drop(get_owned(root_ptr));
313                break;
314            }
315
316            // Try to lower the tree.
317            let Node::Internal(internal_node) = root_ref else {
318                break;
319            };
320
321            if !internal_node.children.is_empty() {
322                // Not empty.
323                break;
324            }
325
326            let locker = match pager.try_acquire::<false>(&internal_node.lock) {
327                Ok(true) => InternalNodeLocker {
328                    node: internal_node,
329                },
330                Ok(false) => {
331                    // The root was retired.
332                    continue;
333                }
334                Err(()) => return false,
335            };
336
337            let new_root_ptr = if internal_node.children.is_empty() {
338                // Replace the root with the unbounded child.
339                internal_node.unbounded_child.load(Acquire, guard)
340            } else {
341                // The internal node is not empty.
342                break;
343            };
344            match root.compare_exchange(root_ptr, new_root_ptr, AcqRel, Acquire, guard) {
345                Ok(_) => {
346                    internal_node.children.freeze::<true>();
347                    locker.unlock_retire();
348                    drop(get_owned(root_ptr));
349                    root_ptr = new_root_ptr;
350                    guard.accelerate();
351                }
352                Err(new_root_ptr) => {
353                    // The root node has been changed.
354                    root_ptr = new_root_ptr;
355                }
356            }
357        }
358
359        true
360    }
361}
362
363impl<K, V> fmt::Debug for Node<K, V>
364where
365    K: 'static + Clone + fmt::Debug + Ord,
366    V: 'static + fmt::Debug,
367{
368    #[inline]
369    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
370        match self {
371            Self::Internal(internal_node) => internal_node.fmt(f),
372            Self::Leaf(leaf_node) => leaf_node.fmt(f),
373        }
374    }
375}