mirror of
https://github.com/voltrevo/ValueScript.git
synced 2026-04-18 03:00:27 -04:00
Split out storage_val
This commit is contained in:
@@ -6,6 +6,7 @@ mod sled_backend;
|
||||
mod storage_backend;
|
||||
mod storage_ops;
|
||||
mod storage_ptr;
|
||||
mod storage_val;
|
||||
mod tests;
|
||||
|
||||
pub use self::storage::Storage;
|
||||
|
||||
@@ -1,14 +1,10 @@
|
||||
use std::rc::Rc;
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::serde_rc::{deserialize_rc, serialize_rc};
|
||||
use crate::storage_ops::StorageOps;
|
||||
use crate::storage_ptr::{tmp_at_ptr, tmp_count_ptr, StorageEntryPtr, StorageHeadPtr};
|
||||
use crate::storage_val::StorageVal;
|
||||
use crate::StorageBackend;
|
||||
|
||||
pub struct Storage<SB: StorageBackend> {
|
||||
sb: SB,
|
||||
pub(crate) sb: SB,
|
||||
}
|
||||
|
||||
impl<SB: StorageBackend> Storage<SB> {
|
||||
@@ -72,142 +68,3 @@ impl<SB: StorageBackend> Storage<SB> {
|
||||
.transaction(|sb| Ok(sb.read(key)?.map(|entry| entry.ref_count)))
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
pub struct StorageEntry {
|
||||
pub(crate) ref_count: u64,
|
||||
|
||||
#[serde(serialize_with = "serialize_rc", deserialize_with = "deserialize_rc")]
|
||||
pub(crate) refs: Rc<Vec<StorageEntryPtr>>,
|
||||
|
||||
data: Vec<u8>,
|
||||
}
|
||||
|
||||
#[derive(Default, Serialize, Deserialize, PartialEq, Eq, Debug, Clone)]
|
||||
pub enum StoragePoint {
|
||||
#[default]
|
||||
Void,
|
||||
Number(u64),
|
||||
Array(
|
||||
#[serde(serialize_with = "serialize_rc", deserialize_with = "deserialize_rc")]
|
||||
Rc<Vec<StoragePoint>>,
|
||||
),
|
||||
Ref(u64),
|
||||
}
|
||||
|
||||
impl StoragePoint {
|
||||
pub fn maybe_replace_store<E, SO: StorageOps<E>>(
|
||||
&self,
|
||||
tx: &mut SO,
|
||||
refs: &Rc<Vec<StorageEntryPtr>>,
|
||||
) -> Result<Option<StorageEntryPtr>, E> {
|
||||
Ok(match &self {
|
||||
StoragePoint::Void => None,
|
||||
StoragePoint::Number(_) => None,
|
||||
StoragePoint::Array(arr) => 'b: {
|
||||
let mut replacements: Vec<(usize, StorageEntryPtr)> = Vec::new();
|
||||
|
||||
for i in 0..arr.len() {
|
||||
if let Some(key) = arr[i].maybe_replace_store(tx, refs)? {
|
||||
replacements.push((i, key));
|
||||
}
|
||||
}
|
||||
|
||||
if replacements.is_empty() {
|
||||
break 'b Some(tx.store(&StorageVal {
|
||||
point: StoragePoint::Array(arr.clone()),
|
||||
refs: refs.clone(),
|
||||
})?);
|
||||
}
|
||||
|
||||
let mut new_arr = Vec::<StoragePoint>::new();
|
||||
let mut new_refs = (**refs).clone();
|
||||
|
||||
let mut replacements_iter = replacements.iter();
|
||||
let mut next_replacement = replacements_iter.next();
|
||||
|
||||
for (i, point) in arr.iter().enumerate() {
|
||||
if let Some((j, entry_ptr)) = next_replacement {
|
||||
if *j == i {
|
||||
new_arr.push(StoragePoint::Ref(new_refs.len() as u64));
|
||||
new_refs.push(*entry_ptr);
|
||||
next_replacement = replacements_iter.next();
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
new_arr.push(point.clone());
|
||||
}
|
||||
|
||||
Some(tx.store(&StorageVal {
|
||||
point: StoragePoint::Array(Rc::new(new_arr)),
|
||||
refs: Rc::new(new_refs),
|
||||
})?)
|
||||
}
|
||||
StoragePoint::Ref(_) => None,
|
||||
})
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
fn numbers<E, SO: StorageOps<E>>(
|
||||
&self,
|
||||
tx: &mut SO,
|
||||
refs: &Rc<Vec<StorageEntryPtr>>,
|
||||
) -> Result<Vec<u64>, E> {
|
||||
match &self {
|
||||
StoragePoint::Void => Ok(Vec::new()),
|
||||
StoragePoint::Number(n) => Ok(vec![*n]),
|
||||
StoragePoint::Array(arr) => {
|
||||
let mut numbers = Vec::new();
|
||||
|
||||
for point in arr.iter() {
|
||||
numbers.extend(point.numbers(tx, refs)?);
|
||||
}
|
||||
|
||||
Ok(numbers)
|
||||
}
|
||||
StoragePoint::Ref(i) => {
|
||||
let key = refs[*i as usize];
|
||||
let val = tx.read(key)?.unwrap().to_val();
|
||||
val.point.numbers(tx, &val.refs)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug)]
|
||||
pub struct StorageVal {
|
||||
pub point: StoragePoint,
|
||||
|
||||
#[serde(serialize_with = "serialize_rc", deserialize_with = "deserialize_rc")]
|
||||
pub refs: Rc<Vec<StorageEntryPtr>>,
|
||||
}
|
||||
|
||||
impl StorageEntry {
|
||||
pub fn to_val(&self) -> StorageVal {
|
||||
StorageVal {
|
||||
point: bincode::deserialize(&self.data).unwrap(),
|
||||
refs: self.refs.clone(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl StorageVal {
|
||||
pub fn to_entry(&self) -> StorageEntry {
|
||||
StorageEntry {
|
||||
ref_count: 1,
|
||||
refs: self.refs.clone(),
|
||||
data: bincode::serialize(&self.point).unwrap(),
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
pub(crate) fn numbers<SB: StorageBackend>(
|
||||
&self,
|
||||
storage: &mut Storage<SB>,
|
||||
) -> Result<Vec<u64>, SB::Error<()>> {
|
||||
storage
|
||||
.sb
|
||||
.transaction(|sb| self.point.numbers(sb, &self.refs))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,9 +2,9 @@ use rand::thread_rng;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::{
|
||||
storage::StorageVal,
|
||||
storage_backend::StorageBackendHandle,
|
||||
storage_ptr::{StorageEntryPtr, StorageHeadPtr, StoragePtr},
|
||||
storage_val::StorageVal,
|
||||
};
|
||||
|
||||
pub trait StorageOps<E> {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
use rand::{rngs::ThreadRng, Rng};
|
||||
|
||||
use crate::storage::StorageEntry;
|
||||
use crate::storage_val::StorageEntry;
|
||||
|
||||
#[derive(serde::Serialize, serde::Deserialize, Hash, PartialEq, Eq)]
|
||||
pub struct StoragePtr<T> {
|
||||
|
||||
149
storage/src/storage_val.rs
Normal file
149
storage/src/storage_val.rs
Normal file
@@ -0,0 +1,149 @@
|
||||
use std::rc::Rc;
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::serde_rc::{deserialize_rc, serialize_rc};
|
||||
use crate::storage_ops::StorageOps;
|
||||
use crate::storage_ptr::StorageEntryPtr;
|
||||
|
||||
#[cfg(test)]
|
||||
use crate::{Storage, StorageBackend};
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug)]
|
||||
pub struct StorageVal {
|
||||
pub point: StoragePoint,
|
||||
|
||||
#[serde(serialize_with = "serialize_rc", deserialize_with = "deserialize_rc")]
|
||||
pub refs: Rc<Vec<StorageEntryPtr>>,
|
||||
}
|
||||
|
||||
impl StorageVal {
|
||||
pub fn to_entry(&self) -> StorageEntry {
|
||||
StorageEntry {
|
||||
ref_count: 1,
|
||||
refs: self.refs.clone(),
|
||||
data: bincode::serialize(&self.point).unwrap(),
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
pub(crate) fn numbers<SB: StorageBackend>(
|
||||
&self,
|
||||
storage: &mut Storage<SB>,
|
||||
) -> Result<Vec<u64>, SB::Error<()>> {
|
||||
storage
|
||||
.sb
|
||||
.transaction(|sb| self.point.numbers(sb, &self.refs))
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Default, Serialize, Deserialize, PartialEq, Eq, Debug, Clone)]
|
||||
pub enum StoragePoint {
|
||||
#[default]
|
||||
Void,
|
||||
Number(u64),
|
||||
Array(
|
||||
#[serde(serialize_with = "serialize_rc", deserialize_with = "deserialize_rc")]
|
||||
Rc<Vec<StoragePoint>>,
|
||||
),
|
||||
Ref(u64),
|
||||
}
|
||||
|
||||
impl StoragePoint {
|
||||
pub fn maybe_replace_store<E, SO: StorageOps<E>>(
|
||||
&self,
|
||||
tx: &mut SO,
|
||||
refs: &Rc<Vec<StorageEntryPtr>>,
|
||||
) -> Result<Option<StorageEntryPtr>, E> {
|
||||
Ok(match &self {
|
||||
StoragePoint::Void => None,
|
||||
StoragePoint::Number(_) => None,
|
||||
StoragePoint::Array(arr) => 'b: {
|
||||
let mut replacements: Vec<(usize, StorageEntryPtr)> = Vec::new();
|
||||
|
||||
for i in 0..arr.len() {
|
||||
if let Some(key) = arr[i].maybe_replace_store(tx, refs)? {
|
||||
replacements.push((i, key));
|
||||
}
|
||||
}
|
||||
|
||||
if replacements.is_empty() {
|
||||
break 'b Some(tx.store(&StorageVal {
|
||||
point: StoragePoint::Array(arr.clone()),
|
||||
refs: refs.clone(),
|
||||
})?);
|
||||
}
|
||||
|
||||
let mut new_arr = Vec::<StoragePoint>::new();
|
||||
let mut new_refs = (**refs).clone();
|
||||
|
||||
let mut replacements_iter = replacements.iter();
|
||||
let mut next_replacement = replacements_iter.next();
|
||||
|
||||
for (i, point) in arr.iter().enumerate() {
|
||||
if let Some((j, entry_ptr)) = next_replacement {
|
||||
if *j == i {
|
||||
new_arr.push(StoragePoint::Ref(new_refs.len() as u64));
|
||||
new_refs.push(*entry_ptr);
|
||||
next_replacement = replacements_iter.next();
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
new_arr.push(point.clone());
|
||||
}
|
||||
|
||||
Some(tx.store(&StorageVal {
|
||||
point: StoragePoint::Array(Rc::new(new_arr)),
|
||||
refs: Rc::new(new_refs),
|
||||
})?)
|
||||
}
|
||||
StoragePoint::Ref(_) => None,
|
||||
})
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
fn numbers<E, SO: StorageOps<E>>(
|
||||
&self,
|
||||
tx: &mut SO,
|
||||
refs: &Rc<Vec<StorageEntryPtr>>,
|
||||
) -> Result<Vec<u64>, E> {
|
||||
match &self {
|
||||
StoragePoint::Void => Ok(Vec::new()),
|
||||
StoragePoint::Number(n) => Ok(vec![*n]),
|
||||
StoragePoint::Array(arr) => {
|
||||
let mut numbers = Vec::new();
|
||||
|
||||
for point in arr.iter() {
|
||||
numbers.extend(point.numbers(tx, refs)?);
|
||||
}
|
||||
|
||||
Ok(numbers)
|
||||
}
|
||||
StoragePoint::Ref(i) => {
|
||||
let key = refs[*i as usize];
|
||||
let val = tx.read(key)?.unwrap().to_val();
|
||||
val.point.numbers(tx, &val.refs)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
pub struct StorageEntry {
|
||||
pub(crate) ref_count: u64,
|
||||
|
||||
#[serde(serialize_with = "serialize_rc", deserialize_with = "deserialize_rc")]
|
||||
pub(crate) refs: Rc<Vec<StorageEntryPtr>>,
|
||||
|
||||
data: Vec<u8>,
|
||||
}
|
||||
|
||||
impl StorageEntry {
|
||||
pub fn to_val(&self) -> StorageVal {
|
||||
StorageVal {
|
||||
point: bincode::deserialize(&self.data).unwrap(),
|
||||
refs: self.refs.clone(),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -5,8 +5,9 @@ mod tests_ {
|
||||
use crate::{
|
||||
memory_backend::MemoryBackend,
|
||||
sled_backend::SledBackend,
|
||||
storage::{Storage, StoragePoint, StorageVal},
|
||||
storage::Storage,
|
||||
storage_ptr::storage_head_ptr,
|
||||
storage_val::{StoragePoint, StorageVal},
|
||||
StorageBackend,
|
||||
};
|
||||
|
||||
@@ -115,8 +116,6 @@ mod tests_ {
|
||||
.unwrap()
|
||||
.unwrap();
|
||||
|
||||
dbg!(&value);
|
||||
|
||||
let numbers = value.numbers(storage).unwrap();
|
||||
|
||||
assert_eq!(numbers, vec![1, 2, 3, 4]);
|
||||
|
||||
Reference in New Issue
Block a user