Skip to content

Commit 2cc2646

Browse files
authored
replace lru with schnellru (paritytech#14539)
1 parent 3fee5c7 commit 2cc2646

11 files changed

Lines changed: 58 additions & 71 deletions

File tree

Cargo.lock

Lines changed: 4 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

client/executor/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,8 @@ readme = "README.md"
1414
targets = ["x86_64-unknown-linux-gnu"]
1515

1616
[dependencies]
17-
lru = "0.10.0"
1817
parking_lot = "0.12.1"
18+
schnellru = "0.2.1"
1919
tracing = "0.1.29"
2020

2121
codec = { package = "parity-scale-codec", version = "3.6.1" }

client/executor/src/wasm_runtime.rs

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -22,24 +22,24 @@
2222
//! components of the runtime that are expensive to initialize.
2323
2424
use crate::error::{Error, WasmError};
25+
2526
use codec::Decode;
26-
use lru::LruCache;
2727
use parking_lot::Mutex;
2828
use sc_executor_common::{
2929
runtime_blob::RuntimeBlob,
3030
wasm_runtime::{HeapAllocStrategy, WasmInstance, WasmModule},
3131
};
32+
use schnellru::{ByLength, LruMap};
3233
use sp_core::traits::{Externalities, FetchRuntimeCode, RuntimeCode};
3334
use sp_version::RuntimeVersion;
35+
use sp_wasm_interface::HostFunctions;
36+
3437
use std::{
35-
num::NonZeroUsize,
3638
panic::AssertUnwindSafe,
3739
path::{Path, PathBuf},
3840
sync::Arc,
3941
};
4042

41-
use sp_wasm_interface::HostFunctions;
42-
4343
/// Specification of different methods of executing the runtime Wasm code.
4444
#[derive(Debug, PartialEq, Eq, Hash, Copy, Clone)]
4545
pub enum WasmExecutionMethod {
@@ -163,7 +163,7 @@ pub struct RuntimeCache {
163163
/// A cache of runtimes along with metadata.
164164
///
165165
/// Runtimes sorted by recent usage. The most recently used is at the front.
166-
runtimes: Mutex<LruCache<VersionedRuntimeId, Arc<VersionedRuntime>>>,
166+
runtimes: Mutex<LruMap<VersionedRuntimeId, Arc<VersionedRuntime>>>,
167167
/// The size of the instances cache for each runtime.
168168
max_runtime_instances: usize,
169169
cache_path: Option<PathBuf>,
@@ -185,9 +185,8 @@ impl RuntimeCache {
185185
cache_path: Option<PathBuf>,
186186
runtime_cache_size: u8,
187187
) -> RuntimeCache {
188-
let cap =
189-
NonZeroUsize::new(runtime_cache_size.max(1) as usize).expect("cache size is not zero");
190-
RuntimeCache { runtimes: Mutex::new(LruCache::new(cap)), max_runtime_instances, cache_path }
188+
let cap = ByLength::new(runtime_cache_size.max(1) as u32);
189+
RuntimeCache { runtimes: Mutex::new(LruMap::new(cap)), max_runtime_instances, cache_path }
191190
}
192191

193192
/// Prepares a WASM module instance and executes given function for it.
@@ -275,7 +274,7 @@ impl RuntimeCache {
275274
let versioned_runtime = Arc::new(result?);
276275

277276
// Save new versioned wasm runtime in cache
278-
runtimes.put(versioned_runtime_id, versioned_runtime.clone());
277+
runtimes.insert(versioned_runtime_id, versioned_runtime.clone());
279278

280279
versioned_runtime
281280
};

client/network-gossip/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ futures = "0.3.21"
1919
futures-timer = "3.0.1"
2020
libp2p = "0.51.3"
2121
log = "0.4.17"
22-
lru = "0.10.0"
22+
schnellru = "0.2.1"
2323
tracing = "0.1.29"
2424
prometheus-endpoint = { package = "substrate-prometheus-endpoint", version = "0.10.0-dev", path = "../../utils/prometheus" }
2525
sc-network = { version = "0.10.0-dev", path = "../network/" }

client/network-gossip/src/state_machine.rs

Lines changed: 13 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -20,12 +20,13 @@ use crate::{MessageIntent, Network, ValidationResult, Validator, ValidatorContex
2020

2121
use ahash::AHashSet;
2222
use libp2p::PeerId;
23-
use lru::LruCache;
23+
use schnellru::{ByLength, LruMap};
24+
2425
use prometheus_endpoint::{register, Counter, PrometheusError, Registry, U64};
2526
use sc_network::types::ProtocolName;
2627
use sc_network_common::role::ObservedRole;
2728
use sp_runtime::traits::{Block as BlockT, Hash, HashFor};
28-
use std::{collections::HashMap, iter, num::NonZeroUsize, sync::Arc, time, time::Instant};
29+
use std::{collections::HashMap, iter, sync::Arc, time, time::Instant};
2930

3031
// FIXME: Add additional spam/DoS attack protection: https://github.com/paritytech/substrate/issues/1115
3132
// NOTE: The current value is adjusted based on largest production network deployment (Kusama) and
@@ -36,7 +37,7 @@ use std::{collections::HashMap, iter, num::NonZeroUsize, sync::Arc, time, time::
3637
//
3738
// Assuming that each known message is tracked with a 32 byte hash (common for `Block::Hash`), then
3839
// this cache should take about 256 KB of memory.
39-
const KNOWN_MESSAGES_CACHE_SIZE: usize = 8192;
40+
const KNOWN_MESSAGES_CACHE_SIZE: u32 = 8192;
4041

4142
const REBROADCAST_INTERVAL: time::Duration = time::Duration::from_millis(750);
4243

@@ -155,7 +156,7 @@ where
155156
pub struct ConsensusGossip<B: BlockT> {
156157
peers: HashMap<PeerId, PeerConsensus<B::Hash>>,
157158
messages: Vec<MessageEntry<B>>,
158-
known_messages: LruCache<B::Hash, ()>,
159+
known_messages: LruMap<B::Hash, ()>,
159160
protocol: ProtocolName,
160161
validator: Arc<dyn Validator<B>>,
161162
next_broadcast: Instant,
@@ -181,11 +182,7 @@ impl<B: BlockT> ConsensusGossip<B> {
181182
ConsensusGossip {
182183
peers: HashMap::new(),
183184
messages: Default::default(),
184-
known_messages: {
185-
let cap = NonZeroUsize::new(KNOWN_MESSAGES_CACHE_SIZE)
186-
.expect("cache capacity is not zero");
187-
LruCache::new(cap)
188-
},
185+
known_messages: { LruMap::new(ByLength::new(KNOWN_MESSAGES_CACHE_SIZE)) },
189186
protocol,
190187
validator,
191188
next_broadcast: Instant::now() + REBROADCAST_INTERVAL,
@@ -216,7 +213,7 @@ impl<B: BlockT> ConsensusGossip<B> {
216213
message: Vec<u8>,
217214
sender: Option<PeerId>,
218215
) {
219-
if self.known_messages.put(message_hash, ()).is_none() {
216+
if self.known_messages.insert(message_hash, ()) {
220217
self.messages.push(MessageEntry { message_hash, topic, message, sender });
221218

222219
if let Some(ref metrics) = self.metrics {
@@ -313,7 +310,7 @@ impl<B: BlockT> ConsensusGossip<B> {
313310
);
314311

315312
for (_, ref mut peer) in self.peers.iter_mut() {
316-
peer.known_messages.retain(|h| known_messages.contains(h));
313+
peer.known_messages.retain(|h| known_messages.get(h).is_some());
317314
}
318315
}
319316

@@ -348,7 +345,7 @@ impl<B: BlockT> ConsensusGossip<B> {
348345
for message in messages {
349346
let message_hash = HashFor::<B>::hash(&message[..]);
350347

351-
if self.known_messages.contains(&message_hash) {
348+
if self.known_messages.get(&message_hash).is_some() {
352349
tracing::trace!(
353350
target: "gossip",
354351
%who,
@@ -545,7 +542,7 @@ mod tests {
545542

546543
macro_rules! push_msg {
547544
($consensus:expr, $topic:expr, $hash: expr, $m:expr) => {
548-
if $consensus.known_messages.put($hash, ()).is_none() {
545+
if $consensus.known_messages.insert($hash, ()) {
549546
$consensus.messages.push(MessageEntry {
550547
message_hash: $hash,
551548
topic: $topic,
@@ -720,8 +717,8 @@ mod tests {
720717

721718
push_msg!(consensus, prev_hash, m1_hash, m1);
722719
push_msg!(consensus, best_hash, m2_hash, m2);
723-
consensus.known_messages.put(m1_hash, ());
724-
consensus.known_messages.put(m2_hash, ());
720+
consensus.known_messages.insert(m1_hash, ());
721+
consensus.known_messages.insert(m2_hash, ());
725722

726723
consensus.collect_garbage();
727724
assert_eq!(consensus.messages.len(), 2);
@@ -734,7 +731,7 @@ mod tests {
734731
assert_eq!(consensus.messages.len(), 1);
735732
// known messages are only pruned based on size.
736733
assert_eq!(consensus.known_messages.len(), 2);
737-
assert!(consensus.known_messages.contains(&m2_hash));
734+
assert!(consensus.known_messages.get(&m2_hash).is_some());
738735
}
739736

740737
#[test]

client/network/sync/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,9 @@ futures = "0.3.21"
2424
futures-timer = "3.0.2"
2525
libp2p = "0.51.3"
2626
log = "0.4.17"
27-
lru = "0.10.0"
2827
mockall = "0.11.3"
2928
prost = "0.11"
29+
schnellru = "0.2.1"
3030
smallvec = "1.8.0"
3131
thiserror = "1.0"
3232
fork-tree = { version = "3.0.0", path = "../../../utils/fork-tree" }

client/network/sync/src/block_request_handler.rs

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,8 @@ use codec::{Decode, Encode};
2626
use futures::{channel::oneshot, stream::StreamExt};
2727
use libp2p::PeerId;
2828
use log::debug;
29-
use lru::LruCache;
3029
use prost::Message;
30+
use schnellru::{ByLength, LruMap};
3131

3232
use sc_client_api::BlockBackend;
3333
use sc_network::{
@@ -44,7 +44,6 @@ use sp_runtime::{
4444
use std::{
4545
cmp::min,
4646
hash::{Hash, Hasher},
47-
num::NonZeroUsize,
4847
sync::Arc,
4948
time::Duration,
5049
};
@@ -137,7 +136,7 @@ pub struct BlockRequestHandler<B: BlockT, Client> {
137136
/// Maps from request to number of times we have seen this request.
138137
///
139138
/// This is used to check if a peer is spamming us with the same request.
140-
seen_requests: LruCache<SeenRequestsKey<B>, SeenRequestsValue>,
139+
seen_requests: LruMap<SeenRequestsKey<B>, SeenRequestsValue>,
141140
}
142141

143142
impl<B, Client> BlockRequestHandler<B, Client>
@@ -167,9 +166,8 @@ where
167166
);
168167
protocol_config.inbound_queue = Some(tx);
169168

170-
let capacity =
171-
NonZeroUsize::new(num_peer_hint.max(1) * 2).expect("cache capacity is not zero");
172-
let seen_requests = LruCache::new(capacity);
169+
let capacity = ByLength::new(num_peer_hint.max(1) as u32 * 2);
170+
let seen_requests = LruMap::new(capacity);
173171

174172
(Self { client, request_receiver, seen_requests }, protocol_config)
175173
}
@@ -236,7 +234,7 @@ where
236234
.difference(BlockAttributes::HEADER | BlockAttributes::JUSTIFICATION)
237235
.is_empty();
238236

239-
match self.seen_requests.get_mut(&key) {
237+
match self.seen_requests.get(&key) {
240238
Some(SeenRequestsValue::First) => {},
241239
Some(SeenRequestsValue::Fulfilled(ref mut requests)) => {
242240
*requests = requests.saturating_add(1);
@@ -250,7 +248,7 @@ where
250248
}
251249
},
252250
None => {
253-
self.seen_requests.put(key.clone(), SeenRequestsValue::First);
251+
self.seen_requests.insert(key.clone(), SeenRequestsValue::First);
254252
},
255253
}
256254

@@ -277,7 +275,7 @@ where
277275
.iter()
278276
.any(|b| !b.header.is_empty() || !b.body.is_empty() || b.is_empty_justification)
279277
{
280-
if let Some(value) = self.seen_requests.get_mut(&key) {
278+
if let Some(value) = self.seen_requests.get(&key) {
281279
// If this is the first time we have processed this request, we need to change
282280
// it to `Fulfilled`.
283281
if let SeenRequestsValue::First = value {

client/network/sync/src/engine.rs

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -28,10 +28,10 @@ use codec::{Decode, Encode};
2828
use futures::{FutureExt, StreamExt};
2929
use futures_timer::Delay;
3030
use libp2p::PeerId;
31-
use lru::LruCache;
3231
use prometheus_endpoint::{
3332
register, Gauge, GaugeVec, MetricSource, Opts, PrometheusError, Registry, SourcedGauge, U64,
3433
};
34+
use schnellru::{ByLength, LruMap};
3535

3636
use sc_client_api::{BlockBackend, HeaderBackend, ProofProvider};
3737
use sc_consensus::import_queue::ImportQueueService;
@@ -239,7 +239,7 @@ pub struct SyncingEngine<B: BlockT, Client> {
239239
default_peers_set_num_light: usize,
240240

241241
/// A cache for the data that was associated to a block announcement.
242-
block_announce_data_cache: LruCache<B::Hash, Vec<u8>>,
242+
block_announce_data_cache: LruMap<B::Hash, Vec<u8>>,
243243

244244
/// The `PeerId`'s of all boot nodes.
245245
boot_node_ids: HashSet<PeerId>,
@@ -294,12 +294,9 @@ where
294294
} else {
295295
net_config.network_config.max_blocks_per_request
296296
};
297-
let cache_capacity = NonZeroUsize::new(
298-
(net_config.network_config.default_peers_set.in_peers as usize +
299-
net_config.network_config.default_peers_set.out_peers as usize)
300-
.max(1),
301-
)
302-
.expect("cache capacity is not zero");
297+
let cache_capacity = (net_config.network_config.default_peers_set.in_peers +
298+
net_config.network_config.default_peers_set.out_peers)
299+
.max(1);
303300
let important_peers = {
304301
let mut imp_p = HashSet::new();
305302
for reserved in &net_config.network_config.default_peers_set.reserved_nodes {
@@ -381,7 +378,7 @@ where
381378
network_service,
382379
peers: HashMap::new(),
383380
evicted: HashSet::new(),
384-
block_announce_data_cache: LruCache::new(cache_capacity),
381+
block_announce_data_cache: LruMap::new(ByLength::new(cache_capacity)),
385382
block_announce_protocol_name,
386383
num_connected: num_connected.clone(),
387384
is_major_syncing: is_major_syncing.clone(),
@@ -465,7 +462,7 @@ where
465462

466463
if let Some(data) = announce.data {
467464
if !data.is_empty() {
468-
self.block_announce_data_cache.put(announce.header.hash(), data);
465+
self.block_announce_data_cache.insert(announce.header.hash(), data);
469466
}
470467
}
471468
},

0 commit comments

Comments
 (0)