use super::rows::SelectionRows;
use super::rows::StableSlotResolver;
use crate::storage::warp_table::secondary_index::SlotSet;
use crate::storage::warp_table::{WarpTable, WarpTableRow};
pub(super) enum SelectionMembership<'table> {
Empty,
Borrowed(&'table SlotSet),
Owned(SlotSet),
}
#[must_use]
pub struct Selection<'table, Row: WarpTableRow, Brand = Row> {
pub(super) table: &'table WarpTable<Row, Brand>,
pub(super) membership: SelectionMembership<'table>,
}
impl<'table, Row: WarpTableRow, Brand> Selection<'table, Row, Brand> {
pub(super) const fn empty(table: &'table WarpTable<Row, Brand>) -> Self {
Self {
table,
membership: SelectionMembership::Empty,
}
}
pub(super) const fn borrowed(
table: &'table WarpTable<Row, Brand>,
slots: &'table SlotSet,
) -> Self {
Self {
table,
membership: SelectionMembership::Borrowed(slots),
}
}
pub(super) const fn owned(table: &'table WarpTable<Row, Brand>, slots: SlotSet) -> Self {
Self {
table,
membership: SelectionMembership::Owned(slots),
}
}
pub fn len(&self) -> u64 {
match &self.membership {
SelectionMembership::Empty => 0,
SelectionMembership::Borrowed(slots) => slots.len(),
SelectionMembership::Owned(slots) => slots.len(),
}
}
pub fn is_empty(&self) -> bool {
self.len() == 0
}
pub(crate) fn belongs_to(&self, table: &WarpTable<Row, Brand>) -> bool {
core::ptr::eq(self.table, table)
}
pub fn ids(self) -> impl Iterator<Item = Row::Id> + 'table
where
Row::Indexes: super::rows::StableSlotResolver,
{
let slots = super::rows::SelectionSlotIter::from(self.membership);
let table = self.table;
slots.map(move |slot| {
let super::super::secondary_index::StableSlotResolveOutcome::Resolved {
dense_row, ..
} = match table.__indexes().resolve_stable_slot(slot) {
Ok(resolution) => resolution,
Err(reason) => super::super::inconsistency::invariant_violation(reason),
};
match table.ids().get(dense_row) {
Some(id) => *id,
None => {
super::super::inconsistency::invariant_violation("selected identity missing")
}
}
})
}
pub fn rows(self) -> SelectionRows<'table, Row, Brand>
where
Row::Indexes: super::rows::StableSlotResolver,
{
SelectionRows::new(self.table, self.membership)
}
}