From f4b04dfb72928c9772cc45aedb1492e14e40eaf2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Renault?= Date: Sat, 29 Dec 2018 20:52:00 +0100 Subject: [PATCH] feat: Prefer doing DatabaseView updates atomically --- Cargo.toml | 1 + src/database/database.rs | 22 +++++++++------------- 2 files changed, 10 insertions(+), 13 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 210fb279f..ae85ae7c5 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -7,6 +7,7 @@ authors = ["Kerollmops "] [dependencies] bincode = "1.0" byteorder = "1.2" +crossbeam = "0.6" fst = "0.3" hashbrown = "0.1" lazy_static = "1.1" diff --git a/src/database/database.rs b/src/database/database.rs index 54dc1c0f4..70e3664a3 100644 --- a/src/database/database.rs +++ b/src/database/database.rs @@ -1,10 +1,11 @@ -use std::sync::{Arc, Mutex, RwLock, RwLockReadGuard}; +use std::sync::{Arc, Mutex}; use std::error::Error; use std::path::Path; use rocksdb::rocksdb_options::{DBOptions, IngestExternalFileOptions, ColumnFamilyOptions}; use rocksdb::rocksdb::{Writable, Snapshot}; use rocksdb::{DB, DBVector, MergeOperands}; +use crossbeam::atomic::ArcCell; use crate::database::{DatabaseView, Update, Schema}; use crate::database::{DATA_INDEX, DATA_SCHEMA}; @@ -17,7 +18,7 @@ pub struct Database { db: Mutex>, // This view is updated each time the DB ingests an update - view: RwLock>>, + view: ArcCell>>, } impl Database { @@ -44,7 +45,7 @@ impl Database { let db = Arc::new(db); let snapshot = Snapshot::new(db.clone()); - let view = RwLock::new(DatabaseView::new(snapshot)?); + let view = ArcCell::new(Arc::new(DatabaseView::new(snapshot)?)); Ok(Database { db: Mutex::new(db), view }) } @@ -68,7 +69,7 @@ impl Database { let db = Arc::new(db); let snapshot = Snapshot::new(db.clone()); - let view = RwLock::new(DatabaseView::new(snapshot)?); + let view = ArcCell::new(Arc::new(DatabaseView::new(snapshot)?)); Ok(Database { db: Mutex::new(db), view }) } @@ -101,13 +102,8 @@ impl Database { Snapshot::new(db.clone()) }; - // Here we will block the view creation for the minimum amount of time: - // updating the DatabaseView itself with the new database snapshot - let view = DatabaseView::new(snapshot)?; - match self.view.write() { - Ok(mut lock) => *lock = view, - Err(e) => return Err(e.to_string().into()), - } + let view = Arc::new(DatabaseView::new(snapshot)?); + self.view.set(view); Ok(()) } @@ -123,8 +119,8 @@ impl Database { } } - pub fn view(&self) -> RwLockReadGuard>> { - self.view.read().unwrap() + pub fn view(&self) -> Arc>> { + self.view.get() } }