stack_db/default/
alloc.rs1use std::{fs::{self, File}, io::Cursor, path::{Path, PathBuf}};
4use crate::{base::{database::allocator::Allocator, layer::Layer}, errors::Error};
5
6pub struct SkdbMemAlloc;
10impl<'a> Allocator<'a> for SkdbMemAlloc {
11 type LayerStream = Cursor<Vec<u8>>;
12 #[inline]
13 fn load_layers(&self) -> Result<Vec<Layer<'a, Self::LayerStream>>, Error> {
14 Ok(Vec::new())
15 }
16 #[inline]
17 fn add_layer(&mut self) -> Result<Layer<'a, Self::LayerStream>, Error> {
18 Ok(Layer::new(Cursor::new(Vec::new())))
19 }
20 #[inline]
21 fn drop_top_layer(&mut self) -> Result<(), Error> {
22 Ok(())
23 }
24 #[inline]
25 fn rebase(&mut self, _: usize) -> Result<(), Error> {
26 Ok(())
27 }
28}
29
30pub struct SkdbDirAlloc {
34 pub path: PathBuf,
36 pub layers: Vec<PathBuf>,
38 pub cursor: u32,
39}
40impl SkdbDirAlloc {
41 pub fn new(path: impl AsRef<Path>) -> Result<Self, Error> {
43 let path = path.as_ref();
44
45 fs::create_dir_all(path)?;
46 Ok(Self {
47 path: path.to_path_buf(),
48 layers: Vec::new(),
49 cursor: 0,
50 })
51 }
52
53 pub fn load(path: impl AsRef<Path>) -> Result<Self, Error> {
55 let mut file_paths = Vec::new();
57 for entry in fs::read_dir(&path)? {
58 let entry = entry?;
59 if entry.file_type()?.is_file() {
60 file_paths.push(entry.path());
61 }
62 }
63
64 let mut layers = file_paths.iter()
66 .enumerate()
67 .filter_map(|(i, file)| file.file_name().map(|x| (x.to_string_lossy(), i)))
68 .filter_map(|(name, i)| name.parse::<u32>().ok().map(|x| (x, i)))
69 .collect::<Vec<(u32, usize)>>();
70 layers.sort_unstable_by_key(|x| x.0);
71
72 let cursor = layers.last().map(|x| x.0 + 1).unwrap_or(0);
73 let layers = layers.into_iter()
74 .map(|(_, i)| std::mem::take(&mut file_paths[i]))
75 .collect::<Vec<_>>();
76
77 Ok(Self {
79 path: path.as_ref().to_path_buf(),
80 layers,
81 cursor,
82 })
83 }
84}
85impl<'a> Allocator<'a> for SkdbDirAlloc {
86 type LayerStream = File;
87
88 fn load_layers(&self) -> Result<Vec<Layer<'a, Self::LayerStream>>, Error> {
90 let mut layers = Vec::with_capacity(self.layers.len());
91 for path in self.layers.iter() {
92 let file = File::options()
93 .read(true)
94 .write(true)
95 .append(false)
96 .truncate(false)
97 .open(path)?;
98 layers.push(Layer::load(file)?);
99 } Ok(layers)
100 }
101
102 fn add_layer(&mut self) -> Result<Layer<'a, Self::LayerStream>, Error> {
103 let path = self.path.join(self.cursor.to_string());
104 let file = File::options()
105 .read(true)
106 .write(true)
107 .append(false)
108 .truncate(false)
109 .create_new(true)
110 .open(&path)?;
111 self.cursor += 1;
112 self.layers.push(path);
113 Ok(Layer::new(file))
114 }
115
116 fn drop_top_layer(&mut self) -> Result<(), Error> {
117 let path = if let Some(x) = self.layers.pop() { x } else { return Ok(()) };
118 self.cursor -= 1;
119 fs::remove_file(path)?;
120
121 Ok(())
122 }
123
124 fn rebase(&mut self, top_layer: usize) -> Result<(), Error> {
125 let mut top = Vec::with_capacity(self.layers.len()-top_layer);
126 top.extend(self.layers.drain(top_layer..));
127
128 for path in self.layers.iter() {
130 fs::remove_file(path)?;
131 }
132
133 self.layers.clear();
135 for (i, path) in top.into_iter().enumerate() {
136 let new_path = self.path.join(i.to_string());
137 fs::rename(path, &new_path)?;
138 self.layers.push(new_path);
139 } Ok(())
140 }
141}