#![allow(missing_docs)]
use crate::debug::TableEntry;
use crate::durability::Durability;
use crate::CycleError;
use crate::Database;
use crate::Query;
use crate::QueryTable;
use crate::QueryTableMut;
use crate::RuntimeId;
use crate::SweepStrategy;
use std::borrow::Borrow;
use std::fmt::Debug;
use std::hash::Hash;
pub use crate::derived::DependencyStorage;
pub use crate::derived::MemoizedStorage;
pub use crate::input::InputStorage;
pub use crate::interned::InternedStorage;
pub use crate::interned::LookupInternedStorage;
pub use crate::{revision::Revision, DatabaseKeyIndex, QueryDb, Runtime};
#[derive(Clone, Debug)]
pub struct CycleDetected {
pub(crate) from: RuntimeId,
pub(crate) to: RuntimeId,
}
pub trait DatabaseStorageTypes: Database {
type DatabaseStorage: Default;
}
pub trait DatabaseOps {
fn ops_database(&self) -> &dyn Database;
fn ops_salsa_runtime(&self) -> &Runtime;
fn ops_salsa_runtime_mut(&mut self) -> &mut Runtime;
fn fmt_index(
&self,
index: DatabaseKeyIndex,
fmt: &mut std::fmt::Formatter<'_>,
) -> std::fmt::Result;
fn maybe_changed_since(&self, input: DatabaseKeyIndex, revision: Revision) -> bool;
fn for_each_query(&self, op: &mut dyn FnMut(&dyn QueryStorageMassOps));
}
pub trait QueryStorageMassOps {
fn sweep(&self, runtime: &Runtime, strategy: SweepStrategy);
fn purge(&self);
}
pub trait DatabaseKey: Clone + Debug + Eq + Hash {}
pub trait QueryFunction: Query {
fn execute(db: &<Self as QueryDb<'_>>::DynDb, key: Self::Key) -> Self::Value;
fn recover(
db: &<Self as QueryDb<'_>>::DynDb,
cycle: &[DatabaseKeyIndex],
key: &Self::Key,
) -> Option<Self::Value> {
let _ = (db, cycle, key);
None
}
}
pub fn get_query_table<'me, Q>(db: &'me <Q as QueryDb<'me>>::DynDb) -> QueryTable<'me, Q>
where
Q: Query + 'me,
Q::Storage: QueryStorageOps<Q>,
{
let group_storage: &Q::GroupStorage = HasQueryGroup::group_storage(db);
let query_storage: &Q::Storage = Q::query_storage(group_storage);
QueryTable::new(db, query_storage)
}
pub fn get_query_table_mut<'me, Q>(db: &'me mut <Q as QueryDb<'me>>::DynDb) -> QueryTableMut<'me, Q>
where
Q: Query,
{
let group_storage: &Q::GroupStorage = HasQueryGroup::group_storage(db);
let query_storage = Q::query_storage(group_storage).clone();
QueryTableMut::new(db, query_storage)
}
pub trait QueryGroup: Sized {
type GroupStorage;
type DynDb: ?Sized + Database + HasQueryGroup<Self>;
}
pub trait HasQueryGroup<G>: Database
where
G: QueryGroup,
{
fn group_storage(&self) -> &G::GroupStorage;
}
pub trait QueryStorageOps<Q>
where
Self: QueryStorageMassOps,
Q: Query,
{
fn new(group_index: u16) -> Self;
fn fmt_index(
&self,
db: &<Q as QueryDb<'_>>::DynDb,
index: DatabaseKeyIndex,
fmt: &mut std::fmt::Formatter<'_>,
) -> std::fmt::Result;
fn maybe_changed_since(
&self,
db: &<Q as QueryDb<'_>>::DynDb,
input: DatabaseKeyIndex,
revision: Revision,
) -> bool;
fn try_fetch(
&self,
db: &<Q as QueryDb<'_>>::DynDb,
key: &Q::Key,
) -> Result<Q::Value, CycleError<DatabaseKeyIndex>>;
fn durability(&self, db: &<Q as QueryDb<'_>>::DynDb, key: &Q::Key) -> Durability;
fn entries<C>(&self, db: &<Q as QueryDb<'_>>::DynDb) -> C
where
C: std::iter::FromIterator<TableEntry<Q::Key, Q::Value>>;
}
pub trait InputQueryStorageOps<Q>
where
Q: Query,
{
fn set(
&self,
db: &mut <Q as QueryDb<'_>>::DynDb,
key: &Q::Key,
new_value: Q::Value,
durability: Durability,
);
}
pub trait LruQueryStorageOps {
fn set_lru_capacity(&self, new_capacity: usize);
}
pub trait DerivedQueryStorageOps<Q>
where
Q: Query,
{
fn invalidate<S>(&self, db: &mut <Q as QueryDb<'_>>::DynDb, key: &S)
where
S: Eq + Hash,
Q::Key: Borrow<S>;
}