extern crate bincode;
extern crate rocksdb;
extern crate serde;
use serde::{de::DeserializeOwned, Serialize, ser::SerializeSeq, Serializer, Deserializer, de::Visitor, de::SeqAccess, de::value::SeqDeserializer, de::value::U8Deserializer};
use std::borrow::Borrow;
use std::error;
use std::fmt;
use std::marker::PhantomData;
use std::path::Path;
use std::sync::Arc;
#[derive(Debug)]
pub enum ErrorKind {
Bincode(bincode::Error),
Rocksdb(rocksdb::Error),
}
pub type Error = Box<ErrorKind>;
type Result<T> = ::std::result::Result<T, Error>;
impl From<bincode::Error> for Error {
fn from(e: bincode::Error) -> Error {
Box::new(ErrorKind::Bincode(e))
}
}
impl From<rocksdb::Error> for Error {
fn from(e: rocksdb::Error) -> Error {
Box::new(ErrorKind::Rocksdb(e))
}
}
impl fmt::Display for Error {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match **self {
ErrorKind::Bincode(ref e) => write!(f, "bincode error: {}", e),
ErrorKind::Rocksdb(ref e) => write!(f, "rocksdb error: {}", e),
}
}
}
impl error::Error for Error {
fn source(&self) -> Option<&(dyn error::Error + 'static)> {
match **self {
ErrorKind::Bincode(ref e) => Some(e),
ErrorKind::Rocksdb(ref e) => Some(e),
}
}
}
#[derive(Clone)]
pub struct DB {
db: Arc<rocksdb::DB>,
}
impl DB {
pub fn open<P: AsRef<Path>>(path: P) -> Result<DB> {
Ok(DB {
db: Arc::new(rocksdb::DB::open_default(path)?),
})
}
pub fn prefix<K: Serialize + DeserializeOwned, V: Serialize + DeserializeOwned>(
&self,
prefix: &[u8],
) -> Result<Prefix<K, V>> {
let mut prefix_vec = bincode::serialize(&(prefix.len() as u32)).unwrap();
prefix_vec.extend_from_slice(&prefix);
Ok(Prefix {
db: self.db.clone(),
prefix: prefix_vec,
_k: PhantomData,
_v: PhantomData,
})
}
pub fn prefix_group(&self, prefix: &[u8]) -> Result<PrefixGroup> {
let mut prefix_vec = bincode::serialize(&(prefix.len() as u32)).unwrap();
prefix_vec.extend_from_slice(&prefix);
Ok(PrefixGroup {
db: self.db.clone(),
prefix: prefix_vec,
})
}
pub fn import<'de, D: Deserializer<'de>>(&self, deserializer: D) -> std::result::Result<(), D::Error> {
let visitor = DBVisitor { db: self.clone() };
deserializer.deserialize_seq(visitor)?;
Ok(())
}
}
struct DBVisitor {
db: DB,
}
impl<'de> Visitor<'de> for DBVisitor {
type Value = ();
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
write!(formatter, "a database seq")
}
fn visit_seq<A>(self, mut map: A) -> std::result::Result<(), A::Error>
where A: SeqAccess<'de>
{
while let Some((key, value)) = map.next_element::<(Vec<_>, Vec<_>)>()? {
self.db.db.put(&key, &value).map_err(|e| serde::de::Error::custom(e))?;
}
Ok(())
}
}
impl Serialize for DB {
fn serialize<S: Serializer>(&self, serializer: S) -> std::result::Result<S::Ok, S::Error> {
let mut iter = self.db.raw_iterator();
iter.seek_to_first();
let mut map = serializer.serialize_seq(None)?;
while iter.valid() {
if let (Some(key), Some(value)) = (iter.key(), iter.value()) {
map.serialize_element(&(key,value))?;
}
iter.next();
}
map.end()
}
}
#[derive(Clone)]
pub struct PrefixGroup {
db: Arc<rocksdb::DB>,
prefix: Vec<u8>,
}
impl PrefixGroup {
pub fn prefix<K: Serialize + DeserializeOwned, V: Serialize + DeserializeOwned>(
&self,
prefix: &[u8],
) -> Result<Prefix<K, V>> {
let mut prefix_vec = self.prefix.clone();
bincode::serialize_into(&mut prefix_vec, &(prefix.len() as u32))?;
prefix_vec.extend_from_slice(&prefix);
Ok(Prefix {
db: self.db.clone(),
prefix: prefix_vec,
_k: PhantomData,
_v: PhantomData,
})
}
pub fn prefix_group(&self, prefix: &[u8]) -> Result<PrefixGroup> {
let mut prefix_vec = self.prefix.clone();
bincode::serialize_into(&mut prefix_vec, &(prefix.len() as u32))?;
prefix_vec.extend_from_slice(&prefix);
Ok(PrefixGroup {
db: self.db.clone(),
prefix: prefix_vec,
})
}
}
#[derive(Clone)]
pub struct Prefix<K, V> {
db: Arc<rocksdb::DB>,
prefix: Vec<u8>,
_k: PhantomData<K>,
_v: PhantomData<V>,
}
impl<K: Serialize + DeserializeOwned, V: Serialize + DeserializeOwned> Prefix<K, V> {
pub fn get<Q>(&self, key: &Q) -> Result<Option<V>>
where
K: Borrow<Q>,
Q: Serialize + ?Sized,
{
let mut key_buf = self.prefix.clone();
key_buf.reserve(bincode::serialized_size(&key)? as usize);
bincode::serialize_into(&mut key_buf, &key)?;
match self.db.get(&key_buf)? {
Some(data) => Ok(Some(bincode::deserialize(&data)?)),
None => Ok(None),
}
}
pub fn insert<Q>(&self, key: &Q, value: &V) -> Result<()>
where
K: Borrow<Q>,
Q: Serialize + ?Sized,
{
let mut key_buf = self.prefix.clone();
key_buf.reserve(bincode::serialized_size(&key)? as usize);
bincode::serialize_into(&mut key_buf, &key)?;
let value_buf = bincode::serialize(value)?;
self.db.put(&key_buf, &value_buf)?;
Ok(())
}
pub fn remove<Q>(&self, key: &Q) -> Result<()>
where
K: Borrow<Q>,
Q: Serialize + ?Sized,
{
let mut key_buf = self.prefix.clone();
key_buf.reserve(bincode::serialized_size(&key)? as usize);
bincode::serialize_into(&mut key_buf, &key)?;
self.db.delete(&key_buf)?;
Ok(())
}
pub fn contains_key<Q>(&self, key: &Q) -> Result<bool>
where
K: Borrow<Q>,
Q: Serialize + ?Sized,
{
self.get(key).map(|v| v.is_some()) }
pub fn modify<Q, F: FnOnce(&mut V)>(&self, key: &Q, f: F) -> Result<()>
where
K: Borrow<Q>,
Q: Serialize + ?Sized,
{
match self.get(key)? {
Some(mut value) => {
f(&mut value);
self.insert(&key, &value)
}
None => Ok(()),
}
}
pub fn iter(&self) -> Iter<K, V> {
let mut db_iter = self.db.raw_iterator();
db_iter.seek(&self.prefix);
Iter {
db_iter,
prefix: self.prefix.clone(),
_k: PhantomData,
_v: PhantomData,
}
}
pub fn keys(&self) -> Keys<K> {
let mut db_iter = self.db.raw_iterator();
db_iter.seek(&self.prefix);
Keys {
db_iter,
prefix: self.prefix.clone(),
_k: PhantomData,
}
}
pub fn values(&self) -> Values<V> {
let mut db_iter = self.db.raw_iterator();
db_iter.seek(&self.prefix);
Values {
db_iter,
prefix: self.prefix.clone(),
_v: PhantomData,
}
}
}
pub struct Iter<K, V> {
db_iter: rocksdb::DBRawIterator,
prefix: Vec<u8>,
_k: PhantomData<K>,
_v: PhantomData<V>,
}
impl<K: DeserializeOwned, V: DeserializeOwned> Iterator for Iter<K, V> {
type Item = Result<(K, V)>;
fn next(&mut self) -> Option<Self::Item> {
if self.db_iter.valid() {
let k =
unsafe {self.db_iter.key_inner()}
.and_then(|k| if &k[0..self.prefix.len()] == &self.prefix[..] { Some(k) } else { None } )
.map(|k| bincode::deserialize(&k[self.prefix.len()..]));
let v =
unsafe {self.db_iter.value_inner()}
.map(|k| bincode::deserialize(k));
self.db_iter.next();
k.and_then(|k| v.map(|v| Ok((k?, v?))))
} else {
None
}
}
}
pub struct Keys<K> {
db_iter: rocksdb::DBRawIterator,
prefix: Vec<u8>,
_k: PhantomData<K>,
}
impl<K: DeserializeOwned> Iterator for Keys<K> {
type Item = Result<K>;
fn next(&mut self) -> Option<Self::Item> {
if self.db_iter.valid() {
let k =
unsafe {self.db_iter.key_inner()}
.and_then(|k| if &k[0..self.prefix.len()] == &self.prefix[..] { Some(k) } else { None } )
.map(|k| Ok(bincode::deserialize(&k[self.prefix.len()..])?));
self.db_iter.next();
k
} else {
None
}
}
}
pub struct Values<V> {
db_iter: rocksdb::DBRawIterator,
prefix: Vec<u8>,
_v: PhantomData<V>,
}
impl<V: DeserializeOwned> Iterator for Values<V> {
type Item = Result<V>;
fn next(&mut self) -> Option<Self::Item> {
if self.db_iter.valid() {
let v =
unsafe {self.db_iter.key_inner()}
.and_then(|k| if &k[0..self.prefix.len()] == &self.prefix[..] { Some(k) } else { None } )
.and_then(|_|
unsafe {self.db_iter.value_inner()}
.map(|v| Ok(bincode::deserialize(v)?))
);
self.db_iter.next();
v
} else {
None
}
}
}