use crate::db::commit::marker::CommitIndexOp;
use crate::db::{
data::{CanonicalRow, DataStore, RawDataKey},
index::{IndexStore, RawIndexEntry, RawIndexKey},
};
use std::{cell::RefCell, thread::LocalKey};
#[derive(Clone)]
pub(crate) struct PreparedIndexMutation {
pub(crate) store: &'static LocalKey<RefCell<IndexStore>>,
pub(crate) key: RawIndexKey,
pub(crate) value: Option<RawIndexEntry>,
pub(crate) delta_kind: PreparedIndexDeltaKind,
}
impl From<CommitIndexOp> for PreparedIndexMutation {
fn from(value: CommitIndexOp) -> Self {
Self {
store: value.store,
key: value.key,
value: value.value,
delta_kind: value.delta_kind,
}
}
}
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub(crate) enum PreparedIndexDeltaKind {
None,
IndexInsert,
IndexRemove,
ReverseIndexInsert,
ReverseIndexRemove,
}
impl PreparedIndexDeltaKind {
#[must_use]
pub(crate) const fn from_reverse_index_membership(
old_contains: bool,
new_contains: bool,
) -> Self {
match (old_contains, new_contains) {
(true, false) => Self::ReverseIndexRemove,
(false, true) => Self::ReverseIndexInsert,
_ => Self::None,
}
}
#[must_use]
pub(crate) const fn counter_increments(self) -> (usize, usize, usize, usize) {
match self {
Self::None => (0, 0, 0, 0),
Self::IndexInsert => (1, 0, 0, 0),
Self::IndexRemove => (0, 1, 0, 0),
Self::ReverseIndexInsert => (0, 0, 1, 0),
Self::ReverseIndexRemove => (0, 0, 0, 1),
}
}
}
#[cfg(test)]
mod tests {
use crate::db::commit::PreparedIndexDeltaKind;
#[test]
fn reverse_index_membership_maps_to_expected_delta_kind() {
assert_eq!(
PreparedIndexDeltaKind::from_reverse_index_membership(true, false),
PreparedIndexDeltaKind::ReverseIndexRemove,
);
assert_eq!(
PreparedIndexDeltaKind::from_reverse_index_membership(false, true),
PreparedIndexDeltaKind::ReverseIndexInsert,
);
assert_eq!(
PreparedIndexDeltaKind::from_reverse_index_membership(false, false),
PreparedIndexDeltaKind::None,
);
assert_eq!(
PreparedIndexDeltaKind::from_reverse_index_membership(true, true),
PreparedIndexDeltaKind::None,
);
}
#[test]
fn delta_kind_counter_increments_match_index_variants() {
assert_eq!(
PreparedIndexDeltaKind::IndexInsert.counter_increments(),
(1, 0, 0, 0),
);
assert_eq!(
PreparedIndexDeltaKind::IndexRemove.counter_increments(),
(0, 1, 0, 0),
);
}
#[test]
fn delta_kind_counter_increments_match_reverse_index_variants() {
assert_eq!(
PreparedIndexDeltaKind::ReverseIndexInsert.counter_increments(),
(0, 0, 1, 0),
);
assert_eq!(
PreparedIndexDeltaKind::ReverseIndexRemove.counter_increments(),
(0, 0, 0, 1),
);
assert_eq!(
PreparedIndexDeltaKind::None.counter_increments(),
(0, 0, 0, 0)
);
}
}
#[derive(Clone)]
pub(in crate::db) struct PreparedRowCommitOp {
pub(crate) index_ops: Vec<PreparedIndexMutation>,
pub(crate) data_store: &'static LocalKey<RefCell<DataStore>>,
pub(crate) data_key: RawDataKey,
pub(crate) data_value: Option<CanonicalRow>,
}