server: smart generic vec routes build

This commit is contained in:
nym21
2025-02-12 14:11:04 +01:00
parent eaf76e27f5
commit 269c64e4ed
21 changed files with 278 additions and 411 deletions

View File

@@ -56,7 +56,6 @@ pub struct StorableVec<I, T, const MODE: u8> {
file: File,
/// **Number of values NOT number of bytes**
file_len: usize,
/// Only for SINGLE_THREAD
file_position: u64,
buf: Buffer,
/// Only for CACHED_GETS
@@ -78,8 +77,8 @@ const MAX_CACHE_SIZE: usize = usize::MAX;
impl<I, T, const MODE: u8> StorableVec<I, T, MODE>
where
I: StorableVecIndex,
T: StorableVecType,
I: StoredIndex,
T: StoredType,
{
pub const SIZE_OF_T: usize = size_of::<T>();
pub const PER_PAGE: usize = MAX_PAGE_SIZE / Self::SIZE_OF_T;
@@ -102,20 +101,23 @@ where
pub fn import(path: &Path, version: Version) -> Result<Self> {
fs::create_dir_all(path)?;
let path_version = Self::path_version_(path);
if MODE != STATELESS {
let path_version = Self::path_version_(path);
if let Ok(prev_version) = Version::try_from(path_version.as_path()) {
if prev_version != version {
if prev_version.swap_bytes() == version {
return Err(Error::WrongEndian);
if let Ok(prev_version) = Version::try_from(path_version.as_path()) {
if prev_version != version {
if prev_version.swap_bytes() == version {
return Err(Error::WrongEndian);
}
return Err(Error::DifferentVersion {
found: prev_version,
expected: version,
});
}
return Err(Error::DifferentVersion {
found: prev_version,
expected: version,
});
}
version.write(&path_version)?;
}
version.write(&path_version)?;
let file = Self::open_file_(&Self::path_vec_(path))?;
@@ -336,12 +338,16 @@ where
fn path_version_(path: &Path) -> PathBuf {
path.join("version")
}
pub fn index_type_to_string(&self) -> &str {
std::any::type_name::<I>()
}
}
impl<I, T> StorableVec<I, T, CACHED_GETS>
where
I: StorableVecIndex,
T: StorableVecType,
I: StoredIndex,
T: StoredType,
{
#[inline]
pub fn get(&self, index: I) -> Result<Option<Value<'_, T>>> {
@@ -420,8 +426,8 @@ where
const FLUSH_EVERY: usize = 10_000;
impl<I, T> StorableVec<I, T, SINGLE_THREAD>
where
I: StorableVecIndex,
T: StorableVecType,
I: StoredIndex,
T: StoredType,
{
pub fn get(&mut self, index: I) -> Result<&T> {
self.get_(Self::i_to_usize(index)?)
@@ -499,7 +505,7 @@ where
pub fn compute_transform<A, F>(&mut self, other: &mut StorableVec<I, A, SINGLE_THREAD>, t: F) -> Result<()>
where
A: StorableVecType,
A: StoredType,
F: Fn(&A) -> T,
{
other.iter_from(I::from(self.len()), |(i, a)| self.push_if_needed(i, t(a)))?;
@@ -508,8 +514,8 @@ where
pub fn compute_inverse_more_to_less(&mut self, other: &mut StorableVec<T, I, SINGLE_THREAD>) -> Result<()>
where
I: StorableVecType,
T: StorableVecIndex,
I: StoredType,
T: StoredIndex,
{
let index = self.last()?.cloned().unwrap_or_default();
other.iter_from(index, |(v, i)| self.push_if_needed(*i, v))?;
@@ -522,8 +528,8 @@ where
last_indexes: &mut StorableVec<T, I, SINGLE_THREAD>,
) -> Result<()>
where
I: StorableVecType,
T: StorableVecIndex,
I: StoredType,
T: StoredIndex,
{
first_indexes.iter_from(T::from(self.len()), |(value, first_index)| {
let first_index = Self::i_to_usize(*first_index)?;
@@ -539,7 +545,7 @@ where
final_len: usize,
) -> Result<()>
where
T: Copy + From<usize> + Sub<T, Output = T> + StorableVecIndex,
T: Copy + From<usize> + Sub<T, Output = T> + StoredIndex,
{
let one = T::from(1);
let mut prev_index: Option<I> = None;
@@ -563,8 +569,8 @@ where
) -> Result<()>
where
T: From<T2>,
T2: StorableVecType + Copy + Add<usize, Output = T2> + Sub<T2, Output = T2> + TryInto<T>,
<T2 as TryInto<T>>::Error: error::Error + Send + Sync + 'static,
T2: StoredType + Copy + Add<usize, Output = T2> + Sub<T2, Output = T2> + TryInto<T>,
<T2 as TryInto<T>>::Error: error::Error + 'static,
{
first_indexes.iter_from(I::from(self.len()), |(i, first_index)| {
let last_index = last_indexes.get(i)?;
@@ -580,9 +586,9 @@ where
other_to_self: &mut StorableVec<A, I, SINGLE_THREAD>,
) -> Result<()>
where
I: StorableVecType,
I: StoredType,
T: From<bool>,
A: StorableVecIndex + StorableVecType,
A: StoredIndex + StoredType,
{
self_to_other.iter_from(I::from(self.len()), |(i, other)| {
self.push_if_needed(i, T::from(other_to_self.get(*other)? == &i))
@@ -597,8 +603,8 @@ where
) -> Result<()>
where
T: From<T2>,
T2: StorableVecType + Copy + Add<usize, Output = T2> + Sub<T2, Output = T2> + TryInto<T>,
<T2 as TryInto<T>>::Error: error::Error + Send + Sync + 'static,
T2: StoredType + Copy + Add<usize, Output = T2> + Sub<T2, Output = T2> + TryInto<T>,
<T2 as TryInto<T>>::Error: error::Error + 'static,
F: Fn(&T2) -> T,
{
first_indexes.iter_from(I::from(self.len()), |(i, first_index)| {
@@ -612,8 +618,8 @@ where
impl<I, T> StorableVec<I, T, STATELESS>
where
I: StorableVecIndex,
T: StorableVecType,
I: StoredIndex,
T: StoredType,
{
#[inline]
pub fn get(&self, index: I) -> Result<Option<T>> {
@@ -664,8 +670,8 @@ where
impl<I, T> Clone for StorableVec<I, T, STATELESS>
where
I: StorableVecIndex,
T: StorableVecType,
I: StoredIndex,
T: StoredType,
{
fn clone(&self) -> Self {
let path = &self.pathbuf;

View File

@@ -1,10 +1,12 @@
use std::io;
use std::{io, mem};
use crate::StorableVec;
use crate::{Result, StorableVec, STATELESS};
use super::{StorableVecIndex, StorableVecType};
use super::{StoredIndex, StoredType};
pub trait AnyStorableVec {
pub trait AnyStorableVec: Send + Sync {
fn file_name(&self) -> String;
fn index_type_to_string(&self) -> &str;
fn len(&self) -> usize;
fn is_empty(&self) -> bool;
fn flush(&mut self) -> io::Result<()>;
@@ -12,9 +14,17 @@ pub trait AnyStorableVec {
impl<I, T, const MODE: u8> AnyStorableVec for StorableVec<I, T, MODE>
where
I: StorableVecIndex,
T: StorableVecType,
I: StoredIndex,
T: StoredType,
{
fn file_name(&self) -> String {
self.file_name()
}
fn index_type_to_string(&self) -> &str {
self.index_type_to_string()
}
fn len(&self) -> usize {
self.len()
}
@@ -27,3 +37,28 @@ where
self.flush()
}
}
#[cfg(feature = "json")]
pub trait AnyJsonStorableVec: AnyStorableVec {
fn collect_range_values(&self, from: Option<i64>, to: Option<i64>) -> Result<Vec<serde_json::Value>>;
}
impl<I, T, const MODE: u8> AnyJsonStorableVec for StorableVec<I, T, MODE>
where
I: StoredIndex,
T: StoredType + serde::Serialize,
{
fn collect_range_values(&self, from: Option<i64>, to: Option<i64>) -> Result<Vec<serde_json::Value>> {
if MODE == STATELESS {
Ok(
unsafe { mem::transmute::<&StorableVec<I, T, MODE>, &StorableVec<I, T, STATELESS>>(self) }
.collect_range(from, to)?
.into_iter()
.map(|v| serde_json::to_value(v).unwrap())
.collect::<Vec<_>>(),
)
} else {
unreachable!()
}
}
}

View File

@@ -1,8 +1,8 @@
mod any;
// mod bytes;
mod index;
mod type_;
mod stored_index;
mod stored_type;
pub use any::*;
pub use index::*;
pub use type_::*;
pub use stored_index::*;
pub use stored_type::*;

View File

@@ -1,6 +1,6 @@
use std::{fmt::Debug, ops::Add};
pub trait StorableVecIndex
pub trait StoredIndex
where
Self: Debug
+ Default
@@ -12,10 +12,12 @@ where
+ Ord
+ TryInto<usize>
+ From<usize>
+ Add<usize, Output = Self>,
+ Add<usize, Output = Self>
+ Send
+ Sync,
{
}
impl<I> StorableVecIndex for I where
impl<I> StoredIndex for I where
I: Debug
+ Default
+ Copy
@@ -27,5 +29,7 @@ impl<I> StorableVecIndex for I where
+ TryInto<usize>
+ From<usize>
+ Add<usize, Output = Self>
+ Send
+ Sync
{
}

View File

@@ -0,0 +1,13 @@
use std::fmt::Debug;
use zerocopy::{Immutable, IntoBytes, KnownLayout, TryFromBytes};
pub trait StoredType
where
Self: Sized + Debug + Clone + TryFromBytes + IntoBytes + Immutable + KnownLayout + Send + Sync,
{
}
impl<T> StoredType for T where
T: Sized + Debug + Clone + TryFromBytes + IntoBytes + Immutable + KnownLayout + Send + Sync
{
}

View File

@@ -1,10 +0,0 @@
use std::fmt::Debug;
use zerocopy::{Immutable, IntoBytes, KnownLayout, TryFromBytes};
pub trait StorableVecType
where
Self: Sized + Debug + Clone + TryFromBytes + IntoBytes + Immutable + KnownLayout,
{
}
impl<T> StorableVecType for T where T: Sized + Debug + Clone + TryFromBytes + IntoBytes + Immutable + KnownLayout {}