make concurrent map able to give default values which depend on key
this allows to uphold more complex invariants
This commit is contained in:
@@ -11,6 +11,12 @@
|
|||||||
//! sources, and insertions occur only a few times at the beginning of the process.
|
//! sources, and insertions occur only a few times at the beginning of the process.
|
||||||
//! Then almost all accesses are to existing elements, and from that point on,
|
//! Then almost all accesses are to existing elements, and from that point on,
|
||||||
//! only read locks are taken when using this API.
|
//! only read locks are taken when using this API.
|
||||||
|
//!
|
||||||
|
//! The API also allows to call "retain" if the map gets too big and it needs
|
||||||
|
//! to be pruned in some manner.
|
||||||
|
//!
|
||||||
|
//! This is used instead of dash_map and once_map to avoid unnecessary complexity
|
||||||
|
//! and dependencies, and give exactly the API needed in our application.
|
||||||
|
|
||||||
use std::{borrow::Borrow, collections::HashMap, hash::Hash, sync::RwLock};
|
use std::{borrow::Borrow, collections::HashMap, hash::Hash, sync::RwLock};
|
||||||
|
|
||||||
@@ -98,7 +104,7 @@ impl <K, V> Default for ConcurrentMap<K, V>
|
|||||||
/// to pass the creation function on every access.
|
/// to pass the creation function on every access.
|
||||||
pub struct LazyMap<K, V> {
|
pub struct LazyMap<K, V> {
|
||||||
inner: ConcurrentMap<K, V>,
|
inner: ConcurrentMap<K, V>,
|
||||||
factory: Box<dyn Fn() -> V + Send + Sync>,
|
factory: Box<dyn Fn(&K) -> V + Send + Sync>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<K, V> LazyMap<K, V>
|
impl<K, V> LazyMap<K, V>
|
||||||
@@ -106,7 +112,7 @@ where
|
|||||||
K: Eq + Hash + Clone,
|
K: Eq + Hash + Clone,
|
||||||
{
|
{
|
||||||
/// Create a new lazy map with the given factory for creating initial values.
|
/// Create a new lazy map with the given factory for creating initial values.
|
||||||
pub fn new(factory: impl Fn() -> V + Send + Sync + 'static) -> Self {
|
pub fn new(factory: impl Fn(&K) -> V + Send + Sync + 'static) -> Self {
|
||||||
Self {
|
Self {
|
||||||
inner: ConcurrentMap::new(),
|
inner: ConcurrentMap::new(),
|
||||||
factory: Box::new(factory),
|
factory: Box::new(factory),
|
||||||
@@ -119,7 +125,8 @@ where
|
|||||||
Q: Borrow<K>,
|
Q: Borrow<K>,
|
||||||
A: FnOnce(&V) -> R,
|
A: FnOnce(&V) -> R,
|
||||||
{
|
{
|
||||||
self.inner.get_or_insert_with(key, &self.factory, access)
|
let key = key.borrow();
|
||||||
|
self.inner.get_or_insert_with(key, || (self.factory)(key), access)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Access all entries in the map with a read lock.
|
/// Access all entries in the map with a read lock.
|
||||||
|
|||||||
@@ -115,7 +115,7 @@ impl LogHandler {
|
|||||||
Self {
|
Self {
|
||||||
config,
|
config,
|
||||||
signal_alert_mq_tx,
|
signal_alert_mq_tx,
|
||||||
log_buffers: LazyMap::new(move || LogBuffer::new(buffer_size)),
|
log_buffers: LazyMap::new(move |_key| LogBuffer::new(buffer_size)),
|
||||||
routes,
|
routes,
|
||||||
overall_limits,
|
overall_limits,
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ impl LimiterSet {
|
|||||||
global_limiters: Vec<(LogFilter, Limiter)>,
|
global_limiters: Vec<(LogFilter, Limiter)>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
Self {
|
Self {
|
||||||
limiters: LazyMap::new(make_limiters),
|
limiters: LazyMap::new(move |_key| make_limiters()),
|
||||||
global_limiters,
|
global_limiters,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -178,7 +178,7 @@ pub struct SourceLocationRateLimiter {
|
|||||||
impl SourceLocationRateLimiter {
|
impl SourceLocationRateLimiter {
|
||||||
pub fn new(threshold: RateThreshold, max_entries: usize) -> Self {
|
pub fn new(threshold: RateThreshold, max_entries: usize) -> Self {
|
||||||
Self {
|
Self {
|
||||||
limiters: LazyMap::new(move || MultiRateLimiter::from(threshold)),
|
limiters: LazyMap::new(move |_key| MultiRateLimiter::from(threshold)),
|
||||||
threshold,
|
threshold,
|
||||||
max_entries,
|
max_entries,
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user