mirror of
https://github.com/voltrevo/ValueScript.git
synced 2026-01-10 05:58:03 -05:00
Non-mut storage operations
This commit is contained in:
@@ -7,7 +7,7 @@ use std::{
|
||||
};
|
||||
|
||||
use valuescript_compiler::{assemble, compile, resolve_path, ResolvedPath};
|
||||
use valuescript_vm::{Bytecode, ValTrait, VirtualMachine};
|
||||
use valuescript_vm::{vs_value::Val, Bytecode, DecoderMaker, ValTrait, VirtualMachine};
|
||||
|
||||
fn main() {
|
||||
let exe_path = std::env::current_exe().unwrap();
|
||||
@@ -82,7 +82,12 @@ fn main() {
|
||||
|
||||
while Instant::now() - start < Duration::from_secs(1) {
|
||||
let before = Instant::now();
|
||||
let result = vm.run(bytecode.clone(), None, &[]);
|
||||
let result = vm.run(
|
||||
None,
|
||||
&mut Val::Undefined,
|
||||
bytecode.decoder(0).decode_val(&mut vec![]),
|
||||
vec![],
|
||||
);
|
||||
let after = Instant::now();
|
||||
|
||||
let duration_ms = after.duration_since(before).as_millis();
|
||||
|
||||
@@ -6,7 +6,7 @@ use crate::storage_backend::StorageError;
|
||||
use crate::storage_entity::StorageEntity;
|
||||
use crate::storage_entry::{StorageEntry, StorageEntryReader};
|
||||
use crate::storage_ptr::StorageEntryPtr;
|
||||
use crate::storage_tx::StorageTx;
|
||||
use crate::storage_tx::{StorageTx, StorageTxMut};
|
||||
use crate::{Storage, StorageBackend};
|
||||
|
||||
const NUMBER_TAG: u8 = 0;
|
||||
@@ -27,11 +27,11 @@ impl DemoVal {
|
||||
) -> Result<Vec<u64>, Box<dyn Error>> {
|
||||
storage
|
||||
.sb
|
||||
.borrow_mut()
|
||||
.borrow()
|
||||
.transaction(Rc::downgrade(&storage.sb), |sb| self.numbers_impl(sb))
|
||||
}
|
||||
|
||||
fn write_to_entry<'a, SB: StorageBackend, Tx: StorageTx<'a, SB>>(
|
||||
fn write_to_entry<'a, SB: StorageBackend, Tx: StorageTxMut<'a, SB>>(
|
||||
&self,
|
||||
tx: &mut Tx,
|
||||
entry: &mut StorageEntry,
|
||||
@@ -115,8 +115,11 @@ impl DemoVal {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, SB: StorageBackend, Tx: StorageTx<'a, SB>> StorageEntity<'a, SB, Tx> for DemoVal {
|
||||
fn to_storage_entry(&self, tx: &mut Tx) -> Result<StorageEntry, StorageError<SB>> {
|
||||
impl<SB: StorageBackend> StorageEntity<SB> for DemoVal {
|
||||
fn to_storage_entry<'a, Tx: StorageTxMut<'a, SB>>(
|
||||
&self,
|
||||
tx: &mut Tx,
|
||||
) -> Result<StorageEntry, StorageError<SB>> {
|
||||
let mut entry = StorageEntry {
|
||||
ref_count: 1,
|
||||
refs: Vec::new(),
|
||||
@@ -143,7 +146,10 @@ impl<'a, SB: StorageBackend, Tx: StorageTx<'a, SB>> StorageEntity<'a, SB, Tx> fo
|
||||
Ok(entry)
|
||||
}
|
||||
|
||||
fn from_storage_entry(tx: &mut Tx, entry: StorageEntry) -> Result<Self, StorageError<SB>> {
|
||||
fn from_storage_entry<'a, Tx: StorageTx<'a, SB>>(
|
||||
tx: &mut Tx,
|
||||
entry: StorageEntry,
|
||||
) -> Result<Self, StorageError<SB>> {
|
||||
Self::read_from_entry(tx, &mut StorageEntryReader::new(&entry))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,7 +16,7 @@ mod tests;
|
||||
|
||||
pub use self::storage::Storage;
|
||||
pub use self::storage_backend::{StorageBackend, StorageError};
|
||||
pub use self::storage_tx::StorageTx;
|
||||
pub use self::storage_tx::{StorageTx, StorageTxMut};
|
||||
pub use memory_backend::MemoryBackend;
|
||||
pub use rc_key::RcKey;
|
||||
pub use sled_backend::SledBackend;
|
||||
|
||||
@@ -1,8 +1,11 @@
|
||||
use std::{cell::RefCell, collections::HashMap, error::Error, rc::Weak};
|
||||
|
||||
use crate::{
|
||||
rc_key::RcKey, storage_backend::StorageError, storage_ptr::StorageEntryPtr,
|
||||
storage_tx::StorageTx, StorageAutoPtr, StorageBackend, StorageEntity, StoragePtr,
|
||||
rc_key::RcKey,
|
||||
storage_backend::StorageError,
|
||||
storage_ptr::StorageEntryPtr,
|
||||
storage_tx::{StorageTx, StorageTxMut},
|
||||
StorageAutoPtr, StorageBackend, StorageEntity, StoragePtr,
|
||||
};
|
||||
|
||||
#[derive(Default)]
|
||||
@@ -21,12 +24,32 @@ impl MemoryBackend {
|
||||
impl StorageBackend for MemoryBackend {
|
||||
type CustomError = Box<dyn Error>;
|
||||
type Tx<'a> = MemoryTx<'a>;
|
||||
type TxMut<'a> = MemoryTxMut<'a>;
|
||||
|
||||
fn transaction<F, T>(&mut self, self_weak: Weak<RefCell<Self>>, f: F) -> Result<T, Box<dyn Error>>
|
||||
fn transaction<F, T>(&self, self_weak: Weak<RefCell<Self>>, f: F) -> Result<T, Box<dyn Error>>
|
||||
where
|
||||
F: Fn(&mut Self::Tx<'_>) -> Result<T, StorageError<Self>>,
|
||||
{
|
||||
let mut handle = MemoryTx {
|
||||
backend: self_weak,
|
||||
storage: self,
|
||||
};
|
||||
|
||||
f(&mut handle).map_err(|e| match e {
|
||||
StorageError::<MemoryBackend>::CustomError(e) => e,
|
||||
StorageError::<MemoryBackend>::Error(e) => e,
|
||||
})
|
||||
}
|
||||
|
||||
fn transaction_mut<F, T>(
|
||||
&mut self,
|
||||
self_weak: Weak<RefCell<Self>>,
|
||||
f: F,
|
||||
) -> Result<T, Box<dyn Error>>
|
||||
where
|
||||
F: Fn(&mut Self::TxMut<'_>) -> Result<T, StorageError<Self>>,
|
||||
{
|
||||
let mut handle = MemoryTxMut {
|
||||
backend: self_weak,
|
||||
ref_deltas: Default::default(),
|
||||
cache: Default::default(),
|
||||
@@ -57,13 +80,38 @@ impl StorageBackend for MemoryBackend {
|
||||
}
|
||||
|
||||
pub struct MemoryTx<'a> {
|
||||
backend: Weak<RefCell<MemoryBackend>>,
|
||||
storage: &'a MemoryBackend,
|
||||
}
|
||||
|
||||
impl StorageTx<'_, MemoryBackend> for MemoryTx<'_> {
|
||||
fn read_bytes<T>(
|
||||
&self,
|
||||
ptr: StoragePtr<T>,
|
||||
) -> Result<Option<Vec<u8>>, StorageError<MemoryBackend>> {
|
||||
Ok(self.storage.data.get(&ptr.data).cloned())
|
||||
}
|
||||
|
||||
fn get_auto_ptr<SE: StorageEntity<MemoryBackend>>(
|
||||
&mut self,
|
||||
ptr: StorageEntryPtr,
|
||||
) -> StorageAutoPtr<MemoryBackend, SE> {
|
||||
StorageAutoPtr {
|
||||
_marker: std::marker::PhantomData,
|
||||
sb: self.backend.clone(),
|
||||
ptr,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct MemoryTxMut<'a> {
|
||||
backend: Weak<RefCell<MemoryBackend>>,
|
||||
ref_deltas: HashMap<(u64, u64, u64), i64>,
|
||||
cache: HashMap<RcKey, StorageEntryPtr>,
|
||||
storage: &'a mut MemoryBackend,
|
||||
}
|
||||
|
||||
impl<'a> StorageTx<'a, MemoryBackend> for MemoryTx<'a> {
|
||||
impl<'a> StorageTxMut<'a, MemoryBackend> for MemoryTxMut<'a> {
|
||||
fn ref_deltas(&mut self) -> &mut HashMap<(u64, u64, u64), i64> {
|
||||
&mut self.ref_deltas
|
||||
}
|
||||
@@ -79,7 +127,7 @@ impl<'a> StorageTx<'a, MemoryBackend> for MemoryTx<'a> {
|
||||
Ok(self.storage.data.get(&ptr.data).cloned())
|
||||
}
|
||||
|
||||
fn get_auto_ptr<SE: for<'b> StorageEntity<'b, MemoryBackend, MemoryTx<'b>>>(
|
||||
fn get_auto_ptr<SE: StorageEntity<MemoryBackend>>(
|
||||
&mut self,
|
||||
ptr: StorageEntryPtr,
|
||||
) -> StorageAutoPtr<MemoryBackend, SE> {
|
||||
|
||||
@@ -1,8 +1,11 @@
|
||||
use std::{cell::RefCell, collections::HashMap, error::Error, rc::Weak};
|
||||
|
||||
use crate::{
|
||||
rc_key::RcKey, storage_backend::StorageError, storage_ptr::StorageEntryPtr,
|
||||
storage_tx::StorageTx, StorageAutoPtr, StorageBackend, StoragePtr,
|
||||
rc_key::RcKey,
|
||||
storage_backend::StorageError,
|
||||
storage_ptr::StorageEntryPtr,
|
||||
storage_tx::{StorageTx, StorageTxMut},
|
||||
StorageAutoPtr, StorageBackend, StorageEntity, StoragePtr,
|
||||
};
|
||||
|
||||
pub struct SledBackend {
|
||||
@@ -29,8 +32,9 @@ impl SledBackend {
|
||||
impl StorageBackend for SledBackend {
|
||||
type CustomError = sled::transaction::ConflictableTransactionError<Box<dyn Error>>;
|
||||
type Tx<'a> = SledTx<'a>;
|
||||
type TxMut<'a> = SledTxMut<'a>;
|
||||
|
||||
fn transaction<F, T>(&mut self, self_weak: Weak<RefCell<Self>>, f: F) -> Result<T, Box<dyn Error>>
|
||||
fn transaction<F, T>(&self, self_weak: Weak<RefCell<Self>>, f: F) -> Result<T, Box<dyn Error>>
|
||||
where
|
||||
F: Fn(&mut Self::Tx<'_>) -> Result<T, StorageError<Self>>,
|
||||
{
|
||||
@@ -38,6 +42,33 @@ impl StorageBackend for SledBackend {
|
||||
.db
|
||||
.transaction(|tx| {
|
||||
let mut handle = SledTx {
|
||||
backend: self_weak.clone(),
|
||||
tx,
|
||||
};
|
||||
|
||||
f(&mut handle).map_err(|e| match e {
|
||||
StorageError::CustomError(e) => e,
|
||||
StorageError::Error(e) => Self::CustomError::Abort(e),
|
||||
})
|
||||
})
|
||||
.map_err(|e| match e {
|
||||
sled::transaction::TransactionError::Abort(e) => e,
|
||||
sled::transaction::TransactionError::Storage(e) => e.into(),
|
||||
})
|
||||
}
|
||||
|
||||
fn transaction_mut<F, T>(
|
||||
&mut self,
|
||||
self_weak: Weak<RefCell<Self>>,
|
||||
f: F,
|
||||
) -> Result<T, Box<dyn Error>>
|
||||
where
|
||||
F: Fn(&mut Self::TxMut<'_>) -> Result<T, StorageError<Self>>,
|
||||
{
|
||||
self
|
||||
.db
|
||||
.transaction(|tx| {
|
||||
let mut handle = SledTxMut {
|
||||
backend: self_weak.clone(),
|
||||
ref_deltas: Default::default(),
|
||||
cache: Default::default(),
|
||||
@@ -73,13 +104,44 @@ impl StorageBackend for SledBackend {
|
||||
}
|
||||
|
||||
pub struct SledTx<'a> {
|
||||
backend: Weak<RefCell<SledBackend>>,
|
||||
tx: &'a sled::transaction::TransactionalTree,
|
||||
}
|
||||
|
||||
impl<'a> StorageTx<'a, SledBackend> for SledTx<'a> {
|
||||
fn read_bytes<T>(
|
||||
&self,
|
||||
ptr: StoragePtr<T>,
|
||||
) -> Result<Option<Vec<u8>>, StorageError<SledBackend>> {
|
||||
let value = self
|
||||
.tx
|
||||
.get(ptr.to_bytes())
|
||||
.map_err(|e| StorageError::<SledBackend>::CustomError(e.into()))?
|
||||
.map(|value| value.to_vec());
|
||||
|
||||
Ok(value)
|
||||
}
|
||||
|
||||
fn get_auto_ptr<SE: StorageEntity<SledBackend>>(
|
||||
&mut self,
|
||||
ptr: StorageEntryPtr,
|
||||
) -> crate::StorageAutoPtr<SledBackend, SE> {
|
||||
StorageAutoPtr {
|
||||
_marker: std::marker::PhantomData,
|
||||
sb: self.backend.clone(),
|
||||
ptr,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct SledTxMut<'a> {
|
||||
backend: Weak<RefCell<SledBackend>>,
|
||||
ref_deltas: HashMap<(u64, u64, u64), i64>,
|
||||
cache: HashMap<RcKey, StorageEntryPtr>,
|
||||
tx: &'a sled::transaction::TransactionalTree,
|
||||
}
|
||||
|
||||
impl<'a> StorageTx<'a, SledBackend> for SledTx<'a> {
|
||||
impl<'a> StorageTxMut<'a, SledBackend> for SledTxMut<'a> {
|
||||
fn ref_deltas(&mut self) -> &mut HashMap<(u64, u64, u64), i64> {
|
||||
&mut self.ref_deltas
|
||||
}
|
||||
@@ -101,9 +163,7 @@ impl<'a> StorageTx<'a, SledBackend> for SledTx<'a> {
|
||||
Ok(value)
|
||||
}
|
||||
|
||||
fn get_auto_ptr<
|
||||
SE: for<'b> crate::StorageEntity<'b, SledBackend, <SledBackend as StorageBackend>::Tx<'b>>,
|
||||
>(
|
||||
fn get_auto_ptr<SE: StorageEntity<SledBackend>>(
|
||||
&mut self,
|
||||
ptr: StorageEntryPtr,
|
||||
) -> crate::StorageAutoPtr<SledBackend, SE> {
|
||||
|
||||
@@ -5,7 +5,7 @@ use std::rc::Rc;
|
||||
use crate::storage_auto_ptr::StorageAutoPtr;
|
||||
use crate::storage_entity::StorageEntity;
|
||||
use crate::storage_ptr::{tmp_at_ptr, tmp_count_ptr, StorageEntryPtr, StorageHeadPtr};
|
||||
use crate::{StorageBackend, StorageError, StorageTx};
|
||||
use crate::{StorageBackend, StorageError, StorageTx, StorageTxMut};
|
||||
|
||||
pub struct Storage<SB: StorageBackend> {
|
||||
pub(crate) sb: Rc<RefCell<SB>>,
|
||||
@@ -18,34 +18,28 @@ impl<SB: StorageBackend> Storage<SB> {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_head<SE: for<'a> StorageEntity<'a, SB, SB::Tx<'a>>>(
|
||||
pub fn get_head<SE: StorageEntity<SB>>(
|
||||
&mut self,
|
||||
ptr: StorageHeadPtr,
|
||||
) -> Result<Option<SE>, Box<dyn Error>> {
|
||||
self
|
||||
.sb
|
||||
.borrow_mut()
|
||||
.borrow()
|
||||
.transaction(Rc::downgrade(&self.sb), |sb| sb.get_head(ptr))
|
||||
}
|
||||
|
||||
pub fn get<SE: for<'a> StorageEntity<'a, SB, SB::Tx<'a>>>(
|
||||
&mut self,
|
||||
ptr: StorageEntryPtr,
|
||||
) -> Result<SE, Box<dyn Error>> {
|
||||
pub fn get<SE: StorageEntity<SB>>(&self, ptr: StorageEntryPtr) -> Result<SE, Box<dyn Error>> {
|
||||
// TODO: Avoid going through a transaction when read-only
|
||||
self
|
||||
.sb
|
||||
.borrow_mut()
|
||||
.transaction(Rc::downgrade(&self.sb), |sb| {
|
||||
let entry = sb
|
||||
.read(ptr)?
|
||||
.ok_or(StorageError::Error("Ptr not found".into()))?;
|
||||
self.sb.borrow().transaction(Rc::downgrade(&self.sb), |sb| {
|
||||
let entry = sb
|
||||
.read(ptr)?
|
||||
.ok_or(StorageError::Error("Ptr not found".into()))?;
|
||||
|
||||
SE::from_storage_entry(sb, entry)
|
||||
})
|
||||
SE::from_storage_entry(sb, entry)
|
||||
})
|
||||
}
|
||||
|
||||
pub fn get_auto_ptr<SE: for<'a> StorageEntity<'a, SB, SB::Tx<'a>>>(
|
||||
pub fn get_auto_ptr<SE: StorageEntity<SB>>(
|
||||
&mut self,
|
||||
ptr: StorageEntryPtr,
|
||||
) -> StorageAutoPtr<SB, SE> {
|
||||
@@ -56,7 +50,7 @@ impl<SB: StorageBackend> Storage<SB> {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn set_head<SE: for<'a> StorageEntity<'a, SB, SB::Tx<'a>>>(
|
||||
pub fn set_head<SE: StorageEntity<SB>>(
|
||||
&mut self,
|
||||
ptr: StorageHeadPtr,
|
||||
value: &SE,
|
||||
@@ -64,31 +58,31 @@ impl<SB: StorageBackend> Storage<SB> {
|
||||
self
|
||||
.sb
|
||||
.borrow_mut()
|
||||
.transaction(Rc::downgrade(&self.sb), |sb| sb.set_head(ptr, value))
|
||||
.transaction_mut(Rc::downgrade(&self.sb), |sb| sb.set_head(ptr, value))
|
||||
}
|
||||
|
||||
pub fn remove_head(&mut self, ptr: StorageHeadPtr) -> Result<(), Box<dyn Error>> {
|
||||
self
|
||||
.sb
|
||||
.borrow_mut()
|
||||
.transaction(Rc::downgrade(&self.sb), |sb| sb.remove_head(ptr))
|
||||
.transaction_mut(Rc::downgrade(&self.sb), |sb| sb.remove_head(ptr))
|
||||
}
|
||||
|
||||
pub fn store_tmp<SE: for<'a> StorageEntity<'a, SB, SB::Tx<'a>>>(
|
||||
pub fn store_tmp<SE: StorageEntity<SB>>(
|
||||
&mut self,
|
||||
value: &SE,
|
||||
) -> Result<StorageEntryPtr, Box<dyn Error>> {
|
||||
self
|
||||
.sb
|
||||
.borrow_mut()
|
||||
.transaction(Rc::downgrade(&self.sb), |sb| {
|
||||
let tmp_count = sb.read(tmp_count_ptr())?.unwrap_or(0);
|
||||
.transaction_mut(Rc::downgrade(&self.sb), |sb| {
|
||||
let tmp_count = StorageTxMut::read(sb, tmp_count_ptr())?.unwrap_or(0);
|
||||
let tmp_ptr = tmp_at_ptr(tmp_count);
|
||||
sb.set_head(tmp_ptr, value)?;
|
||||
|
||||
sb.write(tmp_count_ptr(), Some(&(tmp_count + 1)))?;
|
||||
|
||||
let ptr = sb.read(tmp_ptr)?.unwrap_or_else(|| panic!("Ptr not found"));
|
||||
let ptr = StorageTxMut::read(sb, tmp_ptr)?.unwrap_or_else(|| panic!("Ptr not found"));
|
||||
|
||||
Ok(ptr)
|
||||
})
|
||||
@@ -98,8 +92,8 @@ impl<SB: StorageBackend> Storage<SB> {
|
||||
self
|
||||
.sb
|
||||
.borrow_mut()
|
||||
.transaction(Rc::downgrade(&self.sb), |sb| {
|
||||
let tmp_count = sb.read(tmp_count_ptr())?.unwrap_or(0);
|
||||
.transaction_mut(Rc::downgrade(&self.sb), |sb| {
|
||||
let tmp_count = StorageTxMut::read(sb, tmp_count_ptr())?.unwrap_or(0);
|
||||
|
||||
for i in 0..tmp_count {
|
||||
sb.remove_head(tmp_at_ptr(i))?;
|
||||
@@ -120,11 +114,8 @@ impl<SB: StorageBackend> Storage<SB> {
|
||||
&mut self,
|
||||
ptr: StorageEntryPtr,
|
||||
) -> Result<Option<u64>, Box<dyn Error>> {
|
||||
self
|
||||
.sb
|
||||
.borrow_mut()
|
||||
.transaction(Rc::downgrade(&self.sb), |sb| {
|
||||
Ok(sb.read(ptr)?.map(|entry| entry.ref_count))
|
||||
})
|
||||
self.sb.borrow().transaction(Rc::downgrade(&self.sb), |sb| {
|
||||
Ok(sb.read(ptr)?.map(|entry| entry.ref_count))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,17 +1,16 @@
|
||||
use std::fmt::{self, Debug};
|
||||
use std::{cell::RefCell, error::Error, rc::Weak};
|
||||
|
||||
use crate::{StorageBackend, StorageEntity, StorageEntryPtr, StorageTx};
|
||||
use crate::storage_tx::StorageTx;
|
||||
use crate::{StorageBackend, StorageEntity, StorageEntryPtr};
|
||||
|
||||
pub struct StorageAutoPtr<SB: StorageBackend, SE: for<'a> StorageEntity<'a, SB, SB::Tx<'a>>> {
|
||||
pub struct StorageAutoPtr<SB: StorageBackend, SE: StorageEntity<SB>> {
|
||||
pub(crate) _marker: std::marker::PhantomData<SE>,
|
||||
pub(crate) sb: Weak<RefCell<SB>>, // TODO: Does this need to be weak?
|
||||
pub ptr: StorageEntryPtr,
|
||||
}
|
||||
|
||||
impl<SB: StorageBackend, SE: for<'a> StorageEntity<'a, SB, SB::Tx<'a>>> Debug
|
||||
for StorageAutoPtr<SB, SE>
|
||||
{
|
||||
impl<SB: StorageBackend, SE: StorageEntity<SB>> Debug for StorageAutoPtr<SB, SE> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
f.debug_struct("StorageAutoPtr")
|
||||
.field("ptr", &self.ptr)
|
||||
@@ -19,7 +18,7 @@ impl<SB: StorageBackend, SE: for<'a> StorageEntity<'a, SB, SB::Tx<'a>>> Debug
|
||||
}
|
||||
}
|
||||
|
||||
impl<SB: StorageBackend, SE: for<'a> StorageEntity<'a, SB, SB::Tx<'a>>> StorageAutoPtr<SB, SE> {
|
||||
impl<SB: StorageBackend, SE: StorageEntity<SB>> StorageAutoPtr<SB, SE> {
|
||||
pub fn resolve(&self) -> Result<Option<SE>, Box<dyn Error>> {
|
||||
let sb = match self.sb.upgrade() {
|
||||
Some(sb) => sb,
|
||||
|
||||
@@ -1,18 +1,23 @@
|
||||
use std::{cell::RefCell, error::Error, rc::Weak};
|
||||
|
||||
use crate::storage_tx::StorageTx;
|
||||
use crate::storage_tx::{StorageTx, StorageTxMut};
|
||||
|
||||
pub trait StorageBackend: Sized {
|
||||
type CustomError;
|
||||
type Tx<'a>: StorageTx<'a, Self>;
|
||||
type TxMut<'a>: StorageTxMut<'a, Self>;
|
||||
|
||||
fn transaction<F, T>(
|
||||
fn transaction<F, T>(&self, self_weak: Weak<RefCell<Self>>, f: F) -> Result<T, Box<dyn Error>>
|
||||
where
|
||||
F: Fn(&mut Self::Tx<'_>) -> Result<T, StorageError<Self>>;
|
||||
|
||||
fn transaction_mut<F, T>(
|
||||
&mut self,
|
||||
self_weak: Weak<RefCell<Self>>,
|
||||
f: F,
|
||||
) -> Result<T, Box<dyn Error>>
|
||||
where
|
||||
F: Fn(&mut Self::Tx<'_>) -> Result<T, StorageError<Self>>;
|
||||
F: Fn(&mut Self::TxMut<'_>) -> Result<T, StorageError<Self>>;
|
||||
|
||||
fn is_empty(&self) -> bool;
|
||||
|
||||
|
||||
@@ -1,9 +1,18 @@
|
||||
use crate::{
|
||||
storage_backend::StorageError, storage_entry::StorageEntry, storage_tx::StorageTx, StorageBackend,
|
||||
storage_backend::StorageError,
|
||||
storage_entry::StorageEntry,
|
||||
storage_tx::{StorageTx, StorageTxMut},
|
||||
StorageBackend,
|
||||
};
|
||||
|
||||
pub trait StorageEntity<'a, SB: StorageBackend, Tx: StorageTx<'a, SB>>: Sized {
|
||||
fn to_storage_entry(&self, tx: &mut Tx) -> Result<StorageEntry, StorageError<SB>>;
|
||||
pub trait StorageEntity<SB: StorageBackend>: Sized {
|
||||
fn to_storage_entry<'a, Tx: StorageTxMut<'a, SB>>(
|
||||
&self,
|
||||
tx: &mut Tx,
|
||||
) -> Result<StorageEntry, StorageError<SB>>;
|
||||
|
||||
fn from_storage_entry(tx: &mut Tx, entry: StorageEntry) -> Result<Self, StorageError<SB>>;
|
||||
fn from_storage_entry<'a, Tx: StorageTx<'a, SB>>(
|
||||
tx: &mut Tx,
|
||||
entry: StorageEntry,
|
||||
) -> Result<Self, StorageError<SB>>;
|
||||
}
|
||||
|
||||
@@ -9,6 +9,54 @@ use crate::{
|
||||
};
|
||||
|
||||
pub trait StorageTx<'a, SB: StorageBackend>: Sized {
|
||||
fn read_bytes<T>(&self, ptr: StoragePtr<T>) -> Result<Option<Vec<u8>>, StorageError<SB>>;
|
||||
|
||||
fn read<T: for<'de> Deserialize<'de>>(
|
||||
&mut self,
|
||||
ptr: StoragePtr<T>,
|
||||
) -> Result<Option<T>, StorageError<SB>> {
|
||||
let data = match self.read_bytes(ptr)? {
|
||||
Some(data) => data,
|
||||
None => return Ok(None),
|
||||
};
|
||||
|
||||
bincode::deserialize(&data)
|
||||
.map(Some)
|
||||
.map_err(StorageError::from)
|
||||
}
|
||||
|
||||
fn get_auto_ptr<SE: StorageEntity<SB>>(&mut self, ptr: StorageEntryPtr)
|
||||
-> StorageAutoPtr<SB, SE>;
|
||||
|
||||
fn read_or_err<T: for<'de> Deserialize<'de>>(
|
||||
&mut self,
|
||||
ptr: StoragePtr<T>,
|
||||
) -> Result<T, StorageError<SB>> {
|
||||
match self.read(ptr)? {
|
||||
Some(data) => Ok(data),
|
||||
None => Err(StorageError::Error("Ptr not found".into())),
|
||||
}
|
||||
}
|
||||
|
||||
fn get_head<SE: StorageEntity<SB>>(
|
||||
&mut self,
|
||||
head_ptr: StorageHeadPtr,
|
||||
) -> Result<Option<SE>, StorageError<SB>> {
|
||||
let entry_ptr = match self.read(head_ptr)? {
|
||||
Some(entry_ptr) => entry_ptr,
|
||||
None => return Ok(None),
|
||||
};
|
||||
|
||||
let entry = match self.read(entry_ptr)? {
|
||||
Some(entry) => entry,
|
||||
None => return Ok(None),
|
||||
};
|
||||
|
||||
SE::from_storage_entry(self, entry).map(Some)
|
||||
}
|
||||
}
|
||||
|
||||
pub trait StorageTxMut<'a, SB: StorageBackend>: Sized {
|
||||
fn ref_deltas(&mut self) -> &mut HashMap<(u64, u64, u64), i64>;
|
||||
fn cache(&mut self) -> &mut HashMap<RcKey, StorageEntryPtr>;
|
||||
fn read_bytes<T>(&self, ptr: StoragePtr<T>) -> Result<Option<Vec<u8>>, StorageError<SB>>;
|
||||
@@ -32,10 +80,8 @@ pub trait StorageTx<'a, SB: StorageBackend>: Sized {
|
||||
.map_err(StorageError::from)
|
||||
}
|
||||
|
||||
fn get_auto_ptr<SE: for<'b> StorageEntity<'b, SB, SB::Tx<'b>>>(
|
||||
&mut self,
|
||||
ptr: StorageEntryPtr,
|
||||
) -> StorageAutoPtr<SB, SE>;
|
||||
fn get_auto_ptr<SE: StorageEntity<SB>>(&mut self, ptr: StorageEntryPtr)
|
||||
-> StorageAutoPtr<SB, SE>;
|
||||
|
||||
fn read_or_err<T: for<'de> Deserialize<'de>>(
|
||||
&mut self,
|
||||
@@ -60,7 +106,7 @@ pub trait StorageTx<'a, SB: StorageBackend>: Sized {
|
||||
self.write_bytes(ptr, bytes)
|
||||
}
|
||||
|
||||
fn get_head<SE: StorageEntity<'a, SB, Self>>(
|
||||
fn get_head<SE: StorageEntity<SB>>(
|
||||
&mut self,
|
||||
head_ptr: StorageHeadPtr,
|
||||
) -> Result<Option<SE>, StorageError<SB>> {
|
||||
@@ -77,7 +123,7 @@ pub trait StorageTx<'a, SB: StorageBackend>: Sized {
|
||||
SE::from_storage_entry(self, entry).map(Some)
|
||||
}
|
||||
|
||||
fn set_head<SE: StorageEntity<'a, SB, Self>>(
|
||||
fn set_head<SE: StorageEntity<SB>>(
|
||||
&mut self,
|
||||
head_ptr: StorageHeadPtr,
|
||||
value: &SE,
|
||||
@@ -100,7 +146,7 @@ pub trait StorageTx<'a, SB: StorageBackend>: Sized {
|
||||
self.write(head_ptr, None)
|
||||
}
|
||||
|
||||
fn store<SE: StorageEntity<'a, SB, Self>>(
|
||||
fn store<SE: StorageEntity<SB>>(
|
||||
&mut self,
|
||||
value: &SE,
|
||||
) -> Result<StorageEntryPtr, StorageError<SB>> {
|
||||
@@ -185,7 +231,7 @@ pub trait StorageTx<'a, SB: StorageBackend>: Sized {
|
||||
self.cache().get(&key).cloned()
|
||||
}
|
||||
|
||||
fn store_and_cache<SE: StorageEntity<'a, SB, Self>>(
|
||||
fn store_and_cache<SE: StorageEntity<SB>>(
|
||||
&mut self,
|
||||
value: &SE,
|
||||
key: RcKey,
|
||||
@@ -198,3 +244,16 @@ pub trait StorageTx<'a, SB: StorageBackend>: Sized {
|
||||
Ok(ptr)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, SB: StorageBackend, TxMut: StorageTxMut<'a, SB>> StorageTx<'a, SB> for TxMut {
|
||||
fn read_bytes<T>(&self, ptr: StoragePtr<T>) -> Result<Option<Vec<u8>>, StorageError<SB>> {
|
||||
TxMut::read_bytes(self, ptr)
|
||||
}
|
||||
|
||||
fn get_auto_ptr<SE: StorageEntity<SB>>(
|
||||
&mut self,
|
||||
ptr: StorageEntryPtr,
|
||||
) -> StorageAutoPtr<SB, SE> {
|
||||
TxMut::get_auto_ptr(self, ptr)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
use std::{cell::RefCell, collections::HashMap, fmt, ops::Index, rc::Rc, slice::SliceIndex};
|
||||
|
||||
use storage::{StorageBackend, StorageEntity, StorageError, StorageTx};
|
||||
use storage::{StorageBackend, StorageEntity, StorageError, StorageTx, StorageTxMut};
|
||||
|
||||
use crate::{bytecode_decoder::BytecodeDecoder, vs_value::Val};
|
||||
|
||||
@@ -45,8 +45,11 @@ impl DecoderMaker for Rc<Bytecode> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, SB: StorageBackend, Tx: StorageTx<'a, SB>> StorageEntity<'a, SB, Tx> for Bytecode {
|
||||
fn to_storage_entry(&self, _tx: &mut Tx) -> Result<storage::StorageEntry, StorageError<SB>> {
|
||||
impl<SB: StorageBackend> StorageEntity<SB> for Bytecode {
|
||||
fn to_storage_entry<'a, TxMut: StorageTxMut<'a, SB>>(
|
||||
&self,
|
||||
_tx: &mut TxMut,
|
||||
) -> Result<storage::StorageEntry, StorageError<SB>> {
|
||||
Ok(storage::StorageEntry {
|
||||
ref_count: 1,
|
||||
refs: vec![],
|
||||
@@ -54,7 +57,7 @@ impl<'a, SB: StorageBackend, Tx: StorageTx<'a, SB>> StorageEntity<'a, SB, Tx> fo
|
||||
})
|
||||
}
|
||||
|
||||
fn from_storage_entry(
|
||||
fn from_storage_entry<'a, Tx: StorageTx<'a, SB>>(
|
||||
_tx: &mut Tx,
|
||||
entry: storage::StorageEntry,
|
||||
) -> Result<Self, StorageError<SB>> {
|
||||
|
||||
@@ -5,7 +5,7 @@ use num_derive::{FromPrimitive, ToPrimitive};
|
||||
use num_traits::{FromPrimitive, ToPrimitive};
|
||||
use storage::{
|
||||
RcKey, StorageBackend, StorageEntity, StorageEntry, StorageEntryReader, StorageEntryWriter,
|
||||
StorageError, StorageTx,
|
||||
StorageError, StorageTx, StorageTxMut,
|
||||
};
|
||||
|
||||
use crate::{
|
||||
@@ -47,8 +47,11 @@ impl Tag {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, SB: StorageBackend + 'static, Tx: StorageTx<'a, SB>> StorageEntity<'a, SB, Tx> for Val {
|
||||
fn from_storage_entry(tx: &mut Tx, entry: StorageEntry) -> Result<Self, StorageError<SB>> {
|
||||
impl<SB: StorageBackend + 'static> StorageEntity<SB> for Val {
|
||||
fn from_storage_entry<'a, Tx: StorageTx<'a, SB>>(
|
||||
tx: &mut Tx,
|
||||
entry: StorageEntry,
|
||||
) -> Result<Self, StorageError<SB>> {
|
||||
let mut reader = StorageEntryReader::new(&entry);
|
||||
let res = read_from_entry(tx, &mut reader);
|
||||
assert!(reader.done());
|
||||
@@ -56,7 +59,10 @@ impl<'a, SB: StorageBackend + 'static, Tx: StorageTx<'a, SB>> StorageEntity<'a,
|
||||
res
|
||||
}
|
||||
|
||||
fn to_storage_entry(&self, tx: &mut Tx) -> Result<StorageEntry, StorageError<SB>> {
|
||||
fn to_storage_entry<'a, TxMut: StorageTxMut<'a, SB>>(
|
||||
&self,
|
||||
tx: &mut TxMut,
|
||||
) -> Result<StorageEntry, StorageError<SB>> {
|
||||
let mut entry = StorageEntry {
|
||||
ref_count: 1,
|
||||
refs: vec![],
|
||||
@@ -156,7 +162,7 @@ impl<'a, SB: StorageBackend + 'static, Tx: StorageTx<'a, SB>> StorageEntity<'a,
|
||||
}
|
||||
}
|
||||
|
||||
fn write_to_entry<'a, SB: StorageBackend + 'static, Tx: StorageTx<'a, SB>>(
|
||||
fn write_to_entry<'a, SB: StorageBackend + 'static, Tx: StorageTxMut<'a, SB>>(
|
||||
val: &Val,
|
||||
tx: &mut Tx,
|
||||
writer: &mut StorageEntryWriter,
|
||||
@@ -246,7 +252,7 @@ fn write_to_entry<'a, SB: StorageBackend + 'static, Tx: StorageTx<'a, SB>>(
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn write_ptr_to_entry<'a, SB: StorageBackend + 'static, Tx: StorageTx<'a, SB>>(
|
||||
fn write_ptr_to_entry<'a, SB: StorageBackend + 'static, Tx: StorageTxMut<'a, SB>>(
|
||||
tx: &mut Tx,
|
||||
writer: &mut StorageEntryWriter,
|
||||
key: RcKey,
|
||||
@@ -413,7 +419,7 @@ fn read_ref_bytecode_from_entry<'a, SB: StorageBackend, Tx: StorageTx<'a, SB>>(
|
||||
Ok(Rc::new(Bytecode::from_storage_entry(tx, entry)?))
|
||||
}
|
||||
|
||||
fn write_ref_bytecode_to_entry<'a, SB: StorageBackend, Tx: StorageTx<'a, SB>>(
|
||||
fn write_ref_bytecode_to_entry<'a, SB: StorageBackend, Tx: StorageTxMut<'a, SB>>(
|
||||
tx: &mut Tx,
|
||||
writer: &mut StorageEntryWriter,
|
||||
bytecode: &Rc<Bytecode>,
|
||||
|
||||
Reference in New Issue
Block a user