pub mod error;
mod kvdb;
mod mem;
pub use crate::kvdb::as_database;
#[cfg(feature = "rocksdb")]
pub use crate::kvdb::as_rocksdb_database;
pub use mem::MemDb;
pub type ColumnId = u32;
#[derive(Clone)]
pub enum Change<H> {
Set(ColumnId, Vec<u8>, Vec<u8>),
Remove(ColumnId, Vec<u8>),
Store(ColumnId, H, Vec<u8>),
Reference(ColumnId, H),
Release(ColumnId, H),
}
#[derive(Default, Clone)]
pub struct Transaction<H>(pub Vec<Change<H>>);
impl<H> Transaction<H> {
pub fn new() -> Self {
Transaction(Vec::new())
}
pub fn set(&mut self, col: ColumnId, key: &[u8], value: &[u8]) {
self.0.push(Change::Set(col, key.to_vec(), value.to_vec()))
}
pub fn set_from_vec(&mut self, col: ColumnId, key: &[u8], value: Vec<u8>) {
self.0.push(Change::Set(col, key.to_vec(), value))
}
pub fn remove(&mut self, col: ColumnId, key: &[u8]) {
self.0.push(Change::Remove(col, key.to_vec()))
}
pub fn store(&mut self, col: ColumnId, hash: H, preimage: Vec<u8>) {
self.0.push(Change::Store(col, hash, preimage))
}
pub fn reference(&mut self, col: ColumnId, hash: H) {
self.0.push(Change::Reference(col, hash))
}
pub fn release(&mut self, col: ColumnId, hash: H) {
self.0.push(Change::Release(col, hash))
}
}
pub trait Database<H: Clone + AsRef<[u8]>>: Send + Sync {
fn commit(&self, transaction: Transaction<H>) -> error::Result<()>;
fn get(&self, col: ColumnId, key: &[u8]) -> Option<Vec<u8>>;
fn contains(&self, col: ColumnId, key: &[u8]) -> bool {
self.get(col, key).is_some()
}
fn value_size(&self, col: ColumnId, key: &[u8]) -> Option<usize> {
self.get(col, key).map(|v| v.len())
}
fn with_get(&self, col: ColumnId, key: &[u8], f: &mut dyn FnMut(&[u8])) {
if let Some(v) = self.get(col, key) {
f(&v)
}
}
fn supports_ref_counting(&self) -> bool {
false
}
fn sanitize_key(&self, _key: &mut Vec<u8>) {}
fn optimize_db_col(&self, _col: ColumnId) -> error::Result<()> {
Ok(())
}
}
impl<H> std::fmt::Debug for dyn Database<H> {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
write!(f, "Database")
}
}
pub fn with_get<R, H: Clone + AsRef<[u8]>>(
db: &dyn Database<H>,
col: ColumnId,
key: &[u8],
mut f: impl FnMut(&[u8]) -> R,
) -> Option<R> {
let mut result: Option<R> = None;
let mut adapter = |k: &_| {
result = Some(f(k));
};
db.with_get(col, key, &mut adapter);
result
}