diff options
author | Alex Auvolat <alex@adnab.me> | 2022-06-03 15:31:07 +0200 |
---|---|---|
committer | Alex Auvolat <alex@adnab.me> | 2022-06-03 15:31:07 +0200 |
commit | 4e72c713f157ae9d5103a461c4c213b2aa6a84b9 (patch) | |
tree | 50fca54ff6540490846d0aa65be5a3c7bfde0e17 /src/table | |
parent | 16e0a655d0d01e3871aee81a0a9660102d6df74e (diff) | |
download | garage-4e72c713f157ae9d5103a461c4c213b2aa6a84b9.tar.gz garage-4e72c713f157ae9d5103a461c4c213b2aa6a84b9.zip |
Start LMDB adapter, with fixed semantics
Diffstat (limited to 'src/table')
-rw-r--r-- | src/table/data.rs | 37 | ||||
-rw-r--r-- | src/table/gc.rs | 14 | ||||
-rw-r--r-- | src/table/merkle.rs | 26 |
3 files changed, 40 insertions, 37 deletions
diff --git a/src/table/data.rs b/src/table/data.rs index 17402bb6..cca96f68 100644 --- a/src/table/data.rs +++ b/src/table/data.rs @@ -182,7 +182,7 @@ where tree_key: &[u8], f: impl Fn(Option<F::E>) -> F::E, ) -> Result<Option<F::E>, Error> { - let changed = self.store.db().transaction(|tx| { + let changed = self.store.db().transaction(|mut tx| { let (old_entry, old_bytes, new_entry) = match tx.get(&self.store, tree_key)? { Some(old_bytes) => { let old_entry = self.decode_entry(&old_bytes).map_err(db::TxError::Abort)?; @@ -203,6 +203,7 @@ where .map_err(Error::RmpEncode) .map_err(db::TxError::Abort)?; let encoding_changed = Some(&new_bytes[..]) != old_bytes.as_ref().map(|x| &x[..]); + drop(old_bytes); if value_changed || encoding_changed { let new_bytes_hash = blake2sum(&new_bytes[..]); @@ -241,15 +242,16 @@ where } pub(crate) fn delete_if_equal(self: &Arc<Self>, k: &[u8], v: &[u8]) -> Result<bool, Error> { - let removed = self.store.db().transaction(|tx| { - if let Some(cur_v) = tx.get(&self.store, k)? { - if cur_v == v { - tx.remove(&self.store, k)?; - tx.insert(&self.merkle_todo, k, vec![])?; - return Ok(true); - } + let removed = self.store.db().transaction(|mut tx| { + let remove = match tx.get(&self.store, k)? { + Some(cur_v) if cur_v == v => true, + _ => false, + }; + if remove { + tx.remove(&self.store, k)?; + tx.insert(&self.merkle_todo, k, vec![])?; } - Ok(false) + Ok(remove) })?; if removed { @@ -267,15 +269,16 @@ where k: &[u8], vhash: Hash, ) -> Result<bool, Error> { - let removed = self.store.db().transaction(|tx| { - if let Some(cur_v) = tx.get(&self.store, k)? { - if blake2sum(&cur_v[..]) == vhash { - tx.remove(&self.store, k)?; - tx.insert(&self.merkle_todo, k, vec![])?; - return Ok(Some(cur_v.into_vec())); - } + let removed = self.store.db().transaction(|mut tx| { + let remove_v = match tx.get(&self.store, k)? { + Some(cur_v) if blake2sum(&cur_v[..]) == vhash => Some(cur_v.into_vec()), + _ => None, + }; + if remove_v.is_some() { + tx.remove(&self.store, k)?; + tx.insert(&self.merkle_todo, k, vec![])?; } - Ok(None) + Ok(remove_v) })?; if let Some(old_v) = removed { diff --git a/src/table/gc.rs b/src/table/gc.rs index 260fecfa..e2611389 100644 --- a/src/table/gc.rs +++ b/src/table/gc.rs @@ -376,13 +376,13 @@ impl GcTodoEntry { /// what we have to do is still the same pub(crate) fn remove_if_equal(&self, gc_todo_tree: &db::Tree) -> Result<(), Error> { let key = self.todo_table_key(); - gc_todo_tree.db().transaction(|tx| { - let old_val = tx.get(gc_todo_tree, &key)?; - match old_val { - Some(ov) if ov == self.value_hash.as_slice() => { - tx.remove(gc_todo_tree, &key)?; - } - _ => (), + gc_todo_tree.db().transaction(|mut tx| { + let remove = match tx.get(gc_todo_tree, &key)? { + Some(ov) if ov == self.value_hash.as_slice() => true, + _ => false, + }; + if remove { + tx.remove(gc_todo_tree, &key)?; } tx.commit(()) })?; diff --git a/src/table/merkle.rs b/src/table/merkle.rs index 8c574d09..92e1445b 100644 --- a/src/table/merkle.rs +++ b/src/table/merkle.rs @@ -137,17 +137,17 @@ where self.data .merkle_tree .db() - .transaction(|tx| self.update_item_rec(tx, k, &khash, &key, new_vhash))?; - - let deleted = self.data.merkle_todo.db().transaction(|tx| { - let old_val = tx.get(&self.data.merkle_todo, k)?; - match old_val { - Some(ov) if ov == vhash_by => { - tx.remove(&self.data.merkle_todo, k)?; - tx.commit(true) - } - _ => tx.commit(false), + .transaction(|mut tx| self.update_item_rec(&mut tx, k, &khash, &key, new_vhash))?; + + let deleted = self.data.merkle_todo.db().transaction(|mut tx| { + let remove = match tx.get(&self.data.merkle_todo, k)? { + Some(ov) if ov == vhash_by => true, + _ => false, + }; + if remove { + tx.remove(&self.data.merkle_todo, k)?; } + Ok(remove) })?; if !deleted { @@ -162,7 +162,7 @@ where fn update_item_rec( &self, - tx: db::Transaction<'_>, + tx: &mut db::Transaction<'_>, k: &[u8], khash: &Hash, key: &MerkleNodeKey, @@ -288,7 +288,7 @@ where fn read_node_txn( &self, - tx: db::Transaction<'_>, + tx: &mut db::Transaction<'_>, k: &MerkleNodeKey, ) -> db::TxResult<MerkleNode, Error> { let ent = tx.get(&self.data.merkle_tree, k.encode())?; @@ -297,7 +297,7 @@ where fn put_node_txn( &self, - tx: db::Transaction<'_>, + tx: &mut db::Transaction<'_>, k: &MerkleNodeKey, v: &MerkleNode, ) -> db::TxResult<Hash, Error> { |