Struct incr::AtomicMap [−][src]
Like Map
, AtomicMap
provides simple, fast sequence checking by key, but with
the thread-safe backing storage of AtomicIncr
.
Tradeoffs
AtomicMap
is not a concurrent hashmap. Importantly key insertion is not
synchronized. The intended use case is to initialize the map fully on program start,
inserting whatever keys will be used throughout its life, and cloning this master
instance to be used by any threads tracking sequences by those keys.
A fully synchronized map was not chosen for performance reasons. If keys are not fully known when threads are launched, the best options include:
- wrap a normal
Map
in anArc<Mutex<Map>>
orArc<RwLock<Map>>
, - utilize a third-party crate providing a concurrent hashmap implementation
(with
Incr
values).
For a given (already inserted) key, any clone()
d AtomicMap
will use/have a
value at that key that is synchronized across threads (the inner value is
an Arc<AtomicU64>
).
Examples
use incr::AtomicMap; let mut last: AtomicMap<&'static str> = Default::default(); assert_eq!(last.insert("a", 1), true); assert_eq!(last.is_new("missing_key", 1), false); // note difference from `Map` assert_eq!(last.insert("b", 1), true); assert_eq!(last.is_new("a", 1), false); assert_eq!(last.is_new("b", 3), true); assert_eq!(last.is_new_or_insert("c", 1), true); assert_eq!(last.is_new("c", 1), false); assert_eq!(last.get("b"), 3); assert_eq!(last.get("not a key"), 0);
Methods
impl<K> AtomicMap<K> where
K: Eq + Hash,
[src]
impl<K> AtomicMap<K> where
K: Eq + Hash,
pub fn is_new<Q: ?Sized>(&self, key: &Q, val: u64) -> bool where
K: Borrow<Q>,
Q: Hash + Eq,
[src]
pub fn is_new<Q: ?Sized>(&self, key: &Q, val: u64) -> bool where
K: Borrow<Q>,
Q: Hash + Eq,
Returns true
if key
exists and val
is greater than the largest
previously observed value (for key
). Returns false
if key
does
not exist in the inner map. See AtomicMap::check_or_insert
for a function
that behaves similarly to Map::is_new
.
Tradeoffs
This function has a different signature and works differently than
Map::is_new
.
Specifically, Map::is_new
:
- takes
&mut self
- consumes
key
- inserts
val
atkey
ifkey
was not already present in the map.
By contrast, AtomicIncr
:
- takes
&self
- borrows
&key
- does not insert
val
on a key miss, instead "silently" returningfalse
This design was chosen for several reasons, including:
- key insertions are not synchronized across threads. Instead, the map is expected to have been initialized on program start, and a key miss is most likely an error
- A
&self
signature provides more flexibility, and is possible, unlike withMap
, because theAtomicIncr::is_new
function takes&self
The AtomicMap::check_or_insert
function provides insert-on-key-miss
functionality if desired.
Possibly, it would be less confusing if this function returned Option<bool>
,
where a key miss would return None
. Feedback on this issue would be
appreciated.
Examples
use incr::AtomicMap; let mut last: AtomicMap<&'static str> = Default::default(); assert_eq!(last.is_new("a", 1), false); assert_eq!(last.contains_key("a"), false); assert_eq!(last.is_new_or_insert("a", 1), true); assert_eq!(last.get("a"), 1); assert_eq!(last.insert("b", 1), true); assert_eq!(last.is_new("b", 2), true); assert_eq!(last.is_new("b", 2), false);
pub fn is_new_or_insert(&mut self, key: K, val: u64) -> bool
[src]
pub fn is_new_or_insert(&mut self, key: K, val: u64) -> bool
Like is_new
, but inserts val
at key
if the inner map did not
previously contain key
.
This may be renamed to check_or_insert
in the future.
pub fn insert(&mut self, key: K, val: u64) -> bool
[src]
pub fn insert(&mut self, key: K, val: u64) -> bool
An alias for, and Works identically to, is_new_or_insert
. It's
not possible, using the public api, to decrease the value at a given
key, so calling this with a val
lower than the current value
would simply return false
and leave the higher value in the map
unchanged.
pub fn get<Q: ?Sized>(&self, key: &Q) -> u64 where
K: Borrow<Q>,
Q: Hash + Eq,
[src]
pub fn get<Q: ?Sized>(&self, key: &Q) -> u64 where
K: Borrow<Q>,
Q: Hash + Eq,
Returns the highest observed value at key
, or, if key
does not exist,
returns 0
.
pub fn contains_key<Q: ?Sized>(&self, key: &Q) -> bool where
K: Borrow<Q>,
Q: Hash + Eq,
[src]
pub fn contains_key<Q: ?Sized>(&self, key: &Q) -> bool where
K: Borrow<Q>,
Q: Hash + Eq,
pub fn len(&self) -> usize
[src]
pub fn len(&self) -> usize
pub fn is_empty(&self) -> bool
[src]
pub fn is_empty(&self) -> bool
Trait Implementations
impl<K: Default + Eq + Hash> Default for AtomicMap<K>
[src]
impl<K: Default + Eq + Hash> Default for AtomicMap<K>
impl<K: Clone + Eq + Hash> Clone for AtomicMap<K>
[src]
impl<K: Clone + Eq + Hash> Clone for AtomicMap<K>
fn clone(&self) -> AtomicMap<K>
[src]
fn clone(&self) -> AtomicMap<K>
Returns a copy of the value. Read more
fn clone_from(&mut self, source: &Self)
1.0.0[src]
fn clone_from(&mut self, source: &Self)
Performs copy-assignment from source
. Read more
impl<K: Debug + Eq + Hash> Debug for AtomicMap<K>
[src]
impl<K: Debug + Eq + Hash> Debug for AtomicMap<K>