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)),
}
}
}