Skip to content

Commit

Permalink
feat(host): Add TryFrom<DiskKeyValueStore> for MemoryKeyValueStore (
Browse files Browse the repository at this point in the history
  • Loading branch information
clabby committed Sep 6, 2024
1 parent c653800 commit 994268e
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 1 deletion.
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions bin/host/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -42,3 +42,6 @@ tracing-subscriber.workspace = true
command-fds.workspace = true
os_pipe.workspace = true
rocksdb.workspace = true

[dev-dependencies]
proptest.workspace = true
51 changes: 50 additions & 1 deletion bin/host/src/kv/disk.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
//! Contains a concrete implementation of the [KeyValueStore] trait that stores data on disk
//! using [rocksdb].

use super::KeyValueStore;
use super::{KeyValueStore, MemoryKeyValueStore};
use alloy_primitives::B256;
use anyhow::{anyhow, Result};
use rocksdb::{Options, DB};
use std::path::PathBuf;
Expand Down Expand Up @@ -46,3 +47,51 @@ impl Drop for DiskKeyValueStore {
let _ = DB::destroy(&Self::get_db_options(), self.data_directory.as_path());
}
}

impl TryFrom<DiskKeyValueStore> for MemoryKeyValueStore {
type Error = anyhow::Error;

fn try_from(disk_store: DiskKeyValueStore) -> Result<MemoryKeyValueStore> {
let mut memory_store = MemoryKeyValueStore::new();
let mut db_iter = disk_store.db.full_iterator(rocksdb::IteratorMode::Start);

while let Some(Ok((key, value))) = db_iter.next() {
memory_store.set(
B256::try_from(key.as_ref())
.map_err(|e| anyhow!("Failed to convert slice to B256: {e}"))?,
value.to_vec(),
)?;
}

Ok(memory_store)
}
}

#[cfg(test)]
mod test {
use super::DiskKeyValueStore;
use crate::kv::{KeyValueStore, MemoryKeyValueStore};
use proptest::{
arbitrary::any,
collection::{hash_map, vec},
proptest,
};
use std::env::temp_dir;

proptest! {
/// Test that converting from a [DiskKeyValueStore] to a [MemoryKeyValueStore] is lossless.
#[test]
fn convert_disk_kv_to_mem_kv(k_v in hash_map(any::<[u8; 32]>(), vec(any::<u8>(), 0..128), 1..128)) {
let tempdir = temp_dir();
let mut disk_kv = DiskKeyValueStore::new(tempdir);
k_v.iter().for_each(|(k, v)| {
disk_kv.set(k.into(), v.to_vec()).unwrap();
});

let mem_kv = MemoryKeyValueStore::try_from(disk_kv).unwrap();
for (k, v) in k_v {
assert_eq!(mem_kv.get(k.into()).unwrap(), v.to_vec());
}
}
}
}

0 comments on commit 994268e

Please sign in to comment.