pub struct MapCache<K, V> { /* private fields */ }Expand description
A map’s entries, held in the order the store lists them.
Keyed by the key itself, ordered by the name it borrows. A store orders its keys by their levels, and an entry is one level, so the name’s own order is the store’s - the two cannot come apart, because the cache is not holding a second thing to compare.
A read takes a version and holds nothing, so a walk neither blocks a writer nor waits for one, whatever thread either is on. A write publishes a new version that shares every node it did not touch, so it stays O(log n) rather than copying the map.
It is a trade, not a free win. Writes and memory both cost more than a
RwLock<BTreeMap> would, and
crates/main/amethystate/benches/map_snapshot_bench.rs measures against
one.
What it buys is that writing during a walk cannot deadlock. It does not
make it correct: the walk goes on yielding its own version, so a write made
inside the loop is invisible to the rest of it. for k in keys { remove(k) }
wants exactly that; a loop that writes and reads the same key back gets a
stale answer and nothing says so. Loud failure was traded for quiet
staleness.
The shape is not selectable per map, though it could be - the backing type is private either way. Nothing would pick the locking one: it wins only where a map is written in bulk and never walked while it is written, and a map nobody observes is the store’s job.
Implementations§
Source§impl<K: AsRef<str> + Clone, V: Clone> MapCache<K, V>
impl<K: AsRef<str> + Clone, V: Clone> MapCache<K, V>
pub fn new() -> Self
pub fn get(&self, name: &str) -> Option<V>
pub fn contains_key(&self, name: &str) -> bool
Sourcepub fn owned_key(&self, name: &str) -> Option<K>
pub fn owned_key(&self, name: &str) -> Option<K>
The key as the map holds it, for a caller that looked one up by the name it borrows and needs the owned form back.
pub fn len(&self) -> usize
pub fn is_empty(&self) -> bool
pub fn clear(&self)
Sourcepub fn view(&self) -> Entries<K, V>
pub fn view(&self) -> Entries<K, V>
The entries themselves, in order, without copying any of them.
The version is taken when the view is, so writes that land afterwards are not in it however long it is held.
Source§impl<K: AsRef<str> + Clone, V: Clone> MapCache<K, V>
impl<K: AsRef<str> + Clone, V: Clone> MapCache<K, V>
pub fn insert(&self, key: K, value: V) -> Option<V>
pub fn remove(&self, name: &str) -> Option<(K, V)>
Sourcepub fn insert_settled(&self, key: K, value: V, at: u64) -> bool
pub fn insert_settled(&self, key: K, value: V, at: u64) -> bool
Puts value at key unless a change to it the store settled later
has been taken already. Answers whether it was put.
Sourcepub fn remove_settled(&self, name: &str, at: u64) -> bool
pub fn remove_settled(&self, name: &str, at: u64) -> bool
Takes name away unless a change to it the store settled later has
been taken already. Answers whether it was.
Sourcepub fn clear_settled(&self, at: u64) -> bool
pub fn clear_settled(&self, at: u64) -> bool
Empties the map of everything the store settled up to at, keeping
the entries it settled after. Answers whether it did, which it does not
for a clear settled before one already taken.