brk_vec/traits/
generic.rs1use std::{
2 fs::{File, OpenOptions},
3 io::{self, Seek, SeekFrom, Write},
4 path::{Path, PathBuf},
5 sync::Arc,
6 time::{self, Duration},
7};
8
9use arc_swap::ArcSwap;
10use brk_core::{Result, Value};
11use memmap2::Mmap;
12
13use super::{StoredIndex, StoredType};
14
15pub trait GenericStoredVec<I, T>: Send + Sync
16where
17 I: StoredIndex,
18 T: StoredType,
19{
20 const SIZE_OF_T: usize = size_of::<T>();
21
22 #[inline]
23 fn read(&self, index: I, mmap: &Mmap) -> Result<Option<T>> {
24 self.read_(index.to_usize()?, mmap)
25 }
26 fn read_(&self, index: usize, mmap: &Mmap) -> Result<Option<T>>;
27
28 #[inline]
29 fn get_or_read(&self, index: I, mmap: &Mmap) -> Result<Option<Value<T>>> {
30 self.get_or_read_(index.to_usize()?, mmap)
31 }
32 #[inline]
33 fn get_or_read_(&self, index: usize, mmap: &Mmap) -> Result<Option<Value<T>>> {
34 let stored_len = mmap.len() / Self::SIZE_OF_T;
35
36 if index >= stored_len {
37 let pushed = self.pushed();
38 let j = index - stored_len;
39 if j >= pushed.len() {
40 return Ok(None);
41 }
42 Ok(pushed.get(j).map(Value::Ref))
43 } else {
44 Ok(self.read_(index, mmap)?.map(Value::Owned))
45 }
46 }
47
48 #[inline]
49 fn len_(&self) -> usize {
50 self.stored_len() + self.pushed_len()
51 }
52
53 fn mmap(&self) -> &ArcSwap<Mmap>;
54
55 fn stored_len(&self) -> usize;
56
57 fn pushed(&self) -> &[T];
58 #[inline]
59 fn pushed_len(&self) -> usize {
60 self.pushed().len()
61 }
62 fn mut_pushed(&mut self) -> &mut Vec<T>;
63 #[inline]
64 fn push(&mut self, value: T) {
65 self.mut_pushed().push(value)
66 }
67
68 fn path(&self) -> &Path;
69
70 fn open_file(&self) -> io::Result<File> {
73 Self::open_file_(&self.path_vec())
74 }
75 fn open_file_(path: &Path) -> io::Result<File> {
76 OpenOptions::new()
77 .read(true)
78 .create(true)
79 .truncate(false)
80 .append(true)
81 .open(path)
82 }
83
84 fn file_set_len(&mut self, len: u64) -> Result<()> {
85 let mut file = self.open_file()?;
86 Self::file_set_len_(&mut file, len)?;
87 self.update_mmap(file)
88 }
89 fn file_set_len_(file: &mut File, len: u64) -> Result<()> {
90 file.set_len(len)?;
91 file.seek(SeekFrom::End(0))?;
92 Ok(())
93 }
94
95 fn file_write_all(&mut self, buf: &[u8]) -> Result<()> {
96 let mut file = self.open_file()?;
97 file.write_all(buf)?;
98 self.update_mmap(file)
99 }
100
101 fn file_truncate_and_write_all(&mut self, len: u64, buf: &[u8]) -> Result<()> {
102 let mut file = self.open_file()?;
103 Self::file_set_len_(&mut file, len)?;
104 file.write_all(buf)?;
105 self.update_mmap(file)
106 }
107
108 #[inline]
109 fn reset(&mut self) -> Result<()> {
110 self.file_truncate_and_write_all(0, &[])
111 }
112
113 fn new_mmap(file: File) -> Result<Arc<Mmap>> {
114 Ok(Arc::new(unsafe { Mmap::map(&file)? }))
115 }
116
117 fn update_mmap(&mut self, file: File) -> Result<()> {
118 let mmap = Self::new_mmap(file)?;
119 self.mmap().store(mmap);
120 Ok(())
121 }
122
123 #[inline]
124 fn is_pushed_empty(&self) -> bool {
125 self.pushed_len() == 0
126 }
127
128 #[inline]
129 fn has(&self, index: I) -> Result<bool> {
130 Ok(self.has_(index.to_usize()?))
131 }
132 #[inline]
133 fn has_(&self, index: usize) -> bool {
134 index < self.len_()
135 }
136
137 fn flush(&mut self) -> Result<()>;
138
139 fn truncate_if_needed(&mut self, index: I) -> Result<()>;
140
141 #[inline]
142 fn path_vec(&self) -> PathBuf {
143 Self::path_vec_(self.path())
144 }
145 #[inline]
146 fn path_vec_(path: &Path) -> PathBuf {
147 path.join("vec")
148 }
149
150 #[inline]
151 fn path_version_(path: &Path) -> PathBuf {
152 path.join("version")
153 }
154
155 #[inline]
156 fn path_compressed_(path: &Path) -> PathBuf {
157 path.join("compressed")
158 }
159
160 #[inline]
161 fn name_(&self) -> String {
162 self.path()
163 .file_name()
164 .unwrap()
165 .to_str()
166 .unwrap()
167 .to_owned()
168 }
169
170 fn modified_time_(&self) -> Result<Duration> {
171 Ok(self
172 .path_vec()
173 .metadata()?
174 .modified()?
175 .duration_since(time::UNIX_EPOCH)?)
176 }
177}