pipecircuit 0.0.24

Correct. Robust. Fast. Portable. Pick four.
Documentation
use super::{
    SlotSet,
    membership::{Chunk, Membership},
};
use crate::storage::{
    membership::{BucketMembership, MembershipChunks},
    query_workspace::chunk::read::ChunkRead,
};
use core::slice;

#[derive(Clone, Copy)]
pub(in crate::storage::warp_table) enum SlotSetRead<'a> {
    Empty,
    Owned(&'a SlotSet),
    Indexed(BucketMembership<'a>),
}
#[allow(
    clippy::large_enum_variant,
    reason = "borrowed index traversal retains its bounded stacks without allocation"
)]
pub(in crate::storage::warp_table) enum Chunks<'a> {
    Empty,
    Owned(slice::Iter<'a, Chunk>),
    Indexed(MembershipChunks<'a>),
}
impl<'a> Iterator for Chunks<'a> {
    type Item = (u16, ChunkRead<'a>);
    fn next(&mut self) -> Option<Self::Item> {
        match self {
            Self::Empty => None,
            Self::Owned(chunks) => chunks.next().map(|chunk| (chunk.high, chunk.read())),
            Self::Indexed(chunks) => chunks.next().map(|(high, chunk)| (high, chunk.0)),
        }
    }
}
impl DoubleEndedIterator for Chunks<'_> {
    fn next_back(&mut self) -> Option<Self::Item> {
        match self {
            Self::Empty => None,
            Self::Owned(chunks) => chunks.next_back().map(|chunk| (chunk.high, chunk.read())),
            Self::Indexed(chunks) => chunks.next_back().map(|(high, chunk)| (high, chunk.0)),
        }
    }
}
impl<'a> SlotSetRead<'a> {
    pub(in crate::storage::warp_table) fn chunks(self) -> Chunks<'a> {
        match self {
            Self::Empty => Chunks::Empty,
            Self::Owned(set) => Chunks::Owned(set.0.chunks.iter()),
            Self::Indexed(members) => Chunks::Indexed(members.chunks()),
        }
    }
    pub(in crate::storage::warp_table) fn len(self) -> u64 {
        match self {
            Self::Empty => 0,
            Self::Owned(set) => set.len(),
            Self::Indexed(members) => members.len() as u64,
        }
    }
    pub(in crate::storage::warp_table) fn slots(self) -> super::SlotSetSlots<'a> {
        super::lookup::read_slots(self)
    }
    pub(in crate::storage::warp_table) fn is_subset(self, other: Self) -> bool {
        if self.len() > other.len() {
            return false;
        }
        let mut right = other.chunks().peekable();
        self.chunks().all(|(high, left)| {
            while right.peek().is_some_and(|(key, _)| *key < high) {
                right.next();
            }
            let other = right
                .next_if(|(key, _)| *key == high)
                .map_or(ChunkRead::EMPTY, |(_, chunk)| chunk);
            left.is_subset(other)
        })
    }
    pub(in crate::storage::warp_table) fn is_disjoint(self, other: Self) -> bool {
        let mut right = other.chunks().peekable();
        self.chunks().all(|(high, left)| {
            while right.peek().is_some_and(|(key, _)| *key < high) {
                right.next();
            }
            let other = right
                .next_if(|(key, _)| *key == high)
                .map_or(ChunkRead::EMPTY, |(_, chunk)| chunk);
            left.is_disjoint(other)
        })
    }
}
impl SlotSet {
    pub(in crate::storage::warp_table) const fn read(&self) -> SlotSetRead<'_> {
        SlotSetRead::Owned(self)
    }
    pub(in crate::storage::warp_table) fn from_read(source: SlotSetRead<'_>) -> Self {
        Self(Membership {
            len: source.len(),
            chunks: source
                .chunks()
                .map(|(high, read)| Chunk::from_read(high, read))
                .collect(),
        })
    }
}