mapuche_embedded/
lib.rs

1pub mod cmd;
2pub mod frame;
3
4mod config;
5mod db;
6mod rocks;
7mod utils;
8
9use cmd::{Command, Gc};
10
11use db::DBInner;
12use frame::Frame;
13use std::{path::Path, sync::Arc, time::Duration};
14use tokio::{
15    spawn,
16    time::{interval, MissedTickBehavior},
17};
18
19/// Error returned by most functions.
20pub type Error = Box<dyn std::error::Error + Send + Sync>;
21
22/// A specialized `Result` type for mapuche operations.
23///
24/// This is defined as a convenience.
25pub type Result<T> = anyhow::Result<T, Error>;
26
27/// Options to open the DB.
28///
29/// Mostly about gc maters.
30#[derive(Clone)]
31pub struct OpenOptions {
32    pub(crate) gc_enabled: bool,
33    pub(crate) gc_interval: u64,
34}
35
36impl OpenOptions {
37    pub fn new() -> Self {
38        Self::default()
39    }
40
41    /// Set if enable gc. Default is false.
42    pub fn gc_enable(mut self, value: bool) -> Self {
43        self.gc_enabled = value;
44        self
45    }
46
47    /// Set the interval of gc. Default is 10s.
48    pub fn gc_interval(mut self, value: u64) -> Self {
49        self.gc_interval = value;
50        self
51    }
52
53    /// Open the db with a given path.
54    /// It will create or open the fold in path which provide rocksdb storage.
55    pub async fn open<P: AsRef<Path>>(self, path: P) -> Result<DB> {
56        let inner = DBInner::open(path, self.gc_enabled).await?;
57        let inner = Arc::new(inner);
58        Ok(DB { inner })
59    }
60}
61
62impl Default for OpenOptions {
63    fn default() -> Self {
64        Self {
65            gc_enabled: false,
66            gc_interval: u64::MAX,
67        }
68    }
69}
70
71#[derive(Clone)]
72pub struct DB {
73    pub(crate) inner: Arc<DBInner>,
74}
75
76impl DB {
77    pub async fn open<P: AsRef<Path>>(
78        path: P,
79        async_deletion_enabled: bool,
80        gc_interval: u64,
81    ) -> Result<Self> {
82        let db = OpenOptions::new().open(path).await?;
83        let cloned = db.clone();
84        if async_deletion_enabled {
85            spawn(async move {
86                let mut interval = interval(Duration::from_millis(gc_interval));
87                interval.set_missed_tick_behavior(MissedTickBehavior::Delay);
88                loop {
89                    interval.tick().await;
90                    let conn = cloned.conn();
91                    let cmd = Command::Gc(Gc::new());
92                    let _ = conn.execute(cmd).await;
93                }
94            });
95        }
96
97        Ok(db)
98    }
99
100    pub fn conn(&self) -> Conn {
101        Conn {
102            inner: self.inner.clone(),
103        }
104    }
105}
106
107pub struct Conn {
108    pub(crate) inner: Arc<DBInner>,
109}
110
111impl Conn {
112    pub async fn execute(&self, cmd: Command) -> crate::Result<Frame> {
113        cmd.execute(&self.inner).await
114    }
115}