diff --git a/Cargo.lock b/Cargo.lock index 1430acb1b2..16493560c4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -294,6 +294,7 @@ dependencies = [ "kvdb-rocksdb 0.1.0", "linked-hash-map 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "lru-cache 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "memorydb 0.1.1", "num-rational 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)", @@ -515,7 +516,7 @@ dependencies = [ "kvdb 0.1.0", "kvdb-memorydb 0.1.0", "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "lru-cache 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "lru-cache 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)", "primitives 0.4.0 (git+https://github.com/CodeChain-io/rust-codechain-primitives.git)", "rlp 0.2.1", @@ -1430,11 +1431,6 @@ dependencies = [ "slab 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "linked-hash-map" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" - [[package]] name = "linked-hash-map" version = "0.5.1" @@ -1477,10 +1473,10 @@ dependencies = [ [[package]] name = "lru-cache" -version = "0.1.1" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "linked-hash-map 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", + "linked-hash-map 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -3183,13 +3179,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum libflate 0.1.23 (registry+https://github.com/rust-lang/crates.io-index)" = "76912aa0196b6f0e06d9c43ee877be45369157c06172ade12fe20ac3ee5ffa15" "checksum libz-sys 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)" = "2eb5e43362e38e2bca2fd5f5134c4d4564a23a5c28e9b95411652021a8675ebe" "checksum limited-table 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5edd8173067e26a4f03c90698a4de70084862bbbe0c7f2dfe65a1274c35a4d3e" -"checksum linked-hash-map 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7860ec297f7008ff7a1e3382d7f7e1dcd69efc94751a2284bafc3d013c2aa939" "checksum linked-hash-map 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "70fb39025bc7cdd76305867c4eccf2f2dcf6e9a57f5b21a93e1c2d86cd03ec9e" "checksum local-encoding 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e1ceb20f39ff7ae42f3ff9795f3986b1daad821caaa1e1732a0944103a5a1a66" "checksum lock_api 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "949826a5ccf18c1b3a7c3d57692778d21768b79e46eb9dd07bfc4c2160036c54" "checksum log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "e19e8d5c34a3e0e2223db8e060f9e8264aeeb5c5fc64a4ee9965c062211c024b" "checksum log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c84ec4b527950aa83a329754b01dbe3f58361d1c5efacd1f6d68c494d08a17c6" -"checksum lru-cache 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4d06ff7ff06f729ce5f4e227876cb88d10bc59cd4ae1e09fbb2bde15c850dc21" +"checksum lru-cache 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "31e24f1ad8321ca0e8a1e0ac13f23cb668e6f5466c2c57319f6a5cf1cc8e3b1c" "checksum matches 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "100aabe6b8ff4e4a7e32c1c13523379802df0772b82466207ac25b013f193376" "checksum memchr 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "796fba70e76612589ed2ce7f45282f5af869e0fdd7cc6199fa1aa1f1d591ba9d" "checksum memoffset 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0f9dc261e2b62d7a622bf416ea3c5245cdd5d9a7fcc428c0d06804dfce1775b3" diff --git a/core/Cargo.toml b/core/Cargo.toml index a64f993f2c..cfcff63a5a 100644 --- a/core/Cargo.toml +++ b/core/Cargo.toml @@ -24,6 +24,7 @@ hyper = { git = "https://github.com/paritytech/hyper", default-features = false journaldb = { path = "../util/journaldb" } linked-hash-map = "0.5" log = "0.4.6" +lru-cache = "0.1.2" kvdb = { path = "../util/kvdb" } kvdb-rocksdb = { path = "../util/kvdb-rocksdb" } kvdb-memorydb = { path = "../util/kvdb-memorydb" } diff --git a/core/src/blockchain/body_db.rs b/core/src/blockchain/body_db.rs index 01fc8aff88..547c4c4b43 100644 --- a/core/src/blockchain/body_db.rs +++ b/core/src/blockchain/body_db.rs @@ -19,6 +19,7 @@ use std::mem; use std::sync::Arc; use kvdb::{DBTransaction, KeyValueDB}; +use lru_cache::LruCache; use parking_lot::{Mutex, RwLock}; use primitives::{Bytes, H256}; use rlp::RlpStream; @@ -30,9 +31,11 @@ use crate::db::{self, CacheUpdatePolicy, Readable, Writable}; use crate::views::BlockView; use crate::{encoded, UnverifiedTransaction}; +const BODY_CACHE_SIZE: usize = 1000; + pub struct BodyDB { // block cache - body_cache: RwLock>, + body_cache: Mutex>, parcel_address_cache: RwLock>, pending_parcel_addresses: RwLock>>, @@ -48,7 +51,7 @@ impl BodyDB { /// Create new instance of blockchain from given Genesis. pub fn new(genesis: &BlockView, db: Arc) -> Self { let bdb = Self { - body_cache: RwLock::new(HashMap::new()), + body_cache: Mutex::new(LruCache::new(BODY_CACHE_SIZE)), parcel_address_cache: RwLock::new(HashMap::new()), pending_parcel_addresses: RwLock::new(HashMap::new()), @@ -308,8 +311,8 @@ impl BodyProvider for BodyDB { fn block_body(&self, hash: &H256) -> Option { // Check cache first { - let read = self.body_cache.read(); - if let Some(v) = read.get(hash) { + let mut lock = self.body_cache.lock(); + if let Some(v) = lock.get_mut(hash) { return Some(encoded::Body::new(v.clone())) } } @@ -319,8 +322,8 @@ impl BodyProvider for BodyDB { self.db.get(db::COL_BODIES, hash).expect("Low level database error. Some issue with disk?")?; let raw_body = decompress(&compressed_body, blocks_swapper()).into_vec(); - let mut write = self.body_cache.write(); - write.insert(*hash, raw_body.clone()); + let mut lock = self.body_cache.lock(); + lock.insert(*hash, raw_body.clone()); Some(encoded::Body::new(raw_body)) } diff --git a/core/src/blockchain/headerchain.rs b/core/src/blockchain/headerchain.rs index 0ec0d03234..c3d78fc20e 100644 --- a/core/src/blockchain/headerchain.rs +++ b/core/src/blockchain/headerchain.rs @@ -21,6 +21,7 @@ use std::sync::Arc; use ctypes::header::{Header, Seal}; use ctypes::BlockNumber; use kvdb::{DBTransaction, KeyValueDB}; +use lru_cache::LruCache; use parking_lot::{Mutex, RwLock}; use primitives::{Bytes, H256}; use rlp_compress::{blocks_swapper, compress, decompress}; @@ -35,6 +36,7 @@ use crate::views::HeaderView; const BEST_HEADER_KEY: &[u8] = b"best-header"; const BEST_PROPOSAL_HEADER_KEY: &[u8] = b"best-proposal-header"; +const HEADER_CACHE_SIZE: usize = 1000; /// Structure providing fast access to blockchain data. /// @@ -47,7 +49,7 @@ pub struct HeaderChain { best_proposal_header_hash: RwLock, // cache - header_cache: RwLock>, + header_cache: Mutex>, detail_cache: RwLock>, hash_cache: Mutex>, @@ -99,7 +101,7 @@ impl HeaderChain { best_header_hash: RwLock::new(best_header_hash), best_proposal_header_hash: RwLock::new(best_proposal_header_hash), - header_cache: RwLock::new(HashMap::new()), + header_cache: Mutex::new(LruCache::new(HEADER_CACHE_SIZE)), detail_cache: Default::default(), hash_cache: Default::default(), @@ -401,11 +403,11 @@ impl HeaderProvider for HeaderChain { } /// Get block header data -fn block_header_data(hash: &H256, header_cache: &RwLock>, db: &KeyValueDB) -> Option> { +fn block_header_data(hash: &H256, header_cache: &Mutex>, db: &KeyValueDB) -> Option> { // Check cache first { - let read = header_cache.read(); - if let Some(v) = read.get(hash) { + let mut lock = header_cache.lock(); + if let Some(v) = lock.get_mut(hash) { return Some(v.clone()) } } @@ -414,13 +416,13 @@ fn block_header_data(hash: &H256, header_cache: &RwLock>, d let bytes = decompress(&b, blocks_swapper()).into_vec(); - let mut write = header_cache.write(); - if let Some(v) = write.get(hash) { + let mut lock = header_cache.lock(); + if let Some(v) = lock.get_mut(hash) { assert_eq!(&bytes, v); return Some(v.clone()) } - write.insert(*hash, bytes.clone()); + lock.insert(*hash, bytes.clone()); Some(bytes) } diff --git a/core/src/lib.rs b/core/src/lib.rs index 4bc39ca47e..4de7795106 100644 --- a/core/src/lib.rs +++ b/core/src/lib.rs @@ -38,6 +38,7 @@ extern crate kvdb; extern crate kvdb_memorydb; extern crate kvdb_rocksdb; extern crate linked_hash_map; +extern crate lru_cache; extern crate memorydb; extern crate num_rational; extern crate primitives;