mirror of
https://github.com/serai-dex/serai.git
synced 2025-12-08 12:19:24 +00:00
Document serai-db with bounds and intent
This commit is contained in:
376
Cargo.lock
generated
376
Cargo.lock
generated
File diff suppressed because it is too large
Load Diff
@@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "serai-db"
|
name = "serai-db"
|
||||||
version = "0.1.0"
|
version = "0.1.1"
|
||||||
description = "A simple database trait and backends for it"
|
description = "A simple database trait and backends for it"
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
repository = "https://github.com/serai-dex/serai/tree/develop/common/db"
|
repository = "https://github.com/serai-dex/serai/tree/develop/common/db"
|
||||||
@@ -18,7 +18,7 @@ workspace = true
|
|||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
parity-db = { version = "0.4", default-features = false, optional = true }
|
parity-db = { version = "0.4", default-features = false, optional = true }
|
||||||
rocksdb = { version = "0.21", default-features = false, features = ["zstd"], optional = true }
|
rocksdb = { version = "0.23", default-features = false, features = ["zstd"], optional = true }
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
parity-db = ["dep:parity-db"]
|
parity-db = ["dep:parity-db"]
|
||||||
|
|||||||
8
common/db/README.md
Normal file
8
common/db/README.md
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
# Serai DB
|
||||||
|
|
||||||
|
An inefficient, minimal abstraction around databases.
|
||||||
|
|
||||||
|
The abstraction offers `get`, `put`, and `del` with helper functions and macros
|
||||||
|
built on top. Database iteration is not offered, forcing the caller to manually
|
||||||
|
implement indexing schemes. This ensures wide compatibility across abstracted
|
||||||
|
databases.
|
||||||
@@ -14,26 +14,43 @@ mod parity_db;
|
|||||||
#[cfg(feature = "parity-db")]
|
#[cfg(feature = "parity-db")]
|
||||||
pub use parity_db::{ParityDb, new_parity_db};
|
pub use parity_db::{ParityDb, new_parity_db};
|
||||||
|
|
||||||
/// An object implementing get.
|
/// An object implementing `get`.
|
||||||
pub trait Get {
|
pub trait Get {
|
||||||
|
/// Get a value from the database.
|
||||||
fn get(&self, key: impl AsRef<[u8]>) -> Option<Vec<u8>>;
|
fn get(&self, key: impl AsRef<[u8]>) -> Option<Vec<u8>>;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// An atomic database operation.
|
/// An atomic database transaction.
|
||||||
|
///
|
||||||
|
/// A transaction is only required to atomically commit. It is not required that two `Get` calls
|
||||||
|
/// made with the same transaction return the same result, if another transaction wrote to that
|
||||||
|
/// key.
|
||||||
|
///
|
||||||
|
/// If two transactions are created, and both write (including deletions) to the same key, behavior
|
||||||
|
/// is undefined. The transaction may block, deadlock, panic, overwrite one of the two values
|
||||||
|
/// randomly, or any other action, at time of write or at time of commit.
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub trait DbTxn: Send + Get {
|
pub trait DbTxn: Send + Get {
|
||||||
|
/// Write a value to this key.
|
||||||
fn put(&mut self, key: impl AsRef<[u8]>, value: impl AsRef<[u8]>);
|
fn put(&mut self, key: impl AsRef<[u8]>, value: impl AsRef<[u8]>);
|
||||||
|
/// Delete the value from this key.
|
||||||
fn del(&mut self, key: impl AsRef<[u8]>);
|
fn del(&mut self, key: impl AsRef<[u8]>);
|
||||||
|
/// Commit this transaction.
|
||||||
fn commit(self);
|
fn commit(self);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A database supporting atomic operations.
|
/// A database supporting atomic transaction.
|
||||||
pub trait Db: 'static + Send + Sync + Clone + Get {
|
pub trait Db: 'static + Send + Sync + Clone + Get {
|
||||||
|
/// The type representing a database transaction.
|
||||||
type Transaction<'a>: DbTxn;
|
type Transaction<'a>: DbTxn;
|
||||||
|
/// Calculate a key for a database entry.
|
||||||
|
///
|
||||||
|
/// Keys are separated by the database, the item within the database, and the item's key itself.
|
||||||
fn key(db_dst: &'static [u8], item_dst: &'static [u8], key: impl AsRef<[u8]>) -> Vec<u8> {
|
fn key(db_dst: &'static [u8], item_dst: &'static [u8], key: impl AsRef<[u8]>) -> Vec<u8> {
|
||||||
let db_len = u8::try_from(db_dst.len()).unwrap();
|
let db_len = u8::try_from(db_dst.len()).unwrap();
|
||||||
let dst_len = u8::try_from(item_dst.len()).unwrap();
|
let dst_len = u8::try_from(item_dst.len()).unwrap();
|
||||||
[[db_len].as_ref(), db_dst, [dst_len].as_ref(), item_dst, key.as_ref()].concat()
|
[[db_len].as_ref(), db_dst, [dst_len].as_ref(), item_dst, key.as_ref()].concat()
|
||||||
}
|
}
|
||||||
|
/// Open a new transaction.
|
||||||
fn txn(&mut self) -> Self::Transaction<'_>;
|
fn txn(&mut self) -> Self::Transaction<'_>;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ use crate::*;
|
|||||||
#[derive(PartialEq, Eq, Debug)]
|
#[derive(PartialEq, Eq, Debug)]
|
||||||
pub struct MemDbTxn<'a>(&'a MemDb, HashMap<Vec<u8>, Vec<u8>>, HashSet<Vec<u8>>);
|
pub struct MemDbTxn<'a>(&'a MemDb, HashMap<Vec<u8>, Vec<u8>>, HashSet<Vec<u8>>);
|
||||||
|
|
||||||
impl<'a> Get for MemDbTxn<'a> {
|
impl Get for MemDbTxn<'_> {
|
||||||
fn get(&self, key: impl AsRef<[u8]>) -> Option<Vec<u8>> {
|
fn get(&self, key: impl AsRef<[u8]>) -> Option<Vec<u8>> {
|
||||||
if self.2.contains(key.as_ref()) {
|
if self.2.contains(key.as_ref()) {
|
||||||
return None;
|
return None;
|
||||||
@@ -23,7 +23,7 @@ impl<'a> Get for MemDbTxn<'a> {
|
|||||||
.or_else(|| self.0 .0.read().unwrap().get(key.as_ref()).cloned())
|
.or_else(|| self.0 .0.read().unwrap().get(key.as_ref()).cloned())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl<'a> DbTxn for MemDbTxn<'a> {
|
impl DbTxn for MemDbTxn<'_> {
|
||||||
fn put(&mut self, key: impl AsRef<[u8]>, value: impl AsRef<[u8]>) {
|
fn put(&mut self, key: impl AsRef<[u8]>, value: impl AsRef<[u8]>) {
|
||||||
self.2.remove(key.as_ref());
|
self.2.remove(key.as_ref());
|
||||||
self.1.insert(key.as_ref().to_vec(), value.as_ref().to_vec());
|
self.1.insert(key.as_ref().to_vec(), value.as_ref().to_vec());
|
||||||
|
|||||||
Reference in New Issue
Block a user