use crate::{DB,Tree,Storage,Point,Value,Error,RA,Debugger};
use async_std::{sync::{Arc,Mutex},channel::{unbounded,Sender}};
#[cfg(not(feature="wasm"))] use async_std::task::spawn;
#[cfg(feature="wasm")] use async_std::task::{spawn_local as spawn};
#[derive(Clone)]
pub struct SetupFields {
pub branch_factor: usize,
pub max_depth: usize,
pub max_records: usize,
pub max_tree_bytes: usize,
pub ext_records: usize,
pub inline: usize,
pub inline_max_bytes: usize,
pub tree_cache_size: usize,
pub rebuild_depth: usize,
pub debug: Option<Sender<String>>,
}
impl std::fmt::Debug for SetupFields {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("SetupFields")
.field("branch_factor", &self.branch_factor)
.field("max_depth", &self.max_depth)
.field("max_records", &self.max_records)
.field("max_tree_bytes", &self.max_tree_bytes)
.field("ext_records", &self.ext_records)
.field("inline", &self.inline)
.field("inline_max_bytes", &self.inline_max_bytes)
.field("tree_cache_size", &self.tree_cache_size)
.field("rebuild_depth", &self.rebuild_depth)
.field("debug", &format_args!["{}", match &self.debug {
Some(_) => "[enabled]",
None => "[not enabled]",
}])
.finish()
}
}
impl SetupFields {
pub fn default() -> Self {
Self {
branch_factor: 6,
max_depth: 8,
max_records: 20_000,
max_tree_bytes: 1_000_000,
ext_records: 5_000,
inline: 50,
inline_max_bytes: 20_000,
tree_cache_size: 1000,
rebuild_depth: 2,
debug: None,
}
}
pub async fn log(&self, msg: &str) -> Result<(),Error> {
if let Some(d) = &self.debug {
d.send(msg.into()).await?;
}
Ok(())
}
}
#[derive(Clone)]
pub struct Setup<S> where S: RA {
pub storage: Arc<Mutex<Box<dyn Storage<S>>>>,
pub fields: SetupFields
}
impl<S> Setup<S> where S: RA {
pub fn from_storage(storage: Box<dyn Storage<S>>) -> Self {
Self {
storage: Arc::new(Mutex::new(storage)),
fields: SetupFields::default()
}
}
pub fn branch_factor(mut self, bf: usize) -> Self {
self.fields.branch_factor = bf;
self
}
pub fn max_depth(mut self, md: usize) -> Self {
self.fields.max_depth = md;
self
}
pub fn max_records(mut self, mr: usize) -> Self {
self.fields.max_records = mr;
self
}
pub fn max_tree_bytes(mut self, mtb: usize) -> Self {
self.fields.max_tree_bytes = mtb;
self
}
pub fn ext_records(mut self, er: usize) -> Self {
self.fields.ext_records = er;
self
}
pub fn inline(mut self, n: usize) -> Self {
self.fields.inline = n;
self
}
pub fn inline_max_bytes(mut self, n: usize) -> Self {
self.fields.inline_max_bytes = n;
self
}
pub fn tree_cache_size(mut self, n: usize) -> Self {
self.fields.tree_cache_size = n;
self
}
pub fn rebuild_depth(mut self, n: usize) -> Self {
self.fields.rebuild_depth = n;
self
}
pub fn debug(mut self, d: impl Debugger+Send+Sync+'static) -> Self {
let debug = Arc::new(Mutex::new(d));
let (sender,receiver) = unbounded();
spawn(async move {
while let Ok(r) = receiver.recv().await {
let s: String = r;
debug.lock().await.send(&s);
}
});
self.fields.debug = Some(sender);
self
}
pub async fn build<T,P,V> (self) -> Result<DB<S,T,P,V>,Error>
where P: Point, V: Value, T: Tree<P,V> {
DB::open_from_setup(self).await
}
}