use std::collections::BTreeMap;
use uqa_core::DocId;
use uqa_sql::SQLError;
use uqa_storage::mvcc::ObservedIdentifier;
use crate::mutation::{prepared::PreparedInsertConflict, publication::MutationStorage};
#[derive(Default)]
pub struct SuppliedIdentities {
greatest: BTreeMap<String, DocId>,
}
impl SuppliedIdentities {
pub fn note(&mut self, table: &str, prepared: &PreparedInsertConflict) {
let PreparedInsertConflict::Insert {
doc_id,
supplied: true,
} = prepared
else {
return;
};
match self.greatest.get_mut(table) {
Some(greatest) => *greatest = (*greatest).max(*doc_id),
None => {
self.greatest.insert(table.to_owned(), *doc_id);
}
}
}
pub fn observe(self, storage: &dyn MutationStorage) -> Result<ObservedIdentities, SQLError> {
let mut observed = BTreeMap::new();
for (table, doc_id) in self.greatest {
let found = storage.observe_document_identity(&table, doc_id)?;
observed.insert(table, found);
}
Ok(ObservedIdentities { observed })
}
}
#[derive(Default)]
pub struct ObservedIdentities {
observed: BTreeMap<String, ObservedIdentifier>,
}
impl ObservedIdentities {
#[cfg(test)]
pub(super) fn found(
observed: impl IntoIterator<Item = (&'static str, ObservedIdentifier)>,
) -> Self {
Self {
observed: observed
.into_iter()
.map(|(table, found)| (table.to_owned(), found))
.collect(),
}
}
pub fn unused(&self, table: &str, doc_id: DocId) -> bool {
self.observed
.get(table)
.is_some_and(|observed| observed.unused_before(doc_id))
}
}
#[cfg(test)]
mod tests;