Merge pull request #186 from meilisearch/common-db-tree

feat: expose a common DB tree for the database
This commit is contained in:
Clément Renault 2019-09-16 19:08:52 +02:00 committed by GitHub
commit 3712fa7c24
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
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)?; let mut iter = self.index.db.iterator_cf(cf, IteratorMode::End)?;
Ok(iter.next().map(|(key, _)| key)) 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> { 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}; use crate::serde::{Deserializer, DeserializerError};
pub use self::custom_settings_index::CustomSettingsIndex; pub use self::custom_settings_index::CustomSettingsIndex;
pub use self::common_index::CommonIndex;
use self::docs_words_index::DocsWordsIndex; use self::docs_words_index::DocsWordsIndex;
use self::documents_index::DocumentsIndex; use self::documents_index::DocumentsIndex;
use self::main_index::MainIndex; use self::main_index::MainIndex;
@ -33,6 +34,7 @@ use crate::database::{
apply_synonyms_addition, apply_synonyms_deletion, apply_synonyms_addition, apply_synonyms_deletion,
}; };
mod common_index;
mod custom_settings_index; mod custom_settings_index;
mod docs_words_index; mod docs_words_index;
mod documents_index; mod documents_index;

View File

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