diff --git a/meilidb-data/src/database.rs b/meilidb-data/src/database.rs index f3a4d1dbd..7cfc68f22 100644 --- a/meilidb-data/src/database.rs +++ b/meilidb-data/src/database.rs @@ -1,11 +1,17 @@ use std::sync::Arc; use std::path::Path; -use crate::schema::Schema; +use meilidb_core::Index as WordIndex; +use meilidb_core::shared_data_cursor::{FromSharedDataCursor, SharedDataCursor}; +use meilidb_core::write_to_bytes::WriteToBytes; +use sled::IVec; + +use crate::Schema; #[derive(Debug)] pub enum Error { - SchemaNotFound, + SchemaMissing, + WordIndexMissing, SledError(sled::Error), BincodeError(bincode::Error), } @@ -26,6 +32,13 @@ fn index_name(name: &str) -> Vec { format!("index-{}", name).into_bytes() } +fn ivec_into_arc(ivec: IVec) -> Arc<[u8]> { + match ivec { + IVec::Inline(len, bytes) => Arc::from(&bytes[..len as usize]), + IVec::Remote { buf } => buf, + } +} + #[derive(Clone)] pub struct Database(sled::Db); @@ -62,29 +75,52 @@ impl Database { } } -#[derive(Debug, Clone)] +#[derive(Clone)] pub struct Index { schema: Schema, + word_index: Arc, inner: Arc, } impl Index { fn from_raw(inner: Arc) -> Result { let bytes = inner.get("schema")?; - let bytes = bytes.ok_or(Error::SchemaNotFound)?; - + let bytes = bytes.ok_or(Error::SchemaMissing)?; let schema = Schema::read_from_bin(bytes.as_ref())?; - Ok(Index { schema, inner }) + + let bytes = inner.get("word-index")?; + let bytes = bytes.ok_or(Error::WordIndexMissing)?; + let word_index = { + let len = bytes.len(); + let bytes = ivec_into_arc(bytes); + let mut cursor = SharedDataCursor::from_shared_bytes(bytes, 0, len); + + // TODO must handle this error + let word_index = WordIndex::from_shared_data_cursor(&mut cursor).unwrap(); + + Arc::new(word_index) + }; + + Ok(Index { schema, word_index, inner }) } fn new_from_raw(inner: Arc, schema: Schema) -> Result { let mut schema_bytes = Vec::new(); - schema.write_to_bin(&mut schema_bytes); + schema.write_to_bin(&mut schema_bytes)?; inner.set("schema", schema_bytes)?; - Ok(Index { schema, inner }) + + let word_index = WordIndex::default(); + inner.set("word-index", word_index.into_bytes())?; + let word_index = Arc::new(word_index); + + Ok(Index { schema, word_index, inner }) } pub fn schema(&self) -> &Schema { &self.schema } + + pub fn word_index(&self) -> &WordIndex { + &self.word_index + } }