highlandcows_isam/
storage.rs

1/// `IsamStorage<K, V>` — the raw I/O state for an ISAM database.
2///
3/// This is the inner state shared behind an `Arc<Mutex<>>`.  It is never
4/// exposed publicly; callers interact with it only through `Transaction`.
5use std::marker::PhantomData;
6use std::path::{Path, PathBuf};
7
8use serde::de::DeserializeOwned;
9use serde::Serialize;
10
11use crate::error::IsamResult;
12use crate::index::BTree;
13use crate::isam::{idb_path, idx_path};
14use crate::secondary_index::AnySecondaryIndex;
15use crate::store::DataStore;
16
17pub(crate) struct IsamStorage<K, V> {
18    pub(crate) store: DataStore,
19    pub(crate) index: BTree<K>,
20    pub(crate) base_path: PathBuf,
21    pub(crate) secondary_indices: Vec<Box<dyn AnySecondaryIndex<K, V>>>,
22    pub(crate) _phantom: PhantomData<V>,
23}
24
25impl<K, V> IsamStorage<K, V>
26where
27    K: Serialize + DeserializeOwned + Ord + Clone,
28    V: Serialize + DeserializeOwned,
29{
30    pub(crate) fn create(path: &Path) -> IsamResult<Self> {
31        let base = path.to_path_buf();
32        Ok(Self {
33            store: DataStore::create(&idb_path(&base))?,
34            index: BTree::create(&idx_path(&base))?,
35            base_path: base,
36            secondary_indices: Vec::new(),
37            _phantom: PhantomData,
38        })
39    }
40
41    pub(crate) fn open(path: &Path) -> IsamResult<Self> {
42        let base = path.to_path_buf();
43        Ok(Self {
44            store: DataStore::open(&idb_path(&base))?,
45            index: BTree::open(&idx_path(&base))?,
46            base_path: base,
47            secondary_indices: Vec::new(),
48            _phantom: PhantomData,
49        })
50    }
51
52    /// Flush store, index, and all secondary indices to disk (called at commit).
53    pub(crate) fn fsync(&mut self) -> IsamResult<()> {
54        self.store.fsync()?;
55        self.index.fsync()?;
56        for si in &mut self.secondary_indices {
57            si.fsync()?;
58        }
59        Ok(())
60    }
61}