From 1c1f9201b8958d7682b2948c09da968179681c62 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Renault?= Date: Wed, 6 Feb 2019 18:03:41 +0100 Subject: [PATCH] feat: Remove the lifetime restriction for Database Updates --- examples/create-database.rs | 4 +-- src/database/mod.rs | 51 ++++++++++++++++++++++--------------- src/database/update.rs | 29 +++++++-------------- 3 files changed, 42 insertions(+), 42 deletions(-) diff --git a/examples/create-database.rs b/examples/create-database.rs index b00fbf4b5..043b297ef 100644 --- a/examples/create-database.rs +++ b/examples/create-database.rs @@ -61,7 +61,7 @@ fn index( while !end_of_file { let tokenizer_builder = DefaultBuilder::new(); - let mut update = database.update()?; + let mut update = database.start_update()?; loop { end_of_file = !rdr.read_record(&mut raw_record)?; @@ -88,7 +88,7 @@ fn index( println!(); println!("committing update..."); - update.commit()?; + database.commit_update(update)?; } Ok(database) diff --git a/src/database/mod.rs b/src/database/mod.rs index f9fb0af04..ce15de752 100644 --- a/src/database/mod.rs +++ b/src/database/mod.rs @@ -136,13 +136,24 @@ impl Database { Ok(Database { db, view }) } - pub fn update(&self) -> Result> { + pub fn start_update(&self) -> Result> { let schema = match self.db.get(DATA_SCHEMA)? { Some(value) => Schema::read_from_bin(&*value)?, None => panic!("Database does not contain a schema"), }; - Ok(Update::new(self, schema)) + Ok(Update::new(schema)) + } + + pub fn commit_update(&self, update: Update) -> Result>>, Box> { + let batch = update.build()?; + self.db.write(batch)?; + + let snapshot = Snapshot::new(self.db.clone()); + let view = Arc::new(DatabaseView::new(snapshot)?); + self.view.set(view.clone()); + + Ok(view) } pub fn view(&self) -> Arc>> { @@ -202,12 +213,12 @@ mod tests { }; let tokenizer_builder = DefaultBuilder::new(); - let mut builder = database.update()?; + let mut builder = database.start_update()?; let docid0 = builder.update_document(&doc0, &tokenizer_builder, &stop_words)?; let docid1 = builder.update_document(&doc1, &tokenizer_builder, &stop_words)?; - let view = builder.commit()?; + let view = database.commit_update(builder)?; let de_doc0: SimpleDoc = view.document_by_id(docid0)?; let de_doc1: SimpleDoc = view.document_by_id(docid1)?; @@ -271,15 +282,15 @@ mod tests { let tokenizer_builder = DefaultBuilder::new(); - let mut builder = database.update()?; + let mut builder = database.start_update()?; let docid0 = builder.update_document(&doc0, &tokenizer_builder, &stop_words)?; let docid1 = builder.update_document(&doc1, &tokenizer_builder, &stop_words)?; - builder.commit()?; + database.commit_update(builder)?; - let mut builder = database.update()?; + let mut builder = database.start_update()?; let docid2 = builder.update_document(&doc2, &tokenizer_builder, &stop_words)?; let docid3 = builder.update_document(&doc3, &tokenizer_builder, &stop_words)?; - let view = builder.commit()?; + let view = database.commit_update(builder)?; let de_doc0: SimpleDoc = view.document_by_id(docid0)?; let de_doc1: SimpleDoc = view.document_by_id(docid1)?; @@ -358,7 +369,7 @@ mod bench { } let tokenizer_builder = DefaultBuilder; - let mut builder = database.update()?; + let mut builder = database.start_update()?; let mut rng = XorShiftRng::seed_from_u64(42); for i in 0..300 { @@ -370,7 +381,7 @@ mod bench { builder.update_document(&document, &tokenizer_builder, &stop_words)?; } - builder.commit()?; + database.commit_update(builder)?; drop(database); @@ -403,7 +414,7 @@ mod bench { } let tokenizer_builder = DefaultBuilder; - let mut builder = database.update()?; + let mut builder = database.start_update()?; let mut rng = XorShiftRng::seed_from_u64(42); for i in 0..3000 { @@ -415,7 +426,7 @@ mod bench { builder.update_document(&document, &tokenizer_builder, &stop_words)?; } - builder.commit()?; + database.commit_update(builder)?; drop(database); @@ -449,7 +460,7 @@ mod bench { } let tokenizer_builder = DefaultBuilder; - let mut builder = database.update()?; + let mut builder = database.start_update()?; let mut rng = XorShiftRng::seed_from_u64(42); for i in 0..30_000 { @@ -461,7 +472,7 @@ mod bench { builder.update_document(&document, &tokenizer_builder, &stop_words)?; } - builder.commit()?; + database.commit_update(builder)?; drop(database); @@ -494,7 +505,7 @@ mod bench { } let tokenizer_builder = DefaultBuilder; - let mut builder = database.update()?; + let mut builder = database.start_update()?; let mut rng = XorShiftRng::seed_from_u64(42); for i in 0..300 { @@ -506,7 +517,7 @@ mod bench { builder.update_document(&document, &tokenizer_builder, &stop_words)?; } - let view = builder.commit()?; + let view = database.commit_update(builder)?; bench.iter(|| { for q in &["a", "b", "c", "d", "e"] { @@ -539,7 +550,7 @@ mod bench { } let tokenizer_builder = DefaultBuilder; - let mut builder = database.update()?; + let mut builder = database.start_update()?; let mut rng = XorShiftRng::seed_from_u64(42); for i in 0..3000 { @@ -551,7 +562,7 @@ mod bench { builder.update_document(&document, &tokenizer_builder, &stop_words)?; } - let view = builder.commit()?; + let view = database.commit_update(builder)?; bench.iter(|| { for q in &["a", "b", "c", "d", "e"] { @@ -585,7 +596,7 @@ mod bench { } let tokenizer_builder = DefaultBuilder; - let mut builder = database.update()?; + let mut builder = database.start_update()?; let mut rng = XorShiftRng::seed_from_u64(42); for i in 0..30_000 { @@ -597,7 +608,7 @@ mod bench { builder.update_document(&document, &tokenizer_builder, &stop_words)?; } - let view = builder.commit()?; + let view = database.commit_update(builder)?; bench.iter(|| { for q in &["a", "b", "c", "d", "e"] { diff --git a/src/database/update.rs b/src/database/update.rs index ec9eed0df..616c070e5 100644 --- a/src/database/update.rs +++ b/src/database/update.rs @@ -1,14 +1,12 @@ use std::collections::{HashSet, BTreeMap}; use std::error::Error; -use std::sync::Arc; -use rocksdb::rocksdb::{DB, Writable, Snapshot, WriteBatch}; +use rocksdb::rocksdb::{Writable, WriteBatch}; use hashbrown::hash_map::HashMap; use serde::Serialize; use fst::map::Map; use sdset::Set; -use crate::database::{DATA_INDEX, Database, DatabaseView}; use crate::database::index::{Positive, PositiveBuilder, Negative}; use crate::database::document_key::{DocumentKey, DocumentKeyAttr}; use crate::database::serde::serializer::Serializer; @@ -17,20 +15,20 @@ use crate::database::schema::SchemaAttr; use crate::tokenizer::TokenizerBuilder; use crate::data::{DocIds, DocIndexes}; use crate::database::schema::Schema; -use crate::{DocumentId, DocIndex}; use crate::database::index::Index; +use crate::{DocumentId, DocIndex}; +use crate::database::DATA_INDEX; pub type Token = Vec; // TODO could be replaced by a SmallVec -pub struct Update<'a> { - database: &'a Database, +pub struct Update { schema: Schema, raw_builder: RawUpdateBuilder, } -impl<'a> Update<'a> { - pub(crate) fn new(database: &'a Database, schema: Schema) -> Update<'a> { - Update { database, schema, raw_builder: RawUpdateBuilder::new() } +impl Update { + pub(crate) fn new(schema: Schema) -> Update { + Update { schema, raw_builder: RawUpdateBuilder::new() } } pub fn update_document( @@ -65,18 +63,9 @@ impl<'a> Update<'a> { Ok(document_id) } - pub fn commit(self) -> Result>>, Box> { - let batch = self.raw_builder.build()?; - self.database.db.write(batch)?; - - let snapshot = Snapshot::new(self.database.db.clone()); - let view = Arc::new(DatabaseView::new(snapshot)?); - self.database.view.set(view.clone()); - - Ok(view) + pub(crate) fn build(self) -> Result> { + self.raw_builder.build() } - - pub fn abort(self) { } } #[derive(Copy, Clone, PartialEq, Eq)]