vsdb/basic/vecx/
mod.rs

1//!
2//! A disk-based, `Vec`-like data structure.
3//!
4//! `Vecx` provides a vector-like interface for storing a sequence of values on disk.
5//! Values are encoded using `serde`-like methods, allowing for the storage of
6//! complex data types.
7//!
8//! # Examples
9//!
10//! ```
11//! use vsdb::{Vecx, vsdb_set_base_dir, vsdb_get_base_dir};
12//! use std::fs;
13//!
14//! // It's recommended to use a temporary directory for testing
15//! let dir = format!("/tmp/vsdb_testing/{}", rand::random::<u128>());
16//! vsdb_set_base_dir(&dir).unwrap();
17//!
18//! let mut v: Vecx<String> = Vecx::new();
19//!
20//! // Push values
21//! v.push(&"hello".to_string());
22//! v.push(&"world".to_string());
23//!
24//! // Check the length
25//! assert_eq!(v.len(), 2);
26//!
27//! // Get a value by index
28//! assert_eq!(v.get(0), Some("hello".to_string()));
29//!
30//! // Iterate over the values
31//! for value in v.iter() {
32//!     println!("{}", value);
33//! }
34//!
35//! // Pop a value
36//! assert_eq!(v.pop(), Some("world".to_string()));
37//! assert_eq!(v.len(), 1);
38//!
39//! // Clear the vector
40//! v.clear();
41//! assert_eq!(v.len(), 0);
42//!
43//! // Clean up the directory
44//! fs::remove_dir_all(vsdb_get_base_dir()).unwrap();
45//! ```
46
47#[cfg(test)]
48mod test;
49
50use crate::{
51    basic::mapx_ord_rawkey::{
52        MapxOrdRawKey, MapxOrdRawKeyIter, MapxOrdRawKeyIterMut, ValueIterMut, ValueMut,
53    },
54    common::ende::ValueEnDe,
55};
56use ruc::*;
57use serde::{Deserialize, Serialize};
58use std::{borrow::Cow, cmp::Ordering};
59
60/// A disk-based, `Vec`-like data structure with typed values.
61///
62/// `Vecx` stores a sequence of values on disk, encoding them for persistence.
63#[derive(Serialize, Deserialize, PartialEq, Eq, Debug)]
64#[serde(bound = "")]
65pub struct Vecx<T> {
66    inner: MapxOrdRawKey<T>,
67}
68
69impl<T: ValueEnDe> Vecx<T> {
70    /// Creates a "shadow" copy of the `Vecx` instance.
71    ///
72    /// # Safety
73    ///
74    /// This API breaks Rust's semantic safety guarantees. Use only in a race-free environment.
75    #[inline(always)]
76    pub unsafe fn shadow(&self) -> Self {
77        unsafe {
78            Self {
79                inner: self.inner.shadow(),
80            }
81        }
82    }
83
84    /// Creates a `Vecx` from a byte slice.
85    ///
86    /// # Safety
87    ///
88    /// This function is unsafe and assumes the byte slice is a valid representation.
89    #[inline(always)]
90    pub unsafe fn from_bytes(s: impl AsRef<[u8]>) -> Self {
91        unsafe {
92            Self {
93                inner: MapxOrdRawKey::from_bytes(s),
94            }
95        }
96    }
97
98    /// Returns the byte representation of the `Vecx`.
99    #[inline(always)]
100    pub fn as_bytes(&self) -> &[u8] {
101        self.inner.as_bytes()
102    }
103
104    /// Creates a new, empty `Vecx`.
105    #[inline(always)]
106    pub fn new() -> Self {
107        Vecx {
108            inner: MapxOrdRawKey::new(),
109        }
110    }
111
112    /// Retrieves a value at a specific index.
113    #[inline(always)]
114    pub fn get(&self, idx: usize) -> Option<T> {
115        self.inner.get((idx as u64).to_be_bytes())
116    }
117
118    /// Retrieves a mutable reference to a value at a specific index.
119    #[inline(always)]
120    pub fn get_mut(&mut self, idx: usize) -> Option<ValueMut<'_, T>> {
121        self.inner.get_mut((idx as u64).to_be_bytes())
122    }
123
124    /// Retrieves the last value in the vector.
125    #[inline(always)]
126    pub fn last(&self) -> Option<T> {
127        alt!(self.is_empty(), return None);
128        Some(
129            self.inner
130                .get((self.len() as u64 - 1).to_be_bytes())
131                .unwrap(),
132        )
133    }
134
135    /// Returns the number of values in the vector.
136    #[inline(always)]
137    pub fn len(&self) -> usize {
138        self.inner.len()
139    }
140
141    /// Checks if the vector is empty.
142    #[inline(always)]
143    pub fn is_empty(&self) -> bool {
144        self.inner.is_empty()
145    }
146
147    /// Appends a value to the end of the vector.
148    #[inline(always)]
149    pub fn push(&mut self, v: &T) {
150        self.inner.insert((self.len() as u64).to_be_bytes(), v);
151    }
152
153    /// Inserts a value at a specific index.
154    ///
155    /// # Panics
156    ///
157    /// Panics if `idx` is out of bounds.
158    #[inline(always)]
159    pub fn insert(&mut self, idx: usize, v: &T) {
160        let idx = idx as u64;
161        match (self.len() as u64).cmp(&idx) {
162            Ordering::Greater => {
163                self.inner
164                    .inner
165                    .range_detached(
166                        Cow::Borrowed(&idx.to_be_bytes()[..])
167                            ..Cow::Borrowed(&(self.len() as u64).to_be_bytes()[..]),
168                    )
169                    .for_each(|(i, iv)| {
170                        unsafe {
171                            self.inner.insert_encoded_value(
172                                (crate::parse_int!(i, u64) + 1).to_be_bytes(),
173                                iv,
174                            )
175                        };
176                    });
177                self.inner.insert(idx.to_be_bytes(), v);
178            }
179            Ordering::Equal => {
180                self.push(v);
181            }
182            Ordering::Less => {
183                panic!("out of index");
184            }
185        }
186    }
187
188    /// Removes and returns the last value in the vector.
189    #[inline(always)]
190    pub fn pop(&mut self) -> Option<T> {
191        alt!(self.is_empty(), return None);
192        self.inner.remove((self.len() as u64 - 1).to_be_bytes())
193    }
194
195    /// Removes and returns the value at a specific index.
196    ///
197    /// # Panics
198    ///
199    /// Panics if `idx` is out of bounds.
200    #[inline(always)]
201    pub fn remove(&mut self, idx: usize) -> T {
202        let idx = idx as u64;
203        if !self.is_empty() && idx < self.len() as u64 {
204            let last_idx = self.len() as u64 - 1;
205            let ret = self.inner.remove(idx.to_be_bytes()).unwrap();
206            self.inner
207                .inner
208                .range_detached(Cow::Borrowed(&(1 + idx).to_be_bytes()[..])..)
209                .for_each(|(i, v)| {
210                    unsafe {
211                        self.inner.insert_encoded_value(
212                            (crate::parse_int!(i, u64) - 1).to_be_bytes(),
213                            v,
214                        )
215                    };
216                });
217            self.inner.remove(last_idx.to_be_bytes());
218            return ret;
219        }
220        panic!("out of index");
221    }
222
223    /// Removes a value at a specific index and returns it, replacing it with the last value.
224    ///
225    /// # Panics
226    ///
227    /// Panics if `idx` is out of bounds.
228    #[inline(always)]
229    pub fn swap_remove(&mut self, idx: usize) -> T {
230        let idx = idx as u64;
231        if !self.is_empty() && idx < self.len() as u64 {
232            let last_idx = self.len() as u64 - 1;
233            let ret = self.inner.remove(idx.to_be_bytes()).unwrap();
234            if let Some(v) = self.inner.remove(last_idx.to_be_bytes()) {
235                self.inner.insert(idx.to_be_bytes(), &v);
236            }
237            return ret;
238        }
239        panic!("out of index");
240    }
241
242    /// Updates the value at a specific index.
243    ///
244    /// # Panics
245    ///
246    /// Panics if `idx` is out of bounds.
247    #[inline(always)]
248    pub fn update(&mut self, idx: usize, v: &T) -> Option<T> {
249        if idx < self.len() {
250            return self.inner.insert((idx as u64).to_be_bytes(), v);
251        }
252        panic!("out of index");
253    }
254
255    /// Returns an iterator over the vector's values.
256    #[inline(always)]
257    pub fn iter(&self) -> VecxIter<'_, T> {
258        VecxIter(self.inner.iter())
259    }
260
261    /// Returns a mutable iterator over the vector's values.
262    #[inline(always)]
263    pub fn iter_mut(&mut self) -> VecxIterMut<'_, T> {
264        VecxIterMut(self.inner.iter_mut())
265    }
266
267    /// Clears the vector, removing all values.
268    #[inline(always)]
269    pub fn clear(&mut self) {
270        self.inner.clear();
271    }
272
273    /// Checks if this `Vecx` instance is the same as another.
274    #[inline(always)]
275    pub fn is_the_same_instance(&self, other_hdr: &Self) -> bool {
276        self.inner.is_the_same_instance(&other_hdr.inner)
277    }
278}
279
280impl<T> Clone for Vecx<T> {
281    fn clone(&self) -> Self {
282        Self {
283            inner: self.inner.clone(),
284        }
285    }
286}
287
288impl<T: ValueEnDe> Default for Vecx<T> {
289    fn default() -> Self {
290        Self::new()
291    }
292}
293
294/////////////////////////////////////////////////////////////////////////////
295/////////////////////////////////////////////////////////////////////////////
296
297/// An iterator over the values of a `Vecx`.
298pub struct VecxIter<'a, T>(MapxOrdRawKeyIter<'a, T>);
299
300impl<T> Iterator for VecxIter<'_, T>
301where
302    T: ValueEnDe,
303{
304    type Item = T;
305    fn next(&mut self) -> Option<Self::Item> {
306        self.0.next().map(|(_, v)| v)
307    }
308}
309
310impl<V> DoubleEndedIterator for VecxIter<'_, V>
311where
312    V: ValueEnDe,
313{
314    fn next_back(&mut self) -> Option<Self::Item> {
315        self.0.next_back().map(|(_, v)| v)
316    }
317}
318
319/// A mutable iterator over the values of a `Vecx`.
320pub struct VecxIterMut<'a, T>(MapxOrdRawKeyIterMut<'a, T>);
321
322impl<'a, T> Iterator for VecxIterMut<'a, T>
323where
324    T: ValueEnDe,
325{
326    type Item = ValueIterMut<'a, T>;
327    fn next(&mut self) -> Option<Self::Item> {
328        self.0.next().map(|(_, v)| v)
329    }
330}
331
332impl<V> DoubleEndedIterator for VecxIterMut<'_, V>
333where
334    V: ValueEnDe,
335{
336    fn next_back(&mut self) -> Option<Self::Item> {
337        self.0.next_back().map(|(_, v)| v)
338    }
339}
340
341/////////////////////////////////////////////////////////////////////////////
342/////////////////////////////////////////////////////////////////////////////