pipecircuit 0.0.13

Correct. Robust. Fast. Portable.
Documentation
use super::{SecondaryIndex, SecondaryIndexInconsistency};
use crate::storage::warp_table::IndexKey;
use crate::storage::warp_table::dense_key_index::FindOutcome;
use crate::storage::warp_table::inconsistency::invariant_violation;
use crate::storage::warp_table::secondary_index::SlotSet;

#[doc(hidden)]
#[must_use]
pub struct SecondaryIndexMembership<'index, SecondaryKey> {
    secondary_key: SecondaryKey,
    slots: Option<&'index SlotSet>,
}

impl<'index, SecondaryKey> SecondaryIndexMembership<'index, SecondaryKey> {
    pub(in crate::storage::warp_table) fn into_parts(
        self,
    ) -> (SecondaryKey, Option<&'index SlotSet>) {
        (self.secondary_key, self.slots)
    }

    #[cfg(test)]
    pub(crate) const fn secondary_key(&self) -> &SecondaryKey {
        &self.secondary_key
    }

    #[cfg(test)]
    pub(crate) const fn slots(&self) -> Option<&'index SlotSet> {
        self.slots
    }
}

impl<SecondaryKey: IndexKey> SecondaryIndex<SecondaryKey> {
    pub fn find(&self, secondary_key: SecondaryKey) -> SecondaryIndexMembership<'_, SecondaryKey> {
        if self.secondary_keys.len() != self.slot_sets.len() {
            invariant_violation(SecondaryIndexInconsistency::KeySlotSetLengthMismatch {
                secondary_keys: self.secondary_keys.len(),
                slot_sets: self.slot_sets.len(),
            });
        }
        match self
            .secondary_key_index
            .find(secondary_key, &self.secondary_keys)
        {
            Ok(FindOutcome::Present { row, .. }) => {
                let slot_set = self.slot_sets.get(row).unwrap_or_else(|| {
                    invariant_violation(SecondaryIndexInconsistency::SlotSetUnavailable { row })
                });
                SecondaryIndexMembership {
                    secondary_key,
                    slots: Some(slot_set),
                }
            }
            Ok(FindOutcome::Absent) => SecondaryIndexMembership {
                secondary_key,
                slots: None,
            },
            Err(reason) => invariant_violation(SecondaryIndexInconsistency::from(reason)),
        }
    }
}