memory_db/
lib.rs

1// Copyright 2017-2020 Parity Technologies
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//     http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15//! Reference-counted memory-based `HashDB` implementation.
16
17#![cfg_attr(not(feature = "std"), no_std)]
18
19#[cfg(not(feature = "std"))]
20extern crate alloc;
21
22use hash_db::{
23	AsHashDB, AsPlainDB, HashDB, HashDBRef, Hasher as KeyHasher, MaybeDebug, PlainDB, PlainDBRef,
24	Prefix,
25};
26#[cfg(feature = "std")]
27use std::{
28	borrow::Borrow, cmp::Eq, collections::hash_map::Entry, collections::HashMap as Map, hash,
29	marker::PhantomData, mem,
30};
31
32#[cfg(not(feature = "std"))]
33use alloc::collections::btree_map::{BTreeMap as Map, Entry};
34
35#[cfg(not(feature = "std"))]
36use core::{borrow::Borrow, cmp::Eq, hash, marker::PhantomData, mem};
37
38#[cfg(not(feature = "std"))]
39use alloc::vec::Vec;
40
41/// Reference-counted memory-based `HashDB` implementation.
42///
43/// Use `new()` to create a new database. Insert items with `insert()`, remove items
44/// with `remove()`, check for existence with `contains()` and lookup a hash to derive
45/// the data with `get()`. Clear with `clear()` and purge the portions of the data
46/// that have no references with `purge()`.
47///
48/// # Example
49/// ```rust
50///   use hash_db::{Hasher, HashDB, EMPTY_PREFIX};
51///   use keccak_hasher::KeccakHasher;
52///   use memory_db::{MemoryDB, HashKey};
53///
54///   let mut m = MemoryDB::<KeccakHasher, HashKey<_>, Vec<u8>>::default();
55///   let d = "Hello world!".as_bytes();
56///
57///   let k = m.insert(EMPTY_PREFIX, d);
58///   assert!(m.contains(&k, EMPTY_PREFIX));
59///   assert_eq!(m.get(&k, EMPTY_PREFIX).unwrap(), d);
60///
61///   m.insert(EMPTY_PREFIX, d);
62///   assert!(m.contains(&k, EMPTY_PREFIX));
63///
64///   m.remove(&k, EMPTY_PREFIX);
65///   assert!(m.contains(&k, EMPTY_PREFIX));
66///
67///   m.remove(&k, EMPTY_PREFIX);
68///   assert!(!m.contains(&k, EMPTY_PREFIX));
69///
70///   m.remove(&k, EMPTY_PREFIX);
71///   assert!(!m.contains(&k, EMPTY_PREFIX));
72///
73///   m.insert(EMPTY_PREFIX, d);
74///   assert!(!m.contains(&k, EMPTY_PREFIX));
75
76///   m.insert(EMPTY_PREFIX, d);
77///   assert!(m.contains(&k, EMPTY_PREFIX));
78///   assert_eq!(m.get(&k, EMPTY_PREFIX).unwrap(), d);
79///
80///   m.remove(&k, EMPTY_PREFIX);
81///   assert!(!m.contains(&k, EMPTY_PREFIX));
82/// ```
83pub struct MemoryDB<H, KF, T>
84where
85	H: KeyHasher,
86	KF: KeyFunction<H>,
87{
88	data: Map<KF::Key, (T, i32)>,
89	hashed_null_node: H::Out,
90	null_node_data: T,
91	_kf: PhantomData<KF>,
92}
93
94impl<H, KF, T> Clone for MemoryDB<H, KF, T>
95where
96	H: KeyHasher,
97	KF: KeyFunction<H>,
98	T: Clone,
99{
100	fn clone(&self) -> Self {
101		Self {
102			data: self.data.clone(),
103			hashed_null_node: self.hashed_null_node,
104			null_node_data: self.null_node_data.clone(),
105			_kf: Default::default(),
106		}
107	}
108}
109
110impl<H, KF, T> PartialEq<MemoryDB<H, KF, T>> for MemoryDB<H, KF, T>
111where
112	H: KeyHasher,
113	KF: KeyFunction<H>,
114	T: Eq + MaybeDebug,
115{
116	fn eq(&self, other: &MemoryDB<H, KF, T>) -> bool {
117		for a in self.data.iter() {
118			match other.data.get(a.0) {
119				Some(v) if v != a.1 => return false,
120				None => return false,
121				_ => (),
122			}
123		}
124		true
125	}
126}
127
128impl<H, KF, T> Eq for MemoryDB<H, KF, T>
129where
130	H: KeyHasher,
131	KF: KeyFunction<H>,
132	T: Eq + MaybeDebug,
133{
134}
135
136pub trait KeyFunction<H: KeyHasher> {
137	type Key: Send + Sync + Clone + hash::Hash + Eq + MaybeDebug + core::cmp::Ord;
138
139	fn key(hash: &H::Out, prefix: Prefix) -> Self::Key;
140}
141
142/// Key function that only uses the hash
143pub struct HashKey<H>(PhantomData<H>);
144
145impl<H> Clone for HashKey<H> {
146	fn clone(&self) -> Self {
147		Self(Default::default())
148	}
149}
150
151impl<H> core::fmt::Debug for HashKey<H> {
152	fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
153		core::write!(f, "HashKey")
154	}
155}
156
157impl<H: KeyHasher> KeyFunction<H> for HashKey<H> {
158	type Key = H::Out;
159
160	fn key(hash: &H::Out, prefix: Prefix) -> H::Out {
161		hash_key::<H>(hash, prefix)
162	}
163}
164
165/// Make database key from hash only.
166pub fn hash_key<H: KeyHasher>(key: &H::Out, _prefix: Prefix) -> H::Out {
167	*key
168}
169
170/// Key function that concatenates prefix and hash.
171pub struct PrefixedKey<H>(PhantomData<H>);
172
173impl<H> Clone for PrefixedKey<H> {
174	fn clone(&self) -> Self {
175		Self(Default::default())
176	}
177}
178
179impl<H> core::fmt::Debug for PrefixedKey<H> {
180	fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
181		core::write!(f, "PrefixedKey")
182	}
183}
184
185impl<H: KeyHasher> KeyFunction<H> for PrefixedKey<H> {
186	type Key = Vec<u8>;
187
188	fn key(hash: &H::Out, prefix: Prefix) -> Vec<u8> {
189		prefixed_key::<H>(hash, prefix)
190	}
191}
192
193/// Derive a database key from hash value of the node (key) and  the node prefix.
194pub fn prefixed_key<H: KeyHasher>(key: &H::Out, prefix: Prefix) -> Vec<u8> {
195	let mut prefixed_key = Vec::with_capacity(key.as_ref().len() + prefix.0.len() + 1);
196	prefixed_key.extend_from_slice(prefix.0);
197	if let Some(last) = prefix.1 {
198		prefixed_key.push(last);
199	}
200	prefixed_key.extend_from_slice(key.as_ref());
201	prefixed_key
202}
203
204/// Key function that concatenates prefix and hash.
205/// This is doing useless computation and should only be
206/// used for legacy purpose.
207/// It shall be remove in the future.
208#[derive(Clone, Debug)]
209#[deprecated(since = "0.22.0")]
210pub struct LegacyPrefixedKey<H: KeyHasher>(PhantomData<H>);
211
212#[allow(deprecated)]
213impl<H: KeyHasher> KeyFunction<H> for LegacyPrefixedKey<H> {
214	type Key = Vec<u8>;
215
216	fn key(hash: &H::Out, prefix: Prefix) -> Vec<u8> {
217		legacy_prefixed_key::<H>(hash, prefix)
218	}
219}
220
221/// Legacy method for db using previous version of prefix encoding.
222/// Only for trie radix 16 trie.
223#[deprecated(since = "0.22.0")]
224pub fn legacy_prefixed_key<H: KeyHasher>(key: &H::Out, prefix: Prefix) -> Vec<u8> {
225	let mut prefixed_key = Vec::with_capacity(key.as_ref().len() + prefix.0.len() + 1);
226	if let Some(last) = prefix.1 {
227		let mut prev = 0x01u8;
228		for i in prefix.0.iter() {
229			prefixed_key.push((prev << 4) + (*i >> 4));
230			prev = *i;
231		}
232		prefixed_key.push((prev << 4) + (last >> 4));
233	} else {
234		prefixed_key.push(0);
235		prefixed_key.extend_from_slice(prefix.0);
236	}
237	prefixed_key.extend_from_slice(key.as_ref());
238	prefixed_key
239}
240
241impl<H, KF, T> Default for MemoryDB<H, KF, T>
242where
243	H: KeyHasher,
244	T: for<'a> From<&'a [u8]>,
245	KF: KeyFunction<H>,
246{
247	fn default() -> Self {
248		Self::from_null_node(&[0u8][..], [0u8][..].into())
249	}
250}
251
252/// Create a new `MemoryDB` from a given null key/data
253impl<H, KF, T> MemoryDB<H, KF, T>
254where
255	H: KeyHasher,
256	T: Default,
257	KF: KeyFunction<H>,
258{
259	/// Remove an element and delete it from storage if reference count reaches zero.
260	/// If the value was purged, return the old value.
261	pub fn remove_and_purge(&mut self, key: &<H as KeyHasher>::Out, prefix: Prefix) -> Option<T> {
262		if key == &self.hashed_null_node {
263			return None
264		}
265		let key = KF::key(key, prefix);
266		match self.data.entry(key) {
267			Entry::Occupied(mut entry) =>
268				if entry.get().1 == 1 {
269					let (value, _) = entry.remove();
270					Some(value)
271				} else {
272					entry.get_mut().1 -= 1;
273					None
274				},
275			Entry::Vacant(entry) => {
276				let value = T::default();
277				entry.insert((value, -1));
278				None
279			},
280		}
281	}
282
283	/// Shrinks the capacity of the map as much as possible. It will drop
284	/// down as much as possible while maintaining the internal rules
285	/// and possibly leaving some space in accordance with the resize policy.
286	#[inline]
287	pub fn shrink_to_fit(&mut self) {
288		#[cfg(feature = "std")]
289		self.data.shrink_to_fit();
290	}
291}
292
293impl<H, KF, T> MemoryDB<H, KF, T>
294where
295	H: KeyHasher,
296	T: for<'a> From<&'a [u8]>,
297	KF: KeyFunction<H>,
298{
299	/// Create a new `MemoryDB` from a given null key/data
300	pub fn from_null_node(null_key: &[u8], null_node_data: T) -> Self {
301		MemoryDB {
302			data: Map::default(),
303			hashed_null_node: H::hash(null_key),
304			null_node_data,
305			_kf: Default::default(),
306		}
307	}
308
309	/// Create a new instance of `Self`.
310	pub fn new(data: &[u8]) -> Self {
311		Self::from_null_node(data, data.into())
312	}
313
314	/// Create a new default instance of `Self` and returns `Self` and the root hash.
315	pub fn default_with_root() -> (Self, H::Out) {
316		let db = Self::default();
317		let root = db.hashed_null_node;
318
319		(db, root)
320	}
321
322	/// Clear all data from the database.
323	///
324	/// # Examples
325	/// ```rust
326	/// extern crate hash_db;
327	/// extern crate keccak_hasher;
328	/// extern crate memory_db;
329	///
330	/// use hash_db::{Hasher, HashDB, EMPTY_PREFIX};
331	/// use keccak_hasher::KeccakHasher;
332	/// use memory_db::{MemoryDB, HashKey};
333	///
334	/// fn main() {
335	///   let mut m = MemoryDB::<KeccakHasher, HashKey<_>, Vec<u8>>::default();
336	///   let hello_bytes = "Hello world!".as_bytes();
337	///   let hash = m.insert(EMPTY_PREFIX, hello_bytes);
338	///   assert!(m.contains(&hash, EMPTY_PREFIX));
339	///   m.clear();
340	///   assert!(!m.contains(&hash, EMPTY_PREFIX));
341	/// }
342	/// ```
343	pub fn clear(&mut self) {
344		self.data.clear();
345	}
346
347	/// Purge all zero-referenced data from the database.
348	pub fn purge(&mut self) {
349		self.data.retain(|_, (_, rc)| {
350			let keep = *rc != 0;
351			keep
352		});
353	}
354
355	/// Return the internal key-value Map, clearing the current state.
356	pub fn drain(&mut self) -> Map<KF::Key, (T, i32)> {
357		mem::take(&mut self.data)
358	}
359
360	/// Grab the raw information associated with a key. Returns None if the key
361	/// doesn't exist.
362	///
363	/// Even when Some is returned, the data is only guaranteed to be useful
364	/// when the refs > 0.
365	pub fn raw(&self, key: &<H as KeyHasher>::Out, prefix: Prefix) -> Option<(&T, i32)> {
366		if key == &self.hashed_null_node {
367			return Some((&self.null_node_data, 1))
368		}
369		self.data.get(&KF::key(key, prefix)).map(|(value, count)| (value, *count))
370	}
371
372	/// Consolidate all the entries of `other` into `self`.
373	pub fn consolidate(&mut self, mut other: Self) {
374		for (key, (value, rc)) in other.drain() {
375			match self.data.entry(key) {
376				Entry::Occupied(mut entry) => {
377					if entry.get().1 < 0 {
378						entry.get_mut().0 = value;
379					}
380
381					entry.get_mut().1 += rc;
382				},
383				Entry::Vacant(entry) => {
384					entry.insert((value, rc));
385				},
386			}
387		}
388	}
389
390	/// Get the keys in the database together with number of underlying references.
391	pub fn keys(&self) -> Map<KF::Key, i32> {
392		self.data
393			.iter()
394			.filter_map(|(k, v)| if v.1 != 0 { Some((k.clone(), v.1)) } else { None })
395			.collect()
396	}
397}
398
399impl<H, KF, T> PlainDB<H::Out, T> for MemoryDB<H, KF, T>
400where
401	H: KeyHasher,
402	T: Default + PartialEq<T> + for<'a> From<&'a [u8]> + Clone + Send + Sync,
403	KF: Send + Sync + KeyFunction<H>,
404	KF::Key: Borrow<[u8]> + for<'a> From<&'a [u8]>,
405{
406	fn get(&self, key: &H::Out) -> Option<T> {
407		match self.data.get(key.as_ref()) {
408			Some(&(ref d, rc)) if rc > 0 => Some(d.clone()),
409			_ => None,
410		}
411	}
412
413	fn contains(&self, key: &H::Out) -> bool {
414		match self.data.get(key.as_ref()) {
415			Some(&(_, x)) if x > 0 => true,
416			_ => false,
417		}
418	}
419
420	fn emplace(&mut self, key: H::Out, value: T) {
421		match self.data.entry(key.as_ref().into()) {
422			Entry::Occupied(mut entry) => {
423				let &mut (ref mut old_value, ref mut rc) = entry.get_mut();
424				if *rc <= 0 {
425					*old_value = value;
426				}
427				*rc += 1;
428			},
429			Entry::Vacant(entry) => {
430				entry.insert((value, 1));
431			},
432		}
433	}
434
435	fn remove(&mut self, key: &H::Out) {
436		match self.data.entry(key.as_ref().into()) {
437			Entry::Occupied(mut entry) => {
438				let &mut (_, ref mut rc) = entry.get_mut();
439				*rc -= 1;
440			},
441			Entry::Vacant(entry) => {
442				let value = T::default();
443				entry.insert((value, -1));
444			},
445		}
446	}
447}
448
449impl<H, KF, T> PlainDBRef<H::Out, T> for MemoryDB<H, KF, T>
450where
451	H: KeyHasher,
452	T: Default + PartialEq<T> + for<'a> From<&'a [u8]> + Clone + Send + Sync,
453	KF: Send + Sync + KeyFunction<H>,
454	KF::Key: Borrow<[u8]> + for<'a> From<&'a [u8]>,
455{
456	fn get(&self, key: &H::Out) -> Option<T> {
457		PlainDB::get(self, key)
458	}
459	fn contains(&self, key: &H::Out) -> bool {
460		PlainDB::contains(self, key)
461	}
462}
463
464impl<H, KF, T> HashDB<H, T> for MemoryDB<H, KF, T>
465where
466	H: KeyHasher,
467	T: Default + PartialEq<T> + AsRef<[u8]> + for<'a> From<&'a [u8]> + Clone + Send + Sync,
468	KF: KeyFunction<H> + Send + Sync,
469{
470	fn get(&self, key: &H::Out, prefix: Prefix) -> Option<T> {
471		if key == &self.hashed_null_node {
472			return Some(self.null_node_data.clone())
473		}
474
475		let key = KF::key(key, prefix);
476		match self.data.get(&key) {
477			Some(&(ref d, rc)) if rc > 0 => Some(d.clone()),
478			_ => None,
479		}
480	}
481
482	fn contains(&self, key: &H::Out, prefix: Prefix) -> bool {
483		if key == &self.hashed_null_node {
484			return true
485		}
486
487		let key = KF::key(key, prefix);
488		match self.data.get(&key) {
489			Some(&(_, x)) if x > 0 => true,
490			_ => false,
491		}
492	}
493
494	fn emplace(&mut self, key: H::Out, prefix: Prefix, value: T) {
495		if value == self.null_node_data {
496			return
497		}
498
499		let key = KF::key(&key, prefix);
500		match self.data.entry(key) {
501			Entry::Occupied(mut entry) => {
502				let &mut (ref mut old_value, ref mut rc) = entry.get_mut();
503				if *rc <= 0 {
504					*old_value = value;
505				}
506				*rc += 1;
507			},
508			Entry::Vacant(entry) => {
509				entry.insert((value, 1));
510			},
511		}
512	}
513
514	fn insert(&mut self, prefix: Prefix, value: &[u8]) -> H::Out {
515		if T::from(value) == self.null_node_data {
516			return self.hashed_null_node
517		}
518
519		let key = H::hash(value);
520		HashDB::emplace(self, key, prefix, value.into());
521		key
522	}
523
524	fn remove(&mut self, key: &H::Out, prefix: Prefix) {
525		if key == &self.hashed_null_node {
526			return
527		}
528
529		let key = KF::key(key, prefix);
530		match self.data.entry(key) {
531			Entry::Occupied(mut entry) => {
532				let &mut (_, ref mut rc) = entry.get_mut();
533				*rc -= 1;
534			},
535			Entry::Vacant(entry) => {
536				let value = T::default();
537				entry.insert((value, -1));
538			},
539		}
540	}
541}
542
543impl<H, KF, T> HashDBRef<H, T> for MemoryDB<H, KF, T>
544where
545	H: KeyHasher,
546	T: Default + PartialEq<T> + AsRef<[u8]> + for<'a> From<&'a [u8]> + Clone + Send + Sync,
547	KF: KeyFunction<H> + Send + Sync,
548{
549	fn get(&self, key: &H::Out, prefix: Prefix) -> Option<T> {
550		HashDB::get(self, key, prefix)
551	}
552	fn contains(&self, key: &H::Out, prefix: Prefix) -> bool {
553		HashDB::contains(self, key, prefix)
554	}
555}
556
557impl<H, KF, T> AsPlainDB<H::Out, T> for MemoryDB<H, KF, T>
558where
559	H: KeyHasher,
560	T: Default + PartialEq<T> + for<'a> From<&'a [u8]> + Clone + Send + Sync,
561	KF: KeyFunction<H> + Send + Sync,
562	KF::Key: Borrow<[u8]> + for<'a> From<&'a [u8]>,
563{
564	fn as_plain_db(&self) -> &dyn PlainDB<H::Out, T> {
565		self
566	}
567	fn as_plain_db_mut(&mut self) -> &mut dyn PlainDB<H::Out, T> {
568		self
569	}
570}
571
572impl<H, KF, T> AsHashDB<H, T> for MemoryDB<H, KF, T>
573where
574	H: KeyHasher,
575	T: Default + PartialEq<T> + AsRef<[u8]> + for<'a> From<&'a [u8]> + Clone + Send + Sync,
576	KF: KeyFunction<H> + Send + Sync,
577{
578	fn as_hash_db(&self) -> &dyn HashDB<H, T> {
579		self
580	}
581	fn as_hash_db_mut(&mut self) -> &mut dyn HashDB<H, T> {
582		self
583	}
584}
585
586#[cfg(test)]
587mod tests {
588	use super::{HashDB, HashKey, KeyHasher, MemoryDB};
589	use hash_db::EMPTY_PREFIX;
590	use keccak_hasher::KeccakHasher;
591
592	#[test]
593	fn memorydb_remove_and_purge() {
594		let hello_bytes = b"Hello world!";
595		let hello_key = KeccakHasher::hash(hello_bytes);
596
597		let mut m = MemoryDB::<KeccakHasher, HashKey<_>, Vec<u8>>::default();
598		m.remove(&hello_key, EMPTY_PREFIX);
599		assert_eq!(m.raw(&hello_key, EMPTY_PREFIX).unwrap().1, -1);
600		m.purge();
601		assert_eq!(m.raw(&hello_key, EMPTY_PREFIX).unwrap().1, -1);
602		m.insert(EMPTY_PREFIX, hello_bytes);
603		assert_eq!(m.raw(&hello_key, EMPTY_PREFIX).unwrap().1, 0);
604		m.purge();
605		assert_eq!(m.raw(&hello_key, EMPTY_PREFIX), None);
606
607		let mut m = MemoryDB::<KeccakHasher, HashKey<_>, Vec<u8>>::default();
608		assert!(m.remove_and_purge(&hello_key, EMPTY_PREFIX).is_none());
609		assert_eq!(m.raw(&hello_key, EMPTY_PREFIX).unwrap().1, -1);
610		m.insert(EMPTY_PREFIX, hello_bytes);
611		m.insert(EMPTY_PREFIX, hello_bytes);
612		assert_eq!(m.raw(&hello_key, EMPTY_PREFIX).unwrap().1, 1);
613		assert_eq!(&*m.remove_and_purge(&hello_key, EMPTY_PREFIX).unwrap(), hello_bytes);
614		assert_eq!(m.raw(&hello_key, EMPTY_PREFIX), None);
615		assert!(m.remove_and_purge(&hello_key, EMPTY_PREFIX).is_none());
616	}
617
618	#[test]
619	fn consolidate() {
620		let mut main = MemoryDB::<KeccakHasher, HashKey<_>, Vec<u8>>::default();
621		let mut other = MemoryDB::<KeccakHasher, HashKey<_>, Vec<u8>>::default();
622		let remove_key = other.insert(EMPTY_PREFIX, b"doggo");
623		main.remove(&remove_key, EMPTY_PREFIX);
624
625		let insert_key = other.insert(EMPTY_PREFIX, b"arf");
626		main.emplace(insert_key, EMPTY_PREFIX, "arf".as_bytes().to_vec());
627
628		let negative_remove_key = other.insert(EMPTY_PREFIX, b"negative");
629		other.remove(&negative_remove_key, EMPTY_PREFIX); // ref cnt: 0
630		other.remove(&negative_remove_key, EMPTY_PREFIX); // ref cnt: -1
631		main.remove(&negative_remove_key, EMPTY_PREFIX); // ref cnt: -1
632
633		main.consolidate(other);
634
635		assert_eq!(main.raw(&remove_key, EMPTY_PREFIX).unwrap(), (&"doggo".as_bytes().to_vec(), 0));
636		assert_eq!(main.raw(&insert_key, EMPTY_PREFIX).unwrap(), (&"arf".as_bytes().to_vec(), 2));
637		assert_eq!(
638			main.raw(&negative_remove_key, EMPTY_PREFIX).unwrap(),
639			(&"negative".as_bytes().to_vec(), -2),
640		);
641	}
642
643	#[test]
644	fn default_works() {
645		let mut db = MemoryDB::<KeccakHasher, HashKey<_>, Vec<u8>>::default();
646		let hashed_null_node = KeccakHasher::hash(&[0u8][..]);
647		assert_eq!(db.insert(EMPTY_PREFIX, &[0u8][..]), hashed_null_node);
648
649		let (db2, root) = MemoryDB::<KeccakHasher, HashKey<_>, Vec<u8>>::default_with_root();
650		assert!(db2.contains(&root, EMPTY_PREFIX));
651		assert!(db.contains(&root, EMPTY_PREFIX));
652	}
653}