tetcore_database/
mem.rs

1// This file is part of Tetcore.
2
3// Copyright (C) 2017-2021 Parity Technologies (UK) Ltd.
4// SPDX-License-Identifier: Apache-2.0
5
6// Licensed under the Apache License, Version 2.0 (the "License");
7// you may not use this file except in compliance with the License.
8// You may obtain a copy of the License at
9//
10// 	http://www.apache.org/licenses/LICENSE-2.0
11//
12// Unless required by applicable law or agreed to in writing, software
13// distributed under the License is distributed on an "AS IS" BASIS,
14// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15// See the License for the specific language governing permissions and
16// limitations under the License.
17
18//! In-memory implementation of `Database`
19
20use std::collections::HashMap;
21use crate::{Database, Change, ColumnId, Transaction, error};
22use parking_lot::RwLock;
23
24#[derive(Default)]
25/// This implements `Database` as an in-memory hash map. `commit` is not atomic.
26pub struct MemDb<H: Clone + Send + Sync + Eq + PartialEq + Default + std::hash::Hash>
27	(RwLock<(HashMap<ColumnId, HashMap<Vec<u8>, Vec<u8>>>, HashMap<H, Vec<u8>>)>);
28
29impl<H> Database<H> for MemDb<H>
30	where H: Clone + Send + Sync + Eq + PartialEq + Default + std::hash::Hash
31{
32	fn commit(&self, transaction: Transaction<H>) -> error::Result<()> {
33		let mut s = self.0.write();
34		for change in transaction.0.into_iter() {
35			match change {
36				Change::Set(col, key, value) => { s.0.entry(col).or_default().insert(key, value); },
37				Change::Remove(col, key) => { s.0.entry(col).or_default().remove(&key); },
38				Change::Store(hash, preimage) => { s.1.insert(hash, preimage); },
39				Change::Release(hash) => { s.1.remove(&hash); },
40			}
41		}
42
43		Ok(())
44	}
45
46	fn get(&self, col: ColumnId, key: &[u8]) -> Option<Vec<u8>> {
47		let s = self.0.read();
48		s.0.get(&col).and_then(|c| c.get(key).cloned())
49	}
50
51	fn lookup(&self, hash: &H) -> Option<Vec<u8>> {
52		let s = self.0.read();
53		s.1.get(hash).cloned()
54	}
55}
56
57impl<H> MemDb<H>
58	where H: Clone + Send + Sync + Eq + PartialEq + Default + std::hash::Hash
59{
60	/// Create a new instance
61	pub fn new() -> Self {
62		MemDb::default()
63	}
64
65	/// Count number of values in a column
66	pub fn count(&self, col: ColumnId) -> usize {
67		let s = self.0.read();
68		s.0.get(&col).map(|c| c.len()).unwrap_or(0)
69	}
70}
71