Skip to main content

arctic/raw/iter/
range.rs

1use core::cmp;
2use core::fmt::Debug;
3use core::marker::PhantomData;
4use core::ops::ControlFlow;
5use core::ops::RangeFrom;
6use core::ops::RangeFull;
7use core::ops::RangeInclusive;
8use core::ops::RangeToInclusive;
9use core::ptr::NonNull;
10use core::sync::atomic::Ordering;
11
12#[cfg_attr(not(doc), expect(unused))]
13use crate::ConcurrentMap;
14#[cfg_attr(not(doc), expect(unused))]
15use crate::SequentialMap;
16use crate::raw;
17use crate::raw::Edge;
18use crate::raw::edge;
19use crate::raw::edge::Meta as _;
20use crate::raw::iter::Order;
21use crate::raw::key;
22use crate::raw::key::Len as _;
23use crate::raw::node::Lower as _;
24use crate::raw::node::Upper as _;
25use crate::sync::Atomic;
26
27pub(crate) enum RangeIter<'g, K: key::Read, W: key::Write<K>, R: Range<K>> {
28    Root {
29        writer: W,
30        #[expect(clippy::type_complexity)]
31        next: Option<(u64, NonNull<Atomic<Edge<K::Edge>>>)>,
32    },
33    Node(NodeIter<'g, K, W, R>),
34}
35
36impl<'g, K, W, R> Default for RangeIter<'g, K, W, R>
37where
38    K: key::Read,
39    W: key::Write<K>,
40    R: Range<K>,
41{
42    fn default() -> Self {
43        Self::Root {
44            writer: W::default(),
45            next: None,
46        }
47    }
48}
49
50impl<'g, K, W, R> RangeIter<'g, K, W, R>
51where
52    K: key::Read,
53    W: key::Write<K>,
54    R: Range<K>,
55{
56    pub(crate) unsafe fn new_unchecked(
57        root: *mut Atomic<Edge<K::Edge>>,
58        edge: ribbit::Packed<Edge<K::Edge>>,
59        prefix: K,
60        order: Option<Order>,
61        range: &R,
62    ) -> Self {
63        let Some((root, child)) = NonNull::new(root).zip(edge.child()) else {
64            return Self::default();
65        };
66
67        let meta = edge.meta();
68        let len = prefix.len();
69        let mut lower = range.lower(len);
70        let mut upper = range.upper(len);
71
72        let Some((lower_byte, upper_byte)) = lower.check(meta).zip(upper.check(meta)) else {
73            return Self::default();
74        };
75
76        let (writer, len) = W::new(prefix, meta);
77
78        match child {
79            edge::Child::Value(value) => Self::Root {
80                writer,
81                next: Some((value, root)),
82            },
83            edge::Child::Node(node) => {
84                let mut stack = Vec::with_capacity(7);
85                stack.push((len, lower_byte, upper_byte, unsafe {
86                    node.entries(order.is_some(), lower_byte, upper_byte)
87                }));
88
89                Self::Node(NodeIter {
90                    order,
91                    lower,
92                    upper,
93                    writer,
94                    stack,
95                })
96            }
97        }
98    }
99
100    #[inline]
101    pub(crate) fn try_fold<F, B, C>(self, init: C, mut apply: F) -> ControlFlow<B, C>
102    where
103        F: FnMut(C, (&W, u64, NonNull<Atomic<Edge<K::Edge>>>)) -> ControlFlow<B, C>,
104    {
105        match self {
106            RangeIter::Root { writer, mut next } => {
107                if let Some((value, edge)) = next.take() {
108                    apply(init, (&writer, value, edge))
109                } else {
110                    ControlFlow::Continue(init)
111                }
112            }
113            RangeIter::Node(mut iter) => iter.try_fold(init, apply),
114        }
115    }
116
117    #[inline]
118    #[expect(clippy::type_complexity)]
119    pub(crate) fn lend(&mut self) -> Option<(&W, u64, NonNull<Atomic<Edge<K::Edge>>>)> {
120        match self {
121            RangeIter::Root { writer, next } => {
122                crate::cold();
123                let (value, edge) = next.take()?;
124                Some((writer, value, edge))
125            }
126            RangeIter::Node(iter) => iter.lend(),
127        }
128    }
129}
130
131pub(crate) struct NodeIter<'g, K, W, R>
132where
133    K: key::Read,
134    W: key::Write<K>,
135    R: Range<K>,
136{
137    order: Option<Order>,
138    lower: R::Lower,
139    upper: R::Upper,
140    writer: W,
141    #[expect(clippy::type_complexity)]
142    stack: Vec<(
143        W::Len,
144        <R::Lower as Lower<K::Edge>>::Bound,
145        <R::Upper as Upper<K::Edge>>::Bound,
146        raw::node::EntryIter<'g>,
147    )>,
148}
149
150impl<'g, K, W, R> NodeIter<'g, K, W, R>
151where
152    K: key::Read,
153    R: Range<K>,
154    W: key::Write<K>,
155{
156    #[inline]
157    #[expect(clippy::type_complexity)]
158    fn lend(&mut self) -> Option<(&W, u64, NonNull<Atomic<Edge<K::Edge>>>)> {
159        let next = match self.try_fold(None, |init, (_, value, edge)| {
160            validate!(init.is_none());
161            ControlFlow::Break((value, edge))
162        }) {
163            ControlFlow::Break((value, edge)) => Some((value, edge)),
164            ControlFlow::Continue(init) => {
165                validate!(init.is_none());
166                init
167            }
168        };
169
170        next.map(|(value, edge)| (&self.writer, value, edge))
171    }
172
173    // Imagine `self.lower` and `self.upper` defining a triangular subtree of
174    // the entire tree:
175    //
176    // ```text
177    //        /\
178    //       // \
179    //      / \  \
180    //     /  /   \
181    //    /  /\    \
182    //   /  /xx\    \
183    //  /  /xxxx\    \
184    // /  /xxxxxx\    \
185    // ```
186    //
187    // We only need to compare against the bounds on the exterior edges of this
188    // triangle; everything in the interior is included in the range, and everything
189    // in the exterior is excluded.
190    fn try_fold<F, B, C>(&mut self, mut init: C, mut apply: F) -> ControlFlow<B, C>
191    where
192        F: FnMut(C, (&W, u64, NonNull<Atomic<Edge<K::Edge>>>)) -> ControlFlow<B, C>,
193    {
194        'vertical: loop {
195            let Some((len, lower, upper, iter)) = self.stack.last_mut() else {
196                return ControlFlow::Continue(init);
197            };
198
199            'horizontal: loop {
200                let next = match self.order {
201                    None | Some(Order::Ascend) => iter.next(),
202                    Some(Order::Descend) => iter.next_back(),
203                };
204
205                let Some((mut byte, mut edge)) = next else {
206                    self.stack.pop();
207                    continue 'vertical;
208                };
209
210                let mut len = *len;
211                let mut lower = *lower;
212                let mut upper = *upper;
213
214                'flatten: loop {
215                    let (meta, child) = {
216                        let edge = unsafe { edge.cast::<Atomic<Edge<K::Edge>>>().as_ref() }
217                            .load_packed(Ordering::Relaxed);
218                        let Some(child) = edge.child() else {
219                            continue 'horizontal;
220                        };
221                        let meta = edge.meta();
222                        (meta, child)
223                    };
224
225                    lower = if lower.check(byte) {
226                        // Exterior edge, check against bound
227                        match self.lower.check(meta) {
228                            Some(lower) => lower,
229                            // Below lower bound, descending order
230                            None if matches!(self.order, Some(Order::Descend)) => {
231                                self.stack.clear();
232                                return ControlFlow::Continue(init);
233                            }
234                            // Below lower bound, ascending order
235                            None => continue 'horizontal,
236                        }
237                    } else {
238                        // Interior edge
239                        Default::default()
240                    };
241
242                    upper = if upper.check(byte) {
243                        // Exterior edge, check against bound
244                        match self.upper.check(meta) {
245                            Some(upper) => upper,
246                            // Above upper bound, descending order
247                            None if matches!(self.order, Some(Order::Descend)) => {
248                                continue 'horizontal;
249                            }
250                            // Above upper bound, ascending order
251                            None => {
252                                self.stack.clear();
253                                return ControlFlow::Continue(init);
254                            }
255                        }
256                    } else {
257                        // Interior edge
258                        Default::default()
259                    };
260
261                    len = self.writer.replace(len, byte, meta);
262
263                    match child {
264                        edge::Child::Value(value) => {
265                            init = apply(init, (&self.writer, value, edge.cast()))?;
266                            continue 'horizontal;
267                        }
268                        edge::Child::Node(node) => {
269                            // Synchronizes with release compare_exchanges in
270                            // `concurrent::Map::upsert_with_raw` and `raw::Cursor::freeze`.
271                            crate::sync::atomic::fence(Ordering::Acquire);
272
273                            // Avoid pushing and popping node iterators with only one child
274                            match unsafe {
275                                node.entry_or_entries(self.order.is_some(), lower, upper)
276                            } {
277                                Ok((next_byte, next_edge)) => {
278                                    byte = next_byte;
279                                    edge = next_edge;
280                                    continue 'flatten;
281                                }
282                                Err(iter) => {
283                                    self.stack.push((len, lower, upper, iter));
284                                    continue 'vertical;
285                                }
286                            }
287                        }
288                    }
289                }
290            }
291        }
292    }
293}
294
295#[derive(Copy, Clone, Debug)]
296pub struct Include<T>(pub(crate) T);
297
298pub struct Unbound<T = ()>(PhantomData<T>);
299
300impl<T> Copy for Unbound<T> {}
301
302impl<T> Clone for Unbound<T> {
303    fn clone(&self) -> Self {
304        *self
305    }
306}
307
308impl<T> Default for Unbound<T> {
309    #[inline]
310    fn default() -> Self {
311        Self(PhantomData)
312    }
313}
314
315impl<T> Debug for Unbound<T> {
316    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> std::fmt::Result {
317        write!(f, "Unbound")
318    }
319}
320
321/// Native range types (`..`, `lower..`, `..=upper`, `lower..=upper`) that can be passed as bounds to
322/// [`SequentialMap::range`] and [`ConcurrentMap::range`].
323///
324/// Currently, only [`RangeFull`], [`RangeFrom`], [`RangeToInclusive`], and [`RangeInclusive`] are supported.
325/// [`Range`][std::ops::Range] (with an exclusive upper bound) is not supported.
326/// The following types can be used as range bounds:
327/// - Borrowed keys ([`&'_ Key::Borrowed`][crate::Key::Borrowed]),
328/// - Slices (`&'_ [u8]`)
329/// - Array references (`&'_ [u8; 5]`)
330/// - For integer keys, owned integers (`u64`)
331#[expect(private_bounds)]
332pub trait Range<R>
333where
334    R: key::Read,
335{
336    #[doc(hidden)]
337    #[expect(private_bounds)]
338    type Lower: Lower<R::Edge>;
339
340    #[doc(hidden)]
341    #[expect(private_bounds)]
342    type Upper: Upper<R::Edge>;
343
344    #[doc(hidden)]
345    #[expect(private_interfaces)]
346    fn lower(&self, start: R::Len) -> Self::Lower;
347
348    #[doc(hidden)]
349    #[expect(private_interfaces)]
350    fn upper(&self, start: R::Len) -> Self::Upper;
351
352    #[doc(hidden)]
353    #[inline]
354    fn common_prefix(&self) -> R {
355        R::default()
356    }
357}
358
359impl<R: key::Read, T: Into<R> + Copy> Range<R> for RangeInclusive<T> {
360    type Lower = Include<R>;
361    type Upper = Include<R>;
362
363    #[inline]
364    #[expect(private_interfaces)]
365    fn lower(&self, start: R::Len) -> Self::Lower {
366        Include((*self.start()).into().suffix(start))
367    }
368
369    #[inline]
370    #[expect(private_interfaces)]
371    fn upper(&self, start: R::Len) -> Self::Upper {
372        Include((*self.end()).into().suffix(start))
373    }
374
375    #[inline]
376    fn common_prefix(&self) -> R {
377        let lower = (*self.start()).into();
378        let upper = (*self.end()).into();
379        lower.common_prefix(upper)
380    }
381}
382
383impl<R: key::Read, T: Into<R> + Copy> Range<R> for RangeFrom<T> {
384    type Lower = Include<R>;
385    type Upper = Unbound<R>;
386
387    #[inline]
388    #[expect(private_interfaces)]
389    fn lower(&self, start: R::Len) -> Self::Lower {
390        Include(self.start.into().suffix(start))
391    }
392
393    #[inline]
394    #[expect(private_interfaces)]
395    fn upper(&self, _start: R::Len) -> Self::Upper {
396        Unbound::default()
397    }
398}
399
400impl<R: key::Read, T: Into<R> + Copy> Range<R> for RangeToInclusive<T> {
401    type Lower = Unbound<R>;
402    type Upper = Include<R>;
403
404    #[inline]
405    #[expect(private_interfaces)]
406    fn lower(&self, _start: R::Len) -> Self::Lower {
407        Unbound::default()
408    }
409
410    #[inline]
411    #[expect(private_interfaces)]
412    fn upper(&self, start: R::Len) -> Self::Upper {
413        Include(self.end.into().suffix(start))
414    }
415}
416
417impl<R> Range<R> for RangeFull
418where
419    R: key::Read,
420{
421    type Lower = Unbound<R>;
422    type Upper = Unbound<R>;
423
424    #[inline]
425    #[expect(private_interfaces)]
426    fn lower(&self, _: R::Len) -> Self::Lower {
427        Unbound::default()
428    }
429
430    #[inline]
431    #[expect(private_interfaces)]
432    fn upper(&self, _: R::Len) -> Self::Upper {
433        Unbound::default()
434    }
435}
436
437trait Lower<M>: Debug
438where
439    M: ribbit::Pack<Packed: edge::Meta>,
440{
441    type Bound: raw::node::Lower;
442
443    fn check(&mut self, edge: ribbit::Packed<M>) -> Option<Self::Bound>;
444}
445
446trait Upper<M>: Debug
447where
448    M: ribbit::Pack<Packed: edge::Meta>,
449{
450    type Bound: raw::node::Upper;
451
452    fn check(&mut self, edge: ribbit::Packed<M>) -> Option<Self::Bound>;
453}
454
455#[expect(private_bounds)]
456impl<R: key::Read> Include<R> {
457    #[inline]
458    fn check_eq(&mut self, len: <ribbit::Packed<R::Edge> as edge::Meta>::Len) -> Option<u8> {
459        let next = self.0.get_byte(len);
460        let skip = match next {
461            None => R::Len::ZERO,
462            Some(_) => R::Len::BYTE,
463        };
464        self.0 = self.0.suffix(skip + len.into());
465        next
466    }
467}
468
469impl<R: key::Read> Lower<R::Edge> for Include<R> {
470    type Bound = Option<u8>;
471
472    fn check(&mut self, edge: ribbit::Packed<R::Edge>) -> Option<Self::Bound> {
473        let len = edge.len();
474        match edge.cmp(&self.0.get_edge(len)) {
475            cmp::Ordering::Less => None,
476            cmp::Ordering::Equal => Some(self.check_eq(len)),
477            cmp::Ordering::Greater => Some(None),
478        }
479    }
480}
481
482impl<R: key::Read> Upper<R::Edge> for Include<R> {
483    type Bound = Option<u8>;
484
485    fn check(&mut self, edge: ribbit::Packed<R::Edge>) -> Option<Self::Bound> {
486        let len = edge.len();
487        match edge.cmp(&self.0.get_edge(len)) {
488            cmp::Ordering::Less => Some(None),
489            cmp::Ordering::Equal => Some(self.check_eq(len)),
490            cmp::Ordering::Greater => None,
491        }
492    }
493}
494
495impl<R: key::Read> Lower<R::Edge> for Unbound<R> {
496    type Bound = Unbound<R>;
497
498    #[inline]
499    fn check(&mut self, _: ribbit::Packed<R::Edge>) -> Option<Self::Bound> {
500        Some(Unbound::default())
501    }
502}
503
504impl<R: key::Read> Upper<R::Edge> for Unbound<R> {
505    type Bound = Unbound<R>;
506
507    #[inline]
508    fn check(&mut self, _: ribbit::Packed<R::Edge>) -> Option<Self::Bound> {
509        Some(Unbound::default())
510    }
511}