1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83
use std::{ cell::{RefCell, UnsafeCell}, collections::HashMap, }; use primitive_types::H256; use crate::{CachedDatabaseHandle, Database}; #[derive(Debug)] pub struct CachedHandle<D> { pub db: D, cache: Cache, } impl<D: Clone> Clone for CachedHandle<D> { fn clone(&self) -> Self { Self { db: self.db.clone(), cache: Cache::new(), } } } impl<D: CachedDatabaseHandle> CachedHandle<D> { pub fn new(db: D) -> Self { Self { db, cache: Cache::new(), } } pub fn clear_cache(&mut self) { self.cache = Cache::new(); } } impl<D: CachedDatabaseHandle> Database for CachedHandle<D> { fn get(&self, key: H256) -> &[u8] { if !self.cache.contains_key(key) { self.cache.insert(key, self.db.get(key)) } else { self.cache.get(key).unwrap() } } } #[derive(Debug)] pub struct Cache { cache: UnsafeCell<Vec<Vec<u8>>>, map: RefCell<HashMap<H256, usize>>, } impl Cache { pub fn new() -> Cache { Cache { cache: UnsafeCell::new(Vec::new()), map: RefCell::new(HashMap::new()), } } pub fn insert(&self, key: H256, value: Vec<u8>) -> &[u8] { let cache = unsafe { &mut *self.cache.get() }; let index = cache.len(); self.map.borrow_mut().insert(key, index); cache.push(value); &cache[index] } pub fn get(&self, key: H256) -> Option<&[u8]> { let cache = unsafe { &mut *self.cache.get() }; let map = self.map.borrow_mut(); match map.get(&key) { Some(index) => Some(&cache[*index]), None => None, } } pub fn contains_key(&self, key: H256) -> bool { let map = self.map.borrow_mut(); map.contains_key(&key) } }