Replace RocksDB with LevelDB
This commit is contained in:
parent
f1584dada4
commit
7d067926dd
@ -4,12 +4,16 @@ version = "0.1.0"
|
||||
authors = ["Paul Hauner <paul@paulhauner.com>"]
|
||||
edition = "2018"
|
||||
|
||||
[dev-dependencies]
|
||||
tempfile = "3"
|
||||
|
||||
[dependencies]
|
||||
blake2-rfc = "0.2.18"
|
||||
bls = { path = "../../eth2/utils/bls" }
|
||||
bytes = "0.4.10"
|
||||
db-key = "0.0.5"
|
||||
leveldb = "0.8.4"
|
||||
parking_lot = "0.7"
|
||||
rocksdb = "0.10.1"
|
||||
ssz = { path = "../../eth2/utils/ssz" }
|
||||
ssz_derive = { path = "../../eth2/utils/ssz_derive" }
|
||||
tree_hash = { path = "../../eth2/utils/tree_hash" }
|
||||
|
100
beacon_node/db/src/leveldb_store.rs
Normal file
100
beacon_node/db/src/leveldb_store.rs
Normal file
@ -0,0 +1,100 @@
|
||||
use super::*;
|
||||
use db_key::Key;
|
||||
use leveldb::database::kv::KV;
|
||||
use leveldb::database::Database;
|
||||
use leveldb::error::Error as LevelDBError;
|
||||
use leveldb::options::{Options, ReadOptions, WriteOptions};
|
||||
use parking_lot::RwLock;
|
||||
use std::path::Path;
|
||||
|
||||
pub struct LevelDB<K: Key> {
|
||||
db: RwLock<Database<K>>,
|
||||
}
|
||||
|
||||
impl<K: Key> LevelDB<K> {
|
||||
pub fn open(path: &Path) -> Result<Self, Error> {
|
||||
let mut options = Options::new();
|
||||
|
||||
options.create_if_missing = true;
|
||||
|
||||
let db = Database::open(path, options)?;
|
||||
|
||||
Ok(Self {
|
||||
db: RwLock::new(db),
|
||||
})
|
||||
}
|
||||
|
||||
fn read_options(&self) -> ReadOptions<K> {
|
||||
ReadOptions::new()
|
||||
}
|
||||
|
||||
fn write_options(&self) -> WriteOptions {
|
||||
WriteOptions::new()
|
||||
}
|
||||
|
||||
fn get_key_for_col(col: &str, key: &[u8]) -> BytesKey {
|
||||
let mut col = col.as_bytes().to_vec();
|
||||
col.append(&mut key.to_vec());
|
||||
BytesKey { key: col }
|
||||
}
|
||||
}
|
||||
|
||||
pub struct BytesKey {
|
||||
key: Vec<u8>,
|
||||
}
|
||||
|
||||
impl Key for BytesKey {
|
||||
fn from_u8(key: &[u8]) -> Self {
|
||||
Self { key: key.to_vec() }
|
||||
}
|
||||
|
||||
fn as_slice<T, F: Fn(&[u8]) -> T>(&self, f: F) -> T {
|
||||
f(self.key.as_slice())
|
||||
}
|
||||
}
|
||||
|
||||
impl Store for LevelDB<BytesKey> {
|
||||
fn get_bytes(&self, col: &str, key: &[u8]) -> Result<Option<DBValue>, Error> {
|
||||
let column_key = Self::get_key_for_col(col, key);
|
||||
|
||||
self.db
|
||||
.read()
|
||||
.get(self.read_options(), column_key)
|
||||
.map_err(Into::into)
|
||||
}
|
||||
|
||||
fn put_bytes(&self, col: &str, key: &[u8], val: &[u8]) -> Result<(), Error> {
|
||||
let column_key = Self::get_key_for_col(col, key);
|
||||
|
||||
self.db
|
||||
.write()
|
||||
.put(self.write_options(), column_key, val)
|
||||
.map_err(Into::into)
|
||||
}
|
||||
|
||||
fn key_exists(&self, col: &str, key: &[u8]) -> Result<bool, Error> {
|
||||
let column_key = Self::get_key_for_col(col, key);
|
||||
|
||||
self.db
|
||||
.read()
|
||||
.get(self.read_options(), column_key)
|
||||
.map_err(Into::into)
|
||||
.and_then(|val| Ok(val.is_some()))
|
||||
}
|
||||
|
||||
fn key_delete(&self, col: &str, key: &[u8]) -> Result<(), Error> {
|
||||
let column_key = Self::get_key_for_col(col, key);
|
||||
self.db
|
||||
.write()
|
||||
.delete(self.write_options(), column_key)
|
||||
.map_err(Into::into)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<LevelDBError> for Error {
|
||||
fn from(e: LevelDBError) -> Error {
|
||||
Error::DBError {
|
||||
message: format!("{:?}", e),
|
||||
}
|
||||
}
|
||||
}
|
@ -2,8 +2,10 @@
|
||||
mod block_at_slot;
|
||||
mod errors;
|
||||
mod impls;
|
||||
mod leveldb_store;
|
||||
mod memory_db;
|
||||
|
||||
pub use self::leveldb_store::LevelDB;
|
||||
pub use self::memory_db::MemoryDB;
|
||||
pub use errors::Error;
|
||||
pub use types::*;
|
||||
@ -106,6 +108,7 @@ mod tests {
|
||||
use super::*;
|
||||
use ssz::{Decode, Encode};
|
||||
use ssz_derive::{Decode, Encode};
|
||||
use tempfile::tempdir;
|
||||
|
||||
#[derive(PartialEq, Debug, Encode, Decode)]
|
||||
struct StorableThing {
|
||||
@ -127,6 +130,23 @@ mod tests {
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn leveldb_can_store_and_retrieve() {
|
||||
let dir = tempdir().unwrap();
|
||||
let path = dir.path();
|
||||
|
||||
let store = LevelDB::open(&path).unwrap();
|
||||
|
||||
let key = Hash256::random();
|
||||
let item = StorableThing { a: 1, b: 42 };
|
||||
|
||||
store.put(&key, &item).unwrap();
|
||||
|
||||
let retrieved = store.get(&key).unwrap().unwrap();
|
||||
|
||||
assert_eq!(item, retrieved);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn memorydb_can_store_and_retrieve() {
|
||||
let store = MemoryDB::open();
|
||||
|
Loading…
Reference in New Issue
Block a user