feat: Store already opened indexes and word indexes

This commit is contained in:
Clément Renault 2019-04-16 10:47:52 +02:00
parent 0104e93ba9
commit b7805fee93
No known key found for this signature in database
GPG Key ID: 0151CDAB43460DAE
2 changed files with 51 additions and 17 deletions

View File

@ -5,6 +5,7 @@ authors = ["Kerollmops <renault.cle@gmail.com>"]
edition = "2018" edition = "2018"
[dependencies] [dependencies]
arc-swap = "0.3.11"
bincode = "1.1.2" bincode = "1.1.2"
byteorder = "1.3.1" byteorder = "1.3.1"
hashbrown = { version = "0.1.8", features = ["serde"] } hashbrown = { version = "0.1.8", features = ["serde"] }

View File

@ -1,15 +1,18 @@
use std::sync::Arc;
use std::path::Path; use std::path::Path;
use std::sync::Arc;
use meilidb_core::{DocumentId, Index as WordIndex}; use arc_swap::{ArcSwap, Lease};
use hashbrown::HashMap;
use meilidb_core::shared_data_cursor::{FromSharedDataCursor, SharedDataCursor}; use meilidb_core::shared_data_cursor::{FromSharedDataCursor, SharedDataCursor};
use meilidb_core::write_to_bytes::WriteToBytes; use meilidb_core::write_to_bytes::WriteToBytes;
use meilidb_core::{DocumentId, Index as WordIndex};
use sled::IVec; use sled::IVec;
use crate::{Schema, SchemaAttr}; use crate::{Schema, SchemaAttr};
#[derive(Debug)] #[derive(Debug)]
pub enum Error { pub enum Error {
SchemaDiffer,
SchemaMissing, SchemaMissing,
WordIndexMissing, WordIndexMissing,
SledError(sled::Error), SledError(sled::Error),
@ -51,35 +54,61 @@ fn ivec_into_arc(ivec: IVec) -> Arc<[u8]> {
} }
#[derive(Clone)] #[derive(Clone)]
pub struct Database(sled::Db); pub struct Database {
opened: Arc<ArcSwap<HashMap<String, Index>>>,
inner: sled::Db,
}
impl Database { impl Database {
pub fn start_default<P: AsRef<Path>>(path: P) -> Result<Database, Error> { pub fn start_default<P: AsRef<Path>>(path: P) -> Result<Database, Error> {
sled::Db::start_default(path).map(Database).map_err(Into::into) let inner = sled::Db::start_default(path)?;
let opened = Arc::new(ArcSwap::new(Arc::new(HashMap::new())));
Ok(Database { opened, inner })
} }
pub fn open_index(&self, name: &str) -> Result<Option<Index>, Error> { pub fn open_index(&self, name: &str) -> Result<Option<Index>, Error> {
let name = index_name(name); // check if the index was already opened
if let Some(index) = self.opened.lease().get(name) {
return Ok(Some(index.clone()))
}
if self.0.tree_names().into_iter().any(|tn| tn == name) { let raw_name = index_name(name);
let tree = self.0.open_tree(name)?; if self.inner.tree_names().into_iter().any(|tn| tn == raw_name) {
let tree = self.inner.open_tree(raw_name)?;
let index = Index::from_raw(tree)?; let index = Index::from_raw(tree)?;
self.opened.rcu(|opened| {
let mut opened = HashMap::clone(opened);
opened.insert(name.to_string(), index.clone());
opened
});
return Ok(Some(index)) return Ok(Some(index))
} }
Ok(None) Ok(None)
} }
pub fn create_index(&self, name: &str, schema: Schema) -> Result<Index, Error> { pub fn create_index(&self, name: String, schema: Schema) -> Result<Index, Error> {
match self.open_index(name)? { match self.open_index(&name)? {
Some(index) => { Some(index) => {
// TODO check if the schema is the same if index.schema != schema {
return Err(Error::SchemaDiffer);
}
Ok(index) Ok(index)
}, },
None => { None => {
let name = index_name(name); let raw_name = index_name(&name);
let tree = self.0.open_tree(name)?; let tree = self.inner.open_tree(raw_name)?;
let index = Index::new_from_raw(tree, schema)?; let index = Index::new_from_raw(tree, schema)?;
self.opened.rcu(|opened| {
let mut opened = HashMap::clone(opened);
opened.insert(name.clone(), index.clone());
opened
});
Ok(index) Ok(index)
}, },
} }
@ -89,7 +118,7 @@ impl Database {
#[derive(Clone)] #[derive(Clone)]
pub struct Index { pub struct Index {
schema: Schema, schema: Schema,
word_index: Arc<WordIndex>, word_index: Arc<ArcSwap<WordIndex>>,
inner: Arc<sled::Tree>, inner: Arc<sled::Tree>,
} }
@ -109,7 +138,7 @@ impl Index {
// TODO must handle this error // TODO must handle this error
let word_index = WordIndex::from_shared_data_cursor(&mut cursor).unwrap(); let word_index = WordIndex::from_shared_data_cursor(&mut cursor).unwrap();
Arc::new(word_index) Arc::new(ArcSwap::new(Arc::new(word_index)))
}; };
Ok(Index { schema, word_index, inner }) Ok(Index { schema, word_index, inner })
@ -122,7 +151,7 @@ impl Index {
let word_index = WordIndex::default(); let word_index = WordIndex::default();
inner.set("word-index", word_index.into_bytes())?; inner.set("word-index", word_index.into_bytes())?;
let word_index = Arc::new(word_index); let word_index = Arc::new(ArcSwap::new(Arc::new(word_index)));
Ok(Index { schema, word_index, inner }) Ok(Index { schema, word_index, inner })
} }
@ -131,8 +160,12 @@ impl Index {
&self.schema &self.schema
} }
pub fn word_index(&self) -> &WordIndex { pub fn word_index(&self) -> Lease<Arc<WordIndex>> {
&self.word_index self.word_index.lease()
}
fn update_word_index(&self, word_index: Arc<WordIndex>) {
self.word_index.store(word_index)
} }
pub fn set_document_attribute<V>( pub fn set_document_attribute<V>(