pipecircuit 0.0.2

Correct. Robust. Fast. Portable.
Documentation
use super::dense_key_index::FindOutcome;
use super::inconsistency::invariant_violation;
use super::{WarpTable, WarpTableInconsistency, WarpTableRow, WarpTableRowGetOutcome};

#[derive(Clone, Copy, Debug, Eq, PartialEq)]
#[must_use]
pub enum WarpTableGetOutcome<Key, Row> {
    Present { row: Row },
    Absent { key: Key },
}

#[derive(Clone, Copy, Debug, Eq, PartialEq)]
#[must_use]
pub enum WarpTableGetAtOutcome<Row> {
    Present { dense_row: usize, row: Row },
    Absent { dense_row: usize },
}

impl<Row: WarpTableRow, Brand> WarpTable<Row, Brand> {
    pub fn get(&self, key: Row::Key) -> WarpTableGetOutcome<Row::Key, Row::Ref<'_>> {
        let keys = &self.primary_keys;
        if keys.len() != self.len {
            invariant_violation(WarpTableInconsistency::PrimaryKeyColumnLengthMismatch {
                keys: keys.len(),
                rows: self.len,
            });
        }
        let found = self
            .primary_index
            .find(key, keys)
            .unwrap_or_else(|reason| invariant_violation(WarpTableInconsistency::from(reason)));
        let row = match found {
            FindOutcome::Present { row, .. } => row,
            FindOutcome::Absent => return WarpTableGetOutcome::Absent { key },
        };
        let stored_key = keys.get(row).unwrap_or_else(|| {
            invariant_violation(WarpTableInconsistency::PrimaryKeyUnavailable { row })
        });
        let WarpTableRowGetOutcome::Present { row } = Row::get(stored_key, &self.columns, row)
            .unwrap_or_else(|reason| invariant_violation(WarpTableInconsistency::from(reason)));
        WarpTableGetOutcome::Present { row }
    }

    /// Reads the current physical row at `dense_row`.
    ///
    /// Dense rows may relocate after removal. Persistent identity should use a
    /// primary key; secondary selections resolve their opaque membership
    /// immediately before access.
    pub fn get_at(&self, dense_row: usize) -> WarpTableGetAtOutcome<Row::Ref<'_>> {
        let keys = &self.primary_keys;
        if keys.len() != self.len {
            invariant_violation(WarpTableInconsistency::PrimaryKeyColumnLengthMismatch {
                keys: keys.len(),
                rows: self.len,
            });
        }
        if dense_row >= self.len {
            return WarpTableGetAtOutcome::Absent { dense_row };
        }
        let key = keys.get(dense_row).unwrap_or_else(|| {
            invariant_violation(WarpTableInconsistency::PrimaryKeyUnavailable { row: dense_row })
        });
        let WarpTableRowGetOutcome::Present { row } = Row::get(key, &self.columns, dense_row)
            .unwrap_or_else(|reason| invariant_violation(WarpTableInconsistency::from(reason)));
        WarpTableGetAtOutcome::Present { dense_row, row }
    }
}