o3 0.36.0

shared-nothing primitives
Documentation
use std::mem;

use crate::{
    buffer,
    buffer::{
        segments,
        segments::{
            Chain, Handle, Key,
            chain::{view, view::iter::Iter},
            handles::{self, Occupied},
        },
    },
    depot::arena::linked::{self, slots},
};

impl<T, H: Handle<T>> Chain<T, H> {
    pub fn clear(&mut self) {
        let key = mem::replace(&mut self.key, Key::EMPTY);
        Self::release(&self.handle, &key);
    }

    fn release(handle: &H, key: &Key) {
        let nodes = handles::nodes(handle);
        let index = match key.state() {
            None => return,
            Some(Occupied::Single(index)) => {
                // SAFETY: this detached key retains its exact initialized node.
                drop(unsafe { nodes.detached(index) });
                return;
            }
            Some(Occupied::Multi(index)) => index,
        };
        let descs = handles::descriptors(handle);
        // SAFETY: this detached multi key uniquely owns its exact descriptor.
        let (mut desc, retired) = unsafe { descs.detached(index) }.take();
        // SAFETY: the descriptor owns this exact tracked node-store partition.
        unsafe { desc.links.clear(nodes) };
        retired.release();
    }
}

impl<T, H: Handle<T>> Drop for Chain<T, H> {
    fn drop(&mut self) {
        Self::release(&self.handle, &self.key);
    }
}

impl<T: buffer::raw::Segment, H: Handle<T>> Chain<T, H> {
    pub(in crate::buffer::segments) fn state(&self) -> view::State<'_, T> {
        if self.key.is_empty() {
            return view::State::Empty;
        }
        // SAFETY: this unchanged owner has a nonempty key.
        match unsafe { self.occupied() } {
            view::Occupied::Single(index, item) => view::State::Single(index, item),
            view::Occupied::Multi(desc) => view::State::Multi(desc),
        }
    }

    /// # Safety
    /// This unchanged sequence owns a nonempty chain.
    pub(in crate::buffer::segments) unsafe fn occupied(&self) -> view::Occupied<'_, T> {
        // SAFETY: the caller's nonempty owner proof excludes the empty key.
        match unsafe { self.key.occupied() } {
            handles::Occupied::Single(index) => {
                // SAFETY: this shared owner retains its exact initialized single node.
                let node = unsafe { handles::nodes(&self.handle).value(index) };
                view::Occupied::Single(index, node)
            }
            handles::Occupied::Multi(index) => {
                // SAFETY: this shared owner retains its exact initialized descriptor.
                let desc = unsafe { handles::descriptors(&self.handle).value(index) };
                view::Occupied::Multi(desc)
            }
        }
    }
    pub(in crate::buffer::segments) fn totals(&self) -> (segments::Count, usize, usize) {
        match self.state() {
            view::State::Empty => (segments::Count::EMPTY, 0, 0),
            view::State::Single(_, item) => (
                segments::Count::ONE,
                item.len().get(),
                buffer::Residency::resident(item),
            ),
            view::State::Multi(desc) => (
                segments::Count::new(desc.count.get()),
                desc.len,
                desc.resident_bytes,
            ),
        }
    }

    pub fn len(&self) -> usize {
        match self.state() {
            view::State::Empty => 0,
            view::State::Single(_, item) => item.len().get(),
            view::State::Multi(desc) => desc.len,
        }
    }

    pub fn is_empty(&self) -> bool {
        self.key.is_empty()
    }

    pub fn count(&self) -> segments::Count {
        match self.state() {
            view::State::Empty => segments::Count::EMPTY,
            view::State::Single(_, _) => segments::Count::ONE,
            view::State::Multi(desc) => segments::Count::new(desc.count.get()),
        }
    }

    pub fn resident(&self) -> usize {
        match self.state() {
            view::State::Empty => 0,
            view::State::Single(_, item) => buffer::Residency::resident(item),
            view::State::Multi(desc) => desc.resident_bytes,
        }
    }

    pub fn segments(&self) -> Iter<'_, T> {
        let (head, left) = match self.state() {
            view::State::Empty => (slots::Index::NONE, segments::Count::EMPTY),
            view::State::Single(index, _) => (index, segments::Count::ONE),
            view::State::Multi(desc) => (
                desc.links.head_raw(),
                segments::Count::new(desc.count.get()),
            ),
        };
        // SAFETY: this sequence borrow retains the exact immutable live chain.
        let cursor = unsafe { linked::Iter::new(handles::nodes(&self.handle), head) };
        Iter::new(cursor, left)
    }

    pub fn contiguous(&self) -> Option<&[u8]> {
        match self.state() {
            view::State::Empty => Some(&[]),
            view::State::Single(_, item) => Some(item.as_ref().as_ref()),
            view::State::Multi(_) => None,
        }
    }

    pub(in crate::buffer::segments) fn is_same(&self, other: &Self) -> bool {
        self.handle.is_same(&other.handle)
    }
}