-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy pathcache.rs
More file actions
136 lines (123 loc) · 4.01 KB
/
Copy pathcache.rs
File metadata and controls
136 lines (123 loc) · 4.01 KB
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
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
use std::{
sync::{
atomic::{AtomicUsize, Ordering},
Arc,
},
time::Duration,
};
use alloy_primitives::{Address, B256};
use mini_moka::sync::Cache;
/// A thread-safe, in-memory cache for deduplicating order IDs.
#[derive(Debug, Clone)]
pub struct OrderCache {
/// The inner cache.
cache: Cache<B256, ()>,
/// The number of hits.
hits: Arc<AtomicUsize>,
/// The number of misses.
misses: Arc<AtomicUsize>,
}
impl OrderCache {
/// Create a new order cache with the given TTL and size.
/// Includes metrics for hits and misses that are ONLY updated when [`Self::contains`] is
/// called.
pub fn new(cache_ttl: u64, cache_size: u64) -> Self {
Self {
cache: Cache::builder()
.time_to_live(Duration::from_secs(cache_ttl))
.max_capacity(cache_size)
.build(),
hits: Arc::new(AtomicUsize::new(0)),
misses: Arc::new(AtomicUsize::new(0)),
}
}
/// Get the hit ratio of the cache.
pub fn hit_ratio(&self) -> f64 {
let hits = self.hits.load(Ordering::Relaxed);
let misses = self.misses.load(Ordering::Relaxed);
let total = hits + misses;
if total == 0 {
0.0
} else {
hits as f64 / total as f64
}
}
/// Get the number of entries in the cache.
pub fn entry_count(&self) -> u64 {
self.cache.entry_count()
}
/// Insert an order ID into the cache.
pub fn insert(&self, key: B256) {
self.cache.insert(key, ());
}
/// Check if an order ID is in the cache.
/// Updates the metrics for hits and misses.
pub fn contains(&self, id: &B256) -> bool {
if self.cache.contains_key(id) {
self.hits.fetch_add(1, Ordering::Relaxed);
true
} else {
self.misses.fetch_add(1, Ordering::Relaxed);
false
}
}
}
/// A thread-safe, in-memory LRU cache for mapping transactions hashes to recovered signers.
#[derive(Debug, Clone)]
pub struct SignerCache {
/// The inner cache.
cache: Cache<B256, Address>,
/// The number of hits.
hits: Arc<AtomicUsize>,
/// The number of misses.
misses: Arc<AtomicUsize>,
}
impl SignerCache {
/// Create a new signer cache with the given TTL and size.
/// Includes metrics for hits and misses that are ONLY updated when [`Self::get`] is called.
pub fn new(cache_ttl: u64, cache_size: u64) -> Self {
Self {
// NOTE: adding a max capacity with `cache_size` makes this a LRU cache.
cache: Cache::builder()
.time_to_live(Duration::from_secs(cache_ttl))
.max_capacity(cache_size)
.build(),
hits: Arc::new(AtomicUsize::new(0)),
misses: Arc::new(AtomicUsize::new(0)),
}
}
/// Get the hit ratio of the cache.
pub fn hit_ratio(&self) -> f64 {
let hits = self.hits.load(Ordering::Relaxed);
let misses = self.misses.load(Ordering::Relaxed);
let total = hits + misses;
if total == 0 {
0.0
} else {
hits as f64 / total as f64
}
}
/// Get the number of entries in the cache.
pub fn entry_count(&self) -> u64 {
self.cache.entry_count()
}
/// Insert a transaction hash and its recovered signer into the cache.
pub fn insert(&self, tx_hash: B256, signer: Address) {
// TODO: perhaps we should make a "no-op"-like hasher?
self.cache.insert(tx_hash, signer);
}
/// Get the recovered signer for a transaction hash from the cache.
/// Updates the metrics for hits and misses.
pub fn get(&self, tx_hash: &B256) -> Option<Address> {
match self.cache.get(tx_hash) {
Some(address) => {
self.hits.fetch_add(1, Ordering::Relaxed);
Some(address)
}
None => {
self.misses.fetch_add(1, Ordering::Relaxed);
None
}
}
}
}