Skip to content

Commit

Permalink
Rename things and test cleanup in array_0_1
Browse files Browse the repository at this point in the history
  • Loading branch information
voltrevo committed Oct 26, 2023
1 parent 2529453 commit 024f6de
Show file tree
Hide file tree
Showing 4 changed files with 65 additions and 48 deletions.
4 changes: 2 additions & 2 deletions storage/src/memory_backend.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,11 +37,11 @@ pub struct MemoryStorageHandle<'a> {
}

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

fn write<T>(&mut self, key: StoragePtr<T>, data: Option<Vec<u8>>) -> Result<(), E> {
fn write_bytes<T>(&mut self, key: StoragePtr<T>, data: Option<Vec<u8>>) -> Result<(), E> {
match data {
Some(data) => self.storage.data.insert(key.data, data),
None => self.storage.data.remove(&key.data),
Expand Down
4 changes: 2 additions & 2 deletions storage/src/sled_backend.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,15 +49,15 @@ pub struct SledBackendHandle<'a> {
impl<'a, E> StorageBackendHandle<'a, sled::transaction::ConflictableTransactionError<E>>
for SledBackendHandle<'a>
{
fn read<T>(
fn read_bytes<T>(
&self,
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<T>(
fn write_bytes<T>(
&mut self,
key: StoragePtr<T>,
data: Option<Vec<u8>>,
Expand Down
74 changes: 39 additions & 35 deletions storage/src/storage.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,13 @@ pub struct Storage<SB: StorageBackend> {
}

pub trait StorageBackendHandle<'a, 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>;
fn read_bytes<T>(&self, key: StoragePtr<T>) -> Result<Option<Vec<u8>>, E>;
fn write_bytes<T>(&mut self, key: StoragePtr<T>, data: Option<Vec<u8>>) -> Result<(), E>;
}

pub trait StorageOps<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 read<T: for<'de> Deserialize<'de>>(&mut self, key: StoragePtr<T>) -> Result<Option<T>, E>;
fn write<T: Serialize>(&mut self, key: StoragePtr<T>, data: Option<&T>) -> Result<(), E>;

fn inc_ref(&mut self, key: StorageEntryPtr) -> Result<(), E>;
fn dec_ref(&mut self, key: StorageEntryPtr) -> Result<(), E>;
Expand All @@ -30,32 +30,32 @@ impl<'a, Handle, E> StorageOps<E> for Handle
where
Handle: StorageBackendHandle<'a, E>,
{
fn read_t<T: for<'de> Deserialize<'de>>(&mut self, key: StoragePtr<T>) -> Result<Option<T>, E> {
let data = match self.read(key)? {
fn read<T: for<'de> Deserialize<'de>>(&mut self, key: StoragePtr<T>) -> Result<Option<T>, E> {
let data = match self.read_bytes(key)? {
Some(data) => data,
None => return Ok(None),
};

Ok(Some(bincode::deserialize(&data).unwrap()))
}

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 write<T: Serialize>(&mut self, key: StoragePtr<T>, data: Option<&T>) -> Result<(), E> {
self.write_bytes(key, data.map(|data| bincode::serialize(&data).unwrap()))
}

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

entry.ref_count += 1;

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

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

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

fn get_head(&mut self, ptr: StorageHeadPtr) -> Result<Option<StorageVal>, E> {
let key = match self.read_t(ptr)? {
let key = match self.read(ptr)? {
Some(key) => key,
None => return Ok(None),
};

let data = match self.read(key)? {
let data = match self.read_bytes(key)? {
Some(data) => data,
None => panic!("Head points to non-existent key"),
};
Expand All @@ -94,7 +94,7 @@ where
fn set_head(&mut self, ptr: StorageHeadPtr, value: Option<&StorageVal>) -> Result<(), E> {
if let Some(value) = value {
let key = StoragePtr::random(&mut thread_rng());
self.write(key, Some(bincode::serialize(&value.serialize()).unwrap()))?;
self.write_bytes(key, Some(bincode::serialize(&value.serialize()).unwrap()))?;

{
// TODO: Performance: Identify overlapping keys and cancel out the inc+dec
Expand All @@ -103,18 +103,18 @@ where
self.inc_ref(*subkey)?;
}

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

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

self.write_t(ptr, None)
self.write(ptr, None)
}
}
}
Expand Down Expand Up @@ -148,41 +148,45 @@ impl<SB: StorageBackend> Storage<SB> {

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

let tmp_count = sb.read_t(tmp_count_ptr())?.unwrap_or(0);

sb.write(tmp_at_ptr(tmp_count), Some(key.to_bytes()))?;
let tmp_count = sb.read(tmp_count_ptr())?.unwrap_or(0);
let tmp_ptr = tmp_at_ptr(tmp_count);
sb.set_head(tmp_ptr, Some(value))?;

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

let key = sb
.read(tmp_ptr)?
.unwrap_or_else(|| panic!("Missing tmp key"));

Ok(key)
})
}

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

for i in 0..tmp_count {
let tmp_key = tmp_at_ptr(i);

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

sb.dec_ref(entry_ptr)?;
sb.set_head(tmp_at_ptr(i), None)?;
}

sb.write(tmp_count_ptr(), None)?;

Ok(())
})
}

pub(crate) fn get_ref_count(
&mut self,
key: StorageEntryPtr,
) -> Result<Option<u64>, SB::Error<()>> {
self
.sb
.transaction(|sb| Ok(sb.read(key)?.map(|entry| entry.ref_count)))
}
}

#[derive(Serialize, Deserialize)]
Expand Down
31 changes: 22 additions & 9 deletions storage/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,15 +58,28 @@ mod tests_ {
})
.unwrap();

// storage
// .set_head(
// b"test",
// Some(&StorageVal {
// point: StoragePoint::Array(Rc::new(vec![StoragePoint::Ref(0), StoragePoint::Ref(1)])),
// refs: Rc::new(vec![key0, key1]),
// }),
// )
// .unwrap();
storage
.set_head(
storage_head_ptr(b"test"),
Some(&StorageVal {
point: StoragePoint::Array(Rc::new(vec![StoragePoint::Ref(0), StoragePoint::Ref(1)])),
refs: Rc::new(vec![key0, key1]),
}),
)
.unwrap();

assert_eq!(storage.get_ref_count(key0).unwrap(), Some(2));
assert_eq!(storage.get_ref_count(key1).unwrap(), Some(2));

storage.clear_tmp().unwrap();

assert_eq!(storage.get_ref_count(key0).unwrap(), Some(1));
assert_eq!(storage.get_ref_count(key1).unwrap(), Some(1));

storage.set_head(storage_head_ptr(b"test"), None).unwrap();

assert_eq!(storage.get_ref_count(key0).unwrap(), None);
assert_eq!(storage.get_ref_count(key1).unwrap(), None);
}

run(impl_, impl_);
Expand Down

0 comments on commit 024f6de

Please sign in to comment.