Skip to content

Commit

Permalink
Refactor: generic StoragePtrs
Browse files Browse the repository at this point in the history
  • Loading branch information
voltrevo committed Oct 26, 2023
1 parent fe918b0 commit 2529453
Show file tree
Hide file tree
Showing 7 changed files with 144 additions and 129 deletions.
4 changes: 2 additions & 2 deletions storage/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@ mod storage;

mod serde_rc;
mod sled_backend;
mod storage_key;
mod storage_ptr;
mod tests;

pub use self::storage::{Storage, StorageBackend};
pub use memory_backend::MemoryBackend;
pub use sled_backend::SledBackend;
pub use storage_key::StorageKey;
pub use storage_ptr::StoragePtr;
14 changes: 7 additions & 7 deletions storage/src/memory_backend.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@ use std::fmt::Debug as DebugTrait;

use crate::{
storage::{StorageBackend, StorageBackendHandle},
StorageKey,
StoragePtr,
};

pub struct MemoryBackend {
data: HashMap<StorageKey, Vec<u8>>,
data: HashMap<(u64, u64, u64), Vec<u8>>,
}

impl MemoryBackend {
Expand Down Expand Up @@ -37,14 +37,14 @@ pub struct MemoryStorageHandle<'a> {
}

impl<'a, E> StorageBackendHandle<'a, E> for MemoryStorageHandle<'a> {
fn read(&self, key: StorageKey) -> Result<Option<Vec<u8>>, E> {
Ok(self.storage.data.get(&key).cloned())
fn read<T>(&self, key: StoragePtr<T>) -> Result<Option<Vec<u8>>, E> {
Ok(self.storage.data.get(&key.data).cloned())
}

fn write(&mut self, key: StorageKey, data: Option<Vec<u8>>) -> Result<(), E> {
fn write<T>(&mut self, key: StoragePtr<T>, data: Option<Vec<u8>>) -> Result<(), E> {
match data {
Some(data) => self.storage.data.insert(key, data),
None => self.storage.data.remove(&key),
Some(data) => self.storage.data.insert(key.data, data),
None => self.storage.data.remove(&key.data),
};

Ok(())
Expand Down
10 changes: 5 additions & 5 deletions storage/src/sled_backend.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use std::fmt::Debug as DebugTrait;

use crate::{
storage::{StorageBackend, StorageBackendHandle},
StorageKey,
StoragePtr,
};

pub struct SledBackend {
Expand Down Expand Up @@ -49,17 +49,17 @@ pub struct SledBackendHandle<'a> {
impl<'a, E> StorageBackendHandle<'a, sled::transaction::ConflictableTransactionError<E>>
for SledBackendHandle<'a>
{
fn read(
fn read<T>(
&self,
key: StorageKey,
key: StoragePtr<T>,
) -> Result<Option<Vec<u8>>, sled::transaction::ConflictableTransactionError<E>> {
let value = self.tx.get(key.to_bytes())?.map(|value| value.to_vec());
Ok(value)
}

fn write(
fn write<T>(
&mut self,
key: StorageKey,
key: StoragePtr<T>,
data: Option<Vec<u8>>,
) -> Result<(), sled::transaction::ConflictableTransactionError<E>> {
match data {
Expand Down
116 changes: 50 additions & 66 deletions storage/src/storage.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,36 +4,33 @@ use rand::thread_rng;
use serde::{Deserialize, Serialize};

use crate::serde_rc::{deserialize_rc, serialize_rc};
use crate::storage_key::StorageKey;
use crate::storage_ptr::{tmp_at_ptr, tmp_count_ptr, StorageEntryPtr, StorageHeadPtr, StoragePtr};

pub struct Storage<SB: StorageBackend> {
sb: SB,
}

pub trait StorageBackendHandle<'a, E> {
fn read(&self, key: StorageKey) -> Result<Option<Vec<u8>>, E>;
fn write(&mut self, key: StorageKey, data: Option<Vec<u8>>) -> Result<(), E>;
fn read<T>(&self, key: StoragePtr<T>) -> Result<Option<Vec<u8>>, E>;
fn write<T>(&mut self, key: StoragePtr<T>, data: Option<Vec<u8>>) -> Result<(), E>;
}

pub trait StorageOps<E> {
fn read_entry(&mut self, key: StorageKey) -> Result<Option<StorageEntry>, E>;
fn write_entry(&mut self, key: StorageKey, data: Option<&StorageEntry>) -> Result<(), E>;
fn read_t<T: for<'de> Deserialize<'de>>(&mut self, key: StoragePtr<T>) -> Result<Option<T>, E>;
fn write_t<T: Serialize>(&mut self, key: StoragePtr<T>, data: Option<&T>) -> Result<(), E>;

fn inc_ref(&mut self, key: StorageKey) -> Result<(), E>;
fn dec_ref(&mut self, key: StorageKey) -> Result<(), E>;
fn inc_ref(&mut self, key: StorageEntryPtr) -> Result<(), E>;
fn dec_ref(&mut self, key: StorageEntryPtr) -> Result<(), E>;

fn get_head_key(&mut self, name: &[u8]) -> Result<Option<StorageKey>, E>;
fn set_head_key(&mut self, name: &[u8], key: Option<&StorageKey>) -> Result<(), E>;

fn get_head(&mut self, name: &[u8]) -> Result<Option<StorageVal>, E>;
fn set_head(&mut self, name: &[u8], value: Option<&StorageVal>) -> Result<(), E>;
fn get_head(&mut self, ptr: StorageHeadPtr) -> Result<Option<StorageVal>, E>;
fn set_head(&mut self, ptr: StorageHeadPtr, value: Option<&StorageVal>) -> Result<(), E>;
}

impl<'a, T, E> StorageOps<E> for T
impl<'a, Handle, E> StorageOps<E> for Handle
where
T: StorageBackendHandle<'a, E>,
Handle: StorageBackendHandle<'a, E>,
{
fn read_entry(&mut self, key: StorageKey) -> Result<Option<StorageEntry>, E> {
fn read_t<T: for<'de> Deserialize<'de>>(&mut self, key: StoragePtr<T>) -> Result<Option<T>, E> {
let data = match self.read(key)? {
Some(data) => data,
None => return Ok(None),
Expand All @@ -42,23 +39,23 @@ where
Ok(Some(bincode::deserialize(&data).unwrap()))
}

fn write_entry(&mut self, key: StorageKey, data: Option<&StorageEntry>) -> Result<(), E> {
fn write_t<T: Serialize>(&mut self, key: StoragePtr<T>, data: Option<&T>) -> Result<(), E> {
self.write(key, data.map(|data| bincode::serialize(&data).unwrap()))
}

fn inc_ref(&mut self, key: StorageKey) -> Result<(), E> {
let mut entry = match self.read_entry(key)? {
fn inc_ref(&mut self, key: StorageEntryPtr) -> Result<(), E> {
let mut entry = match self.read_t(key)? {
Some(entry) => entry,
None => panic!("Key does not exist"),
};

entry.ref_count += 1;

self.write_entry(key, Some(&entry))
self.write_t(key, Some(&entry))
}

fn dec_ref(&mut self, key: StorageKey) -> Result<(), E> {
let mut entry = match self.read_entry(key)? {
fn dec_ref(&mut self, key: StorageEntryPtr) -> Result<(), E> {
let mut entry = match self.read_t(key)? {
Some(entry) => entry,
None => panic!("Key does not exist"),
};
Expand All @@ -72,23 +69,12 @@ where

self.write(key, None)
} else {
self.write_entry(key, Some(&entry))
}
}

fn get_head_key(&mut self, name: &[u8]) -> Result<Option<StorageKey>, E> {
match self.read(StorageKey::from_bytes(name))? {
Some(key_bytes) => Ok(Some(StorageKey::from_bytes(&key_bytes))),
None => Ok(None),
self.write_t(key, Some(&entry))
}
}

fn set_head_key(&mut self, name: &[u8], key: Option<&StorageKey>) -> Result<(), E> {
self.write(StorageKey::from_bytes(name), key.map(|key| key.to_bytes()))
}

fn get_head(&mut self, name: &[u8]) -> Result<Option<StorageVal>, E> {
let key = match self.get_head_key(name)? {
fn get_head(&mut self, ptr: StorageHeadPtr) -> Result<Option<StorageVal>, E> {
let key = match self.read_t(ptr)? {
Some(key) => key,
None => return Ok(None),
};
Expand All @@ -105,9 +91,9 @@ where
))
}

fn set_head(&mut self, name: &[u8], value: Option<&StorageVal>) -> Result<(), E> {
fn set_head(&mut self, ptr: StorageHeadPtr, value: Option<&StorageVal>) -> Result<(), E> {
if let Some(value) = value {
let key = StorageKey::random(&mut thread_rng());
let key = StoragePtr::random(&mut thread_rng());
self.write(key, Some(bincode::serialize(&value.serialize()).unwrap()))?;

{
Expand All @@ -117,18 +103,18 @@ where
self.inc_ref(*subkey)?;
}

if let Some(old_key) = self.get_head_key(name)? {
if let Some(old_key) = self.read_t(ptr)? {
self.dec_ref(old_key)?;
}
}

self.set_head_key(name, Some(&key))
self.write_t(ptr, Some(&key))
} else {
if let Some(old_key) = self.get_head_key(name)? {
if let Some(old_key) = self.read_t(ptr)? {
self.dec_ref(old_key)?;
}

self.set_head_key(name, None)
self.write_t(ptr, None)
}
}
}
Expand All @@ -148,28 +134,29 @@ impl<SB: StorageBackend> Storage<SB> {
Self { sb }
}

pub fn get_head(&mut self, name: &[u8]) -> Result<Option<StorageVal>, SB::Error<()>> {
self.sb.transaction(|sb| sb.get_head(name))
pub fn get_head(&mut self, ptr: StorageHeadPtr) -> Result<Option<StorageVal>, SB::Error<()>> {
self.sb.transaction(|sb| sb.get_head(ptr))
}

pub fn set_head(&mut self, name: &[u8], value: Option<&StorageVal>) -> Result<(), SB::Error<()>> {
self.sb.transaction(|sb| sb.set_head(name, value))
pub fn set_head(
&mut self,
ptr: StorageHeadPtr,
value: Option<&StorageVal>,
) -> Result<(), SB::Error<()>> {
self.sb.transaction(|sb| sb.set_head(ptr, value))
}

pub fn store_tmp(&mut self, value: &StorageVal) -> Result<StorageKey, SB::Error<()>> {
pub fn store_tmp(&mut self, value: &StorageVal) -> Result<StorageEntryPtr, SB::Error<()>> {
self.sb.transaction(|sb| {
let key = StorageKey::random(&mut thread_rng());
let key = StoragePtr::random(&mut thread_rng());
sb.write(key, Some(bincode::serialize(value).unwrap()))?;

let tmp_count = sb
.read(StorageKey::tmp_count())?
.map(|data| bincode::deserialize::<u64>(&data).unwrap())
.unwrap_or(0);
let tmp_count = sb.read_t(tmp_count_ptr())?.unwrap_or(0);

sb.write(StorageKey::tmp_at(tmp_count), Some(key.to_bytes()))?;
sb.write(tmp_at_ptr(tmp_count), Some(key.to_bytes()))?;

sb.write(
StorageKey::tmp_count(),
tmp_count_ptr(),
Some(bincode::serialize(&(tmp_count + 1)).unwrap()),
)?;

Expand All @@ -179,22 +166,19 @@ impl<SB: StorageBackend> Storage<SB> {

pub fn clear_tmp(&mut self) -> Result<(), SB::Error<()>> {
self.sb.transaction(|sb| {
let tmp_count = sb
.read(StorageKey::tmp_count())?
.map(|data| bincode::deserialize::<u64>(&data).unwrap())
.unwrap_or(0);
let tmp_count = sb.read_t(tmp_count_ptr())?.unwrap_or(0);

for i in 0..tmp_count {
let tmp_key = StorageKey::tmp_at(i);
let key_bytes = sb
.read(tmp_key)?
.unwrap_or_else(|| panic!("Missing tmp key: {:?}", tmp_key));
let tmp_key = tmp_at_ptr(i);

let entry_ptr = sb
.read_t(tmp_key)?
.unwrap_or_else(|| panic!("Missing tmp key"));

let key = StorageKey::from_bytes(&key_bytes);
sb.dec_ref(key)?;
sb.dec_ref(entry_ptr)?;
}

sb.write(StorageKey::tmp_count(), None)?;
sb.write(tmp_count_ptr(), None)?;

Ok(())
})
Expand All @@ -206,7 +190,7 @@ pub struct StorageEntry {
ref_count: u64,

#[serde(serialize_with = "serialize_rc", deserialize_with = "deserialize_rc")]
refs: Rc<Vec<StorageKey>>,
refs: Rc<Vec<StorageEntryPtr>>,

data: Vec<u8>,
}
Expand All @@ -228,7 +212,7 @@ pub struct StorageVal {
pub point: StoragePoint,

#[serde(serialize_with = "serialize_rc", deserialize_with = "deserialize_rc")]
pub refs: Rc<Vec<StorageKey>>,
pub refs: Rc<Vec<StorageEntryPtr>>,
}

impl StorageEntry {
Expand Down
38 changes: 0 additions & 38 deletions storage/src/storage_key.rs

This file was deleted.

Loading

0 comments on commit 2529453

Please sign in to comment.