arctic-wt 0.1.5

Lock-free adaptive radix tree
Documentation
use core::marker::PhantomData;
use core::ops::RangeFull;
use core::sync::atomic::Ordering;

use crate::raw;
use crate::raw::Cursor;
use crate::raw::Edge;
use crate::raw::Key;
use crate::raw::cursor::path;
use crate::raw::iter::EntryIter;
use crate::raw::iter::Order;
use crate::raw::iter::Range;
use crate::raw::iter::RangeIter;
use crate::raw::iter::ValueIter;
use crate::raw::key::Read as _;
use crate::sync::Atomic;

pub(crate) struct Shard<'g, 'k, K, R = RangeFull>
where
    K: Key,
{
    root: *mut Atomic<Edge<K::Edge>>,
    edge: ribbit::Packed<Edge<K::Edge>>,
    prefix: K::Read<'k>,
    range: R,
    _global: PhantomData<&'g Atomic<Edge<K::Edge>>>,
}

impl<'g, 'k, K, R> Shard<'g, 'k, K, R>
where
    K: Key,
    R: raw::iter::Range<K::Read<'k>>,
{
    #[inline]
    pub(crate) unsafe fn new_all(root: &'g Atomic<Edge<K::Edge>>) -> Shard<'g, 'k, K, RangeFull> {
        let edge = root.load_packed(Ordering::Relaxed);
        unsafe { Shard::new(root as *const _ as *mut _, edge, K::Read::default(), ..) }
    }

    pub(crate) unsafe fn new_prefix(
        root: &'g Atomic<Edge<K::Edge>>,
        prefix: K::Read<'k>,
    ) -> Shard<'g, 'k, K, RangeFull> {
        let mut cursor = unsafe { Cursor::<_, path::Len<_>>::new(root, prefix) };
        let Some(edge) = cursor.traverse_prefix() else {
            return unsafe { Shard::new(core::ptr::null_mut(), Edge::NULL, prefix, ..) };
        };
        let len = cursor.len();
        let prefix = prefix.prefix(len);
        unsafe { Shard::new(cursor.edge() as *const _ as *mut _, edge, prefix, ..) }
    }

    pub(crate) unsafe fn new_range(
        root: &'g Atomic<Edge<K::Edge>>,
        range: R,
        prefix: K::Read<'k>,
    ) -> Shard<'g, 'k, K, R>
    where
        R: Range<K::Read<'k>>,
    {
        validate_eq!(prefix, range.common_prefix());
        let mut cursor = unsafe { Cursor::<_, path::Len<_>>::new(root, prefix) };
        let Some(edge) = cursor.traverse_prefix() else {
            return unsafe { Shard::new(core::ptr::null_mut(), Edge::NULL, prefix, range) };
        };
        let len = cursor.len();
        let prefix = prefix.prefix(len);
        unsafe { Shard::new(cursor.edge() as *const _ as *mut _, edge, prefix, range) }
    }

    #[inline]
    unsafe fn new(
        root: *mut Atomic<Edge<K::Edge>>,
        edge: ribbit::Packed<Edge<K::Edge>>,
        prefix: K::Read<'k>,
        range: R,
    ) -> Shard<'g, 'k, K, R> {
        Shard {
            root,
            edge,
            prefix,
            range,
            _global: PhantomData,
        }
    }

    #[inline]
    pub(crate) fn entries(&self, order: Option<Order>) -> EntryIter<'g, 'k, K, R> {
        EntryIter(unsafe {
            RangeIter::new_unchecked(self.root, self.edge, self.prefix, order, &self.range)
        })
    }

    #[inline]
    pub(crate) fn values(&self, order: Option<Order>) -> ValueIter<'g, 'k, K, R> {
        ValueIter(unsafe {
            RangeIter::new_unchecked(self.root, self.edge, self.prefix, order, &self.range)
        })
    }
}