diff --git a/util/src/hashdb.rs b/util/src/hashdb.rs index 8217413ef..ca4120702 100644 --- a/util/src/hashdb.rs +++ b/util/src/hashdb.rs @@ -86,7 +86,7 @@ pub trait HashDB: AsHashDB + Send + Sync { fn emplace(&mut self, key: H256, value: DBValue); /// Remove a datum previously inserted. Insertions can be "owed" such that the same number of `insert()`s may - /// happen without the data being eventually being inserted into the DB. + /// happen without the data being eventually being inserted into the DB. It can be "owed" more than once. /// /// # Examples /// ```rust @@ -100,6 +100,10 @@ pub trait HashDB: AsHashDB + Send + Sync { /// let key = &d.sha3(); /// m.remove(key); // OK - we now owe an insertion. /// assert!(!m.contains(key)); + /// m.remove(key); // OK - we now owe two insertions. + /// assert!(!m.contains(key)); + /// m.insert(d); // OK - still owed. + /// assert!(!m.contains(key)); /// m.insert(d); // OK - now it's "empty" again. /// assert!(!m.contains(key)); /// m.insert(d); // OK - now we've diff --git a/util/src/memorydb.rs b/util/src/memorydb.rs index bd96347ab..cc8d0a3de 100644 --- a/util/src/memorydb.rs +++ b/util/src/memorydb.rs @@ -246,46 +246,57 @@ impl HashDB for MemoryDB { } } -#[test] -fn memorydb_remove_and_purge() { - let hello_bytes = b"Hello world!"; - let hello_key = hello_bytes.sha3(); +#[cfg(test)] +mod tests { + use super::*; - let mut m = MemoryDB::new(); - m.remove(&hello_key); - assert_eq!(m.raw(&hello_key).unwrap().1, -1); - m.purge(); - assert_eq!(m.raw(&hello_key).unwrap().1, -1); - m.insert(hello_bytes); - assert_eq!(m.raw(&hello_key).unwrap().1, 0); - m.purge(); - assert_eq!(m.raw(&hello_key), None); + #[test] + fn memorydb_remove_and_purge() { + let hello_bytes = b"Hello world!"; + let hello_key = hello_bytes.sha3(); - let mut m = MemoryDB::new(); - assert!(m.remove_and_purge(&hello_key).is_none()); - assert_eq!(m.raw(&hello_key).unwrap().1, -1); - m.insert(hello_bytes); - m.insert(hello_bytes); - assert_eq!(m.raw(&hello_key).unwrap().1, 1); - assert_eq!(&*m.remove_and_purge(&hello_key).unwrap(), hello_bytes); - assert_eq!(m.raw(&hello_key), None); - assert!(m.remove_and_purge(&hello_key).is_none()); -} - -#[test] -fn consolidate() { - let mut main = MemoryDB::new(); - let mut other = MemoryDB::new(); - let remove_key = other.insert(b"doggo"); - main.remove(&remove_key); - - let insert_key = other.insert(b"arf"); - main.emplace(insert_key, DBValue::from_slice(b"arf")); - - main.consolidate(other); - - let overlay = main.drain(); - - assert_eq!(overlay.get(&remove_key).unwrap(), &(DBValue::from_slice(b"doggo"), 0)); - assert_eq!(overlay.get(&insert_key).unwrap(), &(DBValue::from_slice(b"arf"), 2)); + let mut m = MemoryDB::new(); + m.remove(&hello_key); + assert_eq!(m.raw(&hello_key).unwrap().1, -1); + m.purge(); + assert_eq!(m.raw(&hello_key).unwrap().1, -1); + m.insert(hello_bytes); + assert_eq!(m.raw(&hello_key).unwrap().1, 0); + m.purge(); + assert_eq!(m.raw(&hello_key), None); + + let mut m = MemoryDB::new(); + assert!(m.remove_and_purge(&hello_key).is_none()); + assert_eq!(m.raw(&hello_key).unwrap().1, -1); + m.insert(hello_bytes); + m.insert(hello_bytes); + assert_eq!(m.raw(&hello_key).unwrap().1, 1); + assert_eq!(&*m.remove_and_purge(&hello_key).unwrap(), hello_bytes); + assert_eq!(m.raw(&hello_key), None); + assert!(m.remove_and_purge(&hello_key).is_none()); + } + + #[test] + fn consolidate() { + let mut main = MemoryDB::new(); + let mut other = MemoryDB::new(); + let remove_key = other.insert(b"doggo"); + main.remove(&remove_key); + + let insert_key = other.insert(b"arf"); + main.emplace(insert_key, DBValue::from_slice(b"arf")); + + let negative_remove_key = other.insert(b"negative"); + other.remove(&negative_remove_key); // ref cnt: 0 + other.remove(&negative_remove_key); // ref cnt: -1 + main.remove(&negative_remove_key); // ref cnt: -1 + + main.consolidate(other); + + let overlay = main.drain(); + + assert_eq!(overlay.get(&remove_key).unwrap(), &(DBValue::from_slice(b"doggo"), 0)); + assert_eq!(overlay.get(&insert_key).unwrap(), &(DBValue::from_slice(b"arf"), 2)); + assert_eq!(overlay.get(&negative_remove_key).unwrap(), &(DBValue::from_slice(b"negative"), -2)); + } }