feat: expose a common DB tree for the database

This commit is contained in:
Quentin de Quelen 2019-09-16 14:49:53 +02:00
parent 8d24e54fa1
commit 918cc235a4
4 changed files with 89 additions and 3 deletions

View File

@ -93,6 +93,13 @@ impl CfTree {
let mut iter = self.index.db.iterator_cf(cf, IteratorMode::End)?;
Ok(iter.next().map(|(key, _)| key))
}
pub fn prefix_iterator<P>(&self, prefix: P) -> RocksDbResult<rocksdb::DBIterator>
where P: AsRef<[u8]>,
{
let cf = self.index.db.cf_handle(&self.index.name).unwrap();
self.index.db.prefix_iterator_cf(cf, prefix)
}
}
pub struct CfIter<'a> {

View File

@ -0,0 +1,68 @@
use serde::de::DeserializeOwned;
use serde::Serialize;
use super::Error;
use std::marker::PhantomData;
#[derive(Clone)]
pub struct CommonIndex(pub crate::CfTree);
impl CommonIndex {
pub fn get<T, K>(&self, key: K) -> Result<Option<T>, Error>
where T: DeserializeOwned,
K: AsRef<[u8]>,
{
let raw = match self.0.get(key)? {
Some(raw) => raw,
None => return Ok(None),
};
let data = bincode::deserialize(&raw)?;
Ok(Some(data))
}
pub fn set<T, K>(&self, key: K, data: &T) -> Result<(), Error>
where T: Serialize,
K: AsRef<[u8]>,
{
let raw = bincode::serialize(data)?;
self.0.insert(key, &raw)?;
Ok(())
}
pub fn prefix_iterator<T, P>(&self, prefix: P) -> Result<SerializedIterator<T>, Error>
where T: DeserializeOwned,
P: AsRef<[u8]>,
{
let iter = self.0.prefix_iterator(prefix)?;
Ok(SerializedIterator { iter, _marker: PhantomData })
}
}
pub struct SerializedIterator<'a, T> {
iter: rocksdb::DBIterator<'a>,
_marker: PhantomData<T>,
}
impl<T> Iterator for SerializedIterator<'_, T>
where T: DeserializeOwned,
{
type Item = (String, T);
fn next(&mut self) -> Option<Self::Item> {
let (raw_key, raw_value) = match self.iter.next() {
Some((key, value)) => (key, value),
None => return None,
};
let value: T = match bincode::deserialize(&raw_value) {
Ok(data) => data,
Err(_) => return None,
};
let key = match std::str::from_utf8(&raw_key) {
Ok(key) => key.to_string(),
Err(_) => return None,
};
Some((key, value))
}
}

View File

@ -18,6 +18,7 @@ use crate::ranked_map::RankedMap;
use crate::serde::{Deserializer, DeserializerError};
pub use self::custom_settings_index::CustomSettingsIndex;
pub use self::common_index::CommonIndex;
use self::docs_words_index::DocsWordsIndex;
use self::documents_index::DocumentsIndex;
use self::main_index::MainIndex;
@ -33,6 +34,7 @@ use crate::database::{
apply_synonyms_addition, apply_synonyms_deletion,
};
mod common_index;
mod custom_settings_index;
mod docs_words_index;
mod documents_index;

View File

@ -9,8 +9,10 @@ mod error;
mod index;
mod update;
use crate::CfTree;
pub use self::error::Error;
pub use self::index::{Index, CustomSettingsIndex};
pub use self::index::{Index, CustomSettingsIndex, CommonIndex};
pub use self::update::DocumentsAddition;
pub use self::update::DocumentsDeletion;
@ -23,6 +25,7 @@ use self::update::apply_synonyms_addition;
use self::update::apply_synonyms_deletion;
const INDEXES_KEY: &str = "indexes";
const COMMON_KEY: &str = "common-index";
fn load_indexes(tree: &rocksdb::DB) -> Result<HashSet<String>, Error> {
match tree.get(INDEXES_KEY)? {
@ -34,6 +37,7 @@ fn load_indexes(tree: &rocksdb::DB) -> Result<HashSet<String>, Error> {
pub struct Database {
cache: RwLock<HashMap<String, Index>>,
inner: Arc<rocksdb::DB>,
common: Arc<CommonIndex>,
}
impl Database {
@ -45,9 +49,10 @@ impl Database {
let cfs = rocksdb::DB::list_cf(&options, &path).unwrap_or_default();
let inner = Arc::new(rocksdb::DB::open_cf(&options, path, cfs)?);
let common_tree = CfTree::create(inner.clone(), COMMON_KEY.to_owned())?;
let common = Arc::new(CommonIndex(common_tree));
let indexes = load_indexes(&inner)?;
let database = Database { cache, inner };
let database = Database { cache, inner, common };
for index in indexes {
database.open_index(&index)?;
@ -112,4 +117,8 @@ impl Database {
Ok(index)
}
pub fn common_index(&self) -> Arc<CommonIndex> {
self.common.clone()
}
}