From d7bf09ecbdb429e53dca5b88df7aa12acd615891 Mon Sep 17 00:00:00 2001 From: Tyler Neely Date: Tue, 28 Jul 2020 12:36:15 +0200 Subject: [PATCH 1/3] Cut 0.34.1 with a new TransactionalTrees::flush method --- CHANGELOG.md | 8 ++++++++ Cargo.toml | 2 +- src/transaction.rs | 29 ++++++++++++++++++++++++++++- tests/test_tree.rs | 15 +++++++++++++++ 4 files changed, 52 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b5eaeb3bb..22382f43b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,11 @@ +# 0.34.1 + +## New Features + +* Added the `TransactionalTree::flush` method to + flush the underlying database after the transaction + commits and before the transaction returns. + # 0.34 ## Improvements diff --git a/Cargo.toml b/Cargo.toml index 45cfaf5e7..53685a73e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sled" -version = "0.34.0" +version = "0.34.1" authors = ["Tyler Neely "] description = "a modern embedded database" license = "MIT/Apache-2.0" diff --git a/src/transaction.rs b/src/transaction.rs index 492e0d4bf..bd20ecddf 100644 --- a/src/transaction.rs +++ b/src/transaction.rs @@ -96,6 +96,7 @@ pub struct TransactionalTree { pub(super) tree: Tree, pub(super) writes: Rc>>>, pub(super) read_cache: Rc>>>, + pub(super) flush_on_commit: Rc>, } /// An error type that is returned from the closure @@ -329,6 +330,11 @@ impl TransactionalTree { Ok(()) } + /// Flush the database before returning from the transaction. + pub fn flush(&self) { + *self.flush_on_commit.borrow_mut() = true; + } + fn unstage(&self) { unimplemented!() } @@ -352,6 +358,7 @@ impl TransactionalTree { tree: tree.clone(), writes: Default::default(), read_cache: Default::default(), + flush_on_commit: Default::default(), } } } @@ -390,7 +397,25 @@ impl TransactionalTrees { // when the peg drops, it ensures all updates // written to the log since its creation are // recovered atomically - peg.seal_batch() + let ret = peg.seal_batch(); + + ret + } + + fn flush_if_configured(&self) -> Result<()> { + let mut should_flush = None; + + for tree in &self.inner { + if *tree.flush_on_commit.borrow() { + should_flush = Some(tree); + break; + } + } + + if let Some(tree) = should_flush { + tree.tree.flush()?; + } + Ok(()) } } @@ -442,6 +467,8 @@ pub trait Transactional { Ok(r) => { let guard = pin(); tt.commit(&guard)?; + drop(_locks); + tt.flush_if_configured()?; return Ok(r); } Err(ConflictableTransactionError::Abort(e)) => { diff --git a/tests/test_tree.rs b/tests/test_tree.rs index 4afe791ec..3f337b902 100644 --- a/tests/test_tree.rs +++ b/tests/test_tree.rs @@ -504,6 +504,21 @@ fn concurrent_tree_transactions() -> TransactionResult<()> { Ok(()) } +#[test] +fn tree_flush_in_transaction() { + let config = sled::Config::new().temporary(true); + let db = config.open().unwrap(); + let tree = db.open_tree(b"a").unwrap(); + + tree.transaction::<_, _, sled::transaction::TransactionError>(|tree| { + tree.insert(b"k1", b"cats")?; + tree.insert(b"k2", b"dogs")?; + tree.flush(); + Ok(()) + }) + .unwrap(); +} + #[test] fn incorrect_multiple_db_transactions() -> TransactionResult<()> { common::setup_logger(); From 3c7312a613caf18ab3ef3c1d72901f2c6cb0ebed Mon Sep 17 00:00:00 2001 From: Tyler Neely Date: Tue, 28 Jul 2020 12:37:01 +0200 Subject: [PATCH 2/3] Update CHANGELOG.md --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 22382f43b..32bc31485 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,7 @@ ## New Features -* Added the `TransactionalTree::flush` method to +* #1136 Added the `TransactionalTree::flush` method to flush the underlying database after the transaction commits and before the transaction returns. From 9e566e7a918adeed68edff9c6330cee29941979c Mon Sep 17 00:00:00 2001 From: Tyler Neely Date: Tue, 28 Jul 2020 12:41:47 +0200 Subject: [PATCH 3/3] Clippy feedback --- src/transaction.rs | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/transaction.rs b/src/transaction.rs index bd20ecddf..4f336c3a0 100644 --- a/src/transaction.rs +++ b/src/transaction.rs @@ -397,9 +397,7 @@ impl TransactionalTrees { // when the peg drops, it ensures all updates // written to the log since its creation are // recovered atomically - let ret = peg.seal_batch(); - - ret + peg.seal_batch() } fn flush_if_configured(&self) -> Result<()> { @@ -452,7 +450,7 @@ pub trait Transactional { let view = Self::view_overlay(&tt); // NB locks must exist until this function returns. - let _locks = if let Ok(l) = tt.stage() { + let locks = if let Ok(l) = tt.stage() { l } else { tt.unstage(); @@ -467,7 +465,7 @@ pub trait Transactional { Ok(r) => { let guard = pin(); tt.commit(&guard)?; - drop(_locks); + drop(locks); tt.flush_if_configured()?; return Ok(r); }