|
|
|
|
@ -1,11 +1,15 @@
@@ -1,11 +1,15 @@
|
|
|
|
|
use argon2::{Config, Variant}; |
|
|
|
|
use cmp::Ordering; |
|
|
|
|
use lru_cache::LruCache; |
|
|
|
|
use rand::prelude::*; |
|
|
|
|
use ruma::serde::{try_from_json_map, CanonicalJsonError, CanonicalJsonObject}; |
|
|
|
|
use std::{ |
|
|
|
|
borrow::Borrow, |
|
|
|
|
cmp, |
|
|
|
|
collections::HashMap, |
|
|
|
|
convert::TryInto, |
|
|
|
|
str::FromStr, |
|
|
|
|
sync::{Arc, Weak}, |
|
|
|
|
time::{SystemTime, UNIX_EPOCH}, |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
@ -141,3 +145,64 @@ pub fn deserialize_from_str<
@@ -141,3 +145,64 @@ pub fn deserialize_from_str<
|
|
|
|
|
} |
|
|
|
|
deserializer.deserialize_str(Visitor(std::marker::PhantomData)) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
pub struct ArcingLruCache<K: Eq + std::hash::Hash, V> { |
|
|
|
|
lru: LruCache<Arc<K>, Arc<V>>, |
|
|
|
|
map: HashMap<Arc<K>, Weak<V>>, |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
impl<K: Eq + std::hash::Hash, V> ArcingLruCache<K, V> { |
|
|
|
|
pub fn new(capacity: usize) -> Self { |
|
|
|
|
ArcingLruCache { |
|
|
|
|
lru: LruCache::new(capacity), |
|
|
|
|
map: HashMap::new(), |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
pub fn prune_dead(&mut self) { |
|
|
|
|
self.map.retain(|_, v| v.strong_count() > 0) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
pub fn insert(&mut self, k: K, v: Arc<V>) { |
|
|
|
|
let key = Arc::new(k); |
|
|
|
|
let v_weak = Arc::downgrade(&v); |
|
|
|
|
|
|
|
|
|
self.lru.insert(key.clone(), v); |
|
|
|
|
|
|
|
|
|
self.map.insert(key, v_weak); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
pub fn get<Q: ?Sized>(&mut self, k: &Q) -> Option<Arc<V>> |
|
|
|
|
where |
|
|
|
|
Arc<K>: Borrow<Q>, |
|
|
|
|
Q: std::hash::Hash + Eq, |
|
|
|
|
{ |
|
|
|
|
if let Some(v) = self.lru.get_mut(&k) { |
|
|
|
|
return Some(v.clone()); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if let Some((map_k, weak)) = self.map.get_key_value(&k) { |
|
|
|
|
if let Some(strong) = weak.upgrade() { |
|
|
|
|
// Revived
|
|
|
|
|
|
|
|
|
|
self.lru.insert(map_k.clone(), strong.clone()); |
|
|
|
|
|
|
|
|
|
Some(strong) |
|
|
|
|
} else { |
|
|
|
|
// Dead
|
|
|
|
|
|
|
|
|
|
// possible race condition is prevented with &mut self
|
|
|
|
|
// self.map.remove(&k);
|
|
|
|
|
|
|
|
|
|
// prune_dead is done here as it's likely that the map has more non-functional weaks if one is encountered
|
|
|
|
|
// unless all inserts to the map has thus far been unique, this should soon-or-later trigger,
|
|
|
|
|
// and fairly "rarely" yet consistently
|
|
|
|
|
self.prune_dead(); |
|
|
|
|
|
|
|
|
|
None |
|
|
|
|
} |
|
|
|
|
} else { |
|
|
|
|
None |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|