Struct evmap::WriteHandle
source · pub struct WriteHandle<K, V, M = (), S = RandomState>where
K: Eq + Hash + Clone,
S: BuildHasher + Clone,
V: Eq + ShallowCopy,
M: 'static + Clone,{ /* private fields */ }
Expand description
A handle that may be used to modify the eventually consistent map.
Note that any changes made to the map will not be made visible to readers until refresh()
is
called.
Examples
let x = ('x', 42);
let (r, mut w) = evmap::new();
// the map is uninitialized, so all lookups should return None
assert_eq!(r.get_and(&x.0, |rs| rs.len()), None);
w.refresh();
// after the first refresh, it is empty, but ready
assert_eq!(r.get_and(&x.0, |rs| rs.len()), None);
w.insert(x.0, x);
// it is empty even after an add (we haven't refresh yet)
assert_eq!(r.get_and(&x.0, |rs| rs.len()), None);
w.refresh();
// but after the swap, the record is there!
assert_eq!(r.get_and(&x.0, |rs| rs.len()), Some(1));
assert_eq!(r.get_and(&x.0, |rs| rs.iter().any(|v| v.0 == x.0 && v.1 == x.1)), Some(true));
Implementations
sourceimpl<K, V, M, S> WriteHandle<K, V, M, S>where
K: Eq + Hash + Clone,
S: BuildHasher + Clone,
V: Eq + ShallowCopy,
M: 'static + Clone,
impl<K, V, M, S> WriteHandle<K, V, M, S>where
K: Eq + Hash + Clone,
S: BuildHasher + Clone,
V: Eq + ShallowCopy,
M: 'static + Clone,
sourcepub fn refresh(&mut self)
pub fn refresh(&mut self)
Refresh the handle used by readers so that pending writes are made visible.
This method needs to wait for all readers to move to the new handle so that it can replay the operational log onto the stale map copy the readers used to use. This can take some time, especially if readers are executing slow operations, or if there are many of them.
sourcepub fn destroy(self)
pub fn destroy(self)
Drop this map without preserving one side for reads.
Normally, the maps are not deallocated until all readers have also gone away.
When this method is called, the map is immediately (but safely) taken away from all
readers, causing all future lookups to return None
.
use std::thread;
let (r, mut w) = evmap::new();
// start some readers
let readers: Vec<_> = (0..4).map(|_| {
let r = r.clone();
thread::spawn(move || {
loop {
let l = r.len();
if l == 0 {
if r.is_destroyed() {
// the writer destroyed the map!
break;
}
thread::yield_now();
} else {
// the reader will either see all the reviews,
// or none of them, since refresh() is atomic.
assert_eq!(l, 4);
}
}
})
}).collect();
// do some writes
w.insert(0, String::from("foo"));
w.insert(1, String::from("bar"));
w.insert(2, String::from("baz"));
w.insert(3, String::from("qux"));
// expose the writes
w.refresh();
assert_eq!(r.len(), 4);
// refresh a few times to exercise the readers
for _ in 0..10 {
w.refresh();
}
// now blow the map away
w.destroy();
// all the threads should eventually see that the map was destroyed
for r in readers.into_iter() {
assert!(r.join().is_ok());
}
sourcepub fn pending(&self) -> &[Operation<K, V>]
pub fn pending(&self) -> &[Operation<K, V>]
Gives the sequence of operations that have not yet been applied.
Note that until the first call to refresh
, the sequence of operations is always empty.
let x = ('x', 42);
let (r, mut w) = evmap::new();
// before the first refresh, no oplog is kept
w.refresh();
assert_eq!(w.pending(), &[]);
w.insert(x.0, x);
assert_eq!(w.pending(), &[Operation::Add(x.0, x)]);
w.refresh();
w.remove(x.0, x);
assert_eq!(w.pending(), &[Operation::Remove(x.0, x)]);
w.refresh();
assert_eq!(w.pending(), &[]);
sourcepub fn flush(&mut self)
pub fn flush(&mut self)
Refresh as necessary to ensure that all operations are visible to readers.
WriteHandle::refresh
will always wait for old readers to depart and swap the maps.
This method will only do so if there are pending operations.
sourcepub fn set_meta(&mut self, meta: M) -> M
pub fn set_meta(&mut self, meta: M) -> M
Set the metadata.
Will only be visible to readers after the next call to refresh()
.
sourcepub fn insert(&mut self, k: K, v: V)
pub fn insert(&mut self, k: K, v: V)
Add the given value to the value-set of the given key.
The updated value-set will only be visible to readers after the next call to refresh()
.
sourcepub fn update(&mut self, k: K, v: V)
pub fn update(&mut self, k: K, v: V)
Replace the value-set of the given key with the given value.
The new value will only be visible to readers after the next call to refresh()
.
sourcepub fn clear(&mut self, k: K)
pub fn clear(&mut self, k: K)
Clear the value-set of the given key, without removing it.
This will allocate an empty value-set for the key if it does not already exist.
The new value will only be visible to readers after the next call to refresh()
.
Methods from Deref<Target = ReadHandle<K, V, M, S>>
sourcepub fn get_and<Q: ?Sized, F, T>(&self, key: &Q, then: F) -> Option<T>where
F: FnOnce(&[V]) -> T,
K: Borrow<Q>,
Q: Hash + Eq,
pub fn get_and<Q: ?Sized, F, T>(&self, key: &Q, then: F) -> Option<T>where
F: FnOnce(&[V]) -> T,
K: Borrow<Q>,
Q: Hash + Eq,
Applies a function to the values corresponding to the key, and returns the result.
The key may be any borrowed form of the map’s key type, but Hash
and Eq
on the borrowed
form must match those for the key type.
Note that not all writes will be included with this read – only those that have been
refreshed by the writer. If no refresh has happened, this function returns None
.
If no values exist for the given key, no refresh has happened, or the map has been
destroyed, then
will not be called, and None
will be returned.
sourcepub fn meta_get_and<Q: ?Sized, F, T>(
&self,
key: &Q,
then: F
) -> Option<(Option<T>, M)>where
F: FnOnce(&[V]) -> T,
K: Borrow<Q>,
Q: Hash + Eq,
pub fn meta_get_and<Q: ?Sized, F, T>(
&self,
key: &Q,
then: F
) -> Option<(Option<T>, M)>where
F: FnOnce(&[V]) -> T,
K: Borrow<Q>,
Q: Hash + Eq,
Applies a function to the values corresponding to the key, and returns the result alongside the meta information.
The key may be any borrowed form of the map’s key type, but Hash
and Eq
on the borrowed
form must match those for the key type.
Note that not all writes will be included with this read – only those that have been
refreshed by the writer. If no refresh has happened, or if the map has been closed by the
writer, this function returns None
.
If no values exist for the given key, then
will not be called, and Some(None, _)
is
returned.
sourcepub fn is_destroyed(&self) -> bool
pub fn is_destroyed(&self) -> bool
If the writer has destroyed this map, this method will return true.
See WriteHandle::destroy
.
sourcepub fn contains_key<Q: ?Sized>(&self, key: &Q) -> boolwhere
K: Borrow<Q>,
Q: Hash + Eq,
pub fn contains_key<Q: ?Sized>(&self, key: &Q) -> boolwhere
K: Borrow<Q>,
Q: Hash + Eq,
Returns true if the map contains any values for the specified key.
The key may be any borrowed form of the map’s key type, but Hash
and Eq
on the borrowed
form must match those for the key type.
Trait Implementations
sourceimpl<K, V, M, S> Deref for WriteHandle<K, V, M, S>where
K: Eq + Hash + Clone,
S: BuildHasher + Clone,
V: Eq + ShallowCopy,
M: 'static + Clone,
impl<K, V, M, S> Deref for WriteHandle<K, V, M, S>where
K: Eq + Hash + Clone,
S: BuildHasher + Clone,
V: Eq + ShallowCopy,
M: 'static + Clone,
type Target = ReadHandle<K, V, M, S>
type Target = ReadHandle<K, V, M, S>
sourceimpl<K, V, M, S> Drop for WriteHandle<K, V, M, S>where
K: Eq + Hash + Clone,
S: BuildHasher + Clone,
V: Eq + ShallowCopy,
M: 'static + Clone,
impl<K, V, M, S> Drop for WriteHandle<K, V, M, S>where
K: Eq + Hash + Clone,
S: BuildHasher + Clone,
V: Eq + ShallowCopy,
M: 'static + Clone,
sourceimpl<K, V, M, S> Extend<(K, V)> for WriteHandle<K, V, M, S>where
K: Eq + Hash + Clone,
S: BuildHasher + Clone,
V: Eq + ShallowCopy,
M: 'static + Clone,
impl<K, V, M, S> Extend<(K, V)> for WriteHandle<K, V, M, S>where
K: Eq + Hash + Clone,
S: BuildHasher + Clone,
V: Eq + ShallowCopy,
M: 'static + Clone,
sourcefn extend<I: IntoIterator<Item = (K, V)>>(&mut self, iter: I)
fn extend<I: IntoIterator<Item = (K, V)>>(&mut self, iter: I)
sourcefn extend_one(&mut self, item: A)
fn extend_one(&mut self, item: A)
extend_one
)sourcefn extend_reserve(&mut self, additional: usize)
fn extend_reserve(&mut self, additional: usize)
extend_one
)