Struct noosphere_core::data::map::Map
source · Expand description
Map CRDT - Supports Composition of CRDT’s with reset-remove semantics.
Reset-remove means that if one replica removes an entry while another actor concurrently edits that entry, once we sync these two maps, we will see that the entry is still in the map but all edits seen by the removing actor will be gone.
See examples/reset_remove.rs for an example of reset-remove semantics in action.
Implementations
sourceimpl<K, V, A> Map<K, V, A>where
K: Ord,
V: Val<A>,
A: Ord + Hash + Clone,
impl<K, V, A> Map<K, V, A>where
K: Ord,
V: Val<A>,
A: Ord + Hash + Clone,
sourcepub fn is_empty(&self) -> ReadCtx<bool, A>
pub fn is_empty(&self) -> ReadCtx<bool, A>
Returns true if the map has no entries, false otherwise
sourcepub fn update<F>(&self, key: impl Into<K>, ctx: AddCtx<A>, f: F) -> Op<K, V, A>where
F: FnOnce(&V, AddCtx<A>) -> <V as CmRDT>::Op,
pub fn update<F>(&self, key: impl Into<K>, ctx: AddCtx<A>, f: F) -> Op<K, V, A>where
F: FnOnce(&V, AddCtx<A>) -> <V as CmRDT>::Op,
Update a value under some key.
If the key is not present in the map, the updater will be given the
result of V::default(). The default value is used to ensure
eventual consistency since our Map’s values are CRDTs themselves.
The impl Into<K> bound provides a nice way of providing an input key that
can easily convert to the Map’s key. For example, we can call this function
with "hello": &str and it can be converted to String.
sourcepub fn rm(&self, key: impl Into<K>, ctx: RmCtx<A>) -> Op<K, V, A>
pub fn rm(&self, key: impl Into<K>, ctx: RmCtx<A>) -> Op<K, V, A>
Remove an entry from the Map
The impl Into<K> bound provides a nice way of providing an input key that
can easily convert to the Map’s key. For example, we can call this function
with "hello": &str and it can be converted to String.
sourcepub fn keys(&self) -> impl Iterator<Item = ReadCtx<&K, A>>
pub fn keys(&self) -> impl Iterator<Item = ReadCtx<&K, A>>
Gets an iterator over the keys of the Map.
Examples
use crdts::Map;
use crdts::MVReg;
use crdts::CmRDT;
type Actor = &'static str;
type Key = &'static str;
let actor = "actor";
let mut map: Map<i32, MVReg<Key, Actor>, Actor> = Map::new();
let add_ctx = map.read_ctx().derive_add_ctx(actor);
map.apply(map.update(100, add_ctx, |v, a| v.write("foo", a)));
let add_ctx = map.read_ctx().derive_add_ctx(actor);
map.apply(map.update(50, add_ctx, |v, a| v.write("bar", a)));
let add_ctx = map.read_ctx().derive_add_ctx(actor);
map.apply(map.update(200, add_ctx, |v, a| v.write("baz", a)));
let mut keys: Vec<_> = map.keys().map(|key_ctx| *key_ctx.val).collect();
keys.sort();
assert_eq!(keys, &[50, 100, 200]);sourcepub fn values(&self) -> impl Iterator<Item = ReadCtx<&V, A>>
pub fn values(&self) -> impl Iterator<Item = ReadCtx<&V, A>>
Gets an iterator over the values of the Map.
Examples
use crdts::Map;
use crdts::MVReg;
use crdts::CmRDT;
type Actor = &'static str;
type Key = &'static str;
let actor = "actor";
let mut map: Map<i32, MVReg<Key, Actor>, Actor> = Map::new();
let add_ctx = map.read_ctx().derive_add_ctx(actor);
map.apply(map.update(100, add_ctx, |v, a| v.write("foo", a)));
let add_ctx = map.read_ctx().derive_add_ctx(actor);
map.apply(map.update(50, add_ctx, |v, a| v.write("bar", a)));
let add_ctx = map.read_ctx().derive_add_ctx(actor);
map.apply(map.update(200, add_ctx, |v, a| v.write("baz", a)));
let mut values: Vec<_> = map
.values()
.map(|val_ctx| val_ctx.val.read().val[0])
.collect();
values.sort();
assert_eq!(values, &["bar", "baz", "foo"]);sourcepub fn iter(&self) -> impl Iterator<Item = ReadCtx<(&K, &V), A>>
pub fn iter(&self) -> impl Iterator<Item = ReadCtx<(&K, &V), A>>
Gets an iterator over the entries of the Map.
Examples
use crdts::Map;
use crdts::MVReg;
use crdts::CmRDT;
type Actor = &'static str;
type Key = &'static str;
let actor = "actor";
let mut map: Map<i32, MVReg<Key, Actor>, Actor> = Map::new();
let add_ctx = map.read_ctx().derive_add_ctx(actor);
map.apply(map.update(100, add_ctx, |v, a| v.write("foo", a)));
let add_ctx = map.read_ctx().derive_add_ctx(actor);
map.apply(map.update(50, add_ctx, |v, a| v.write("bar", a)));
let add_ctx = map.read_ctx().derive_add_ctx(actor);
map.apply(map.update(200, add_ctx, |v, a| v.write("baz", a)));
let mut items: Vec<_> = map
.iter()
.map(|item_ctx| (*item_ctx.val.0, item_ctx.val.1.read().val[0]))
.collect();
items.sort();
assert_eq!(items, &[(50, "bar"), (100, "foo"), (200, "baz")]);Trait Implementations
sourceimpl<K, V, A> Clone for Map<K, V, A>where
K: Clone + Ord,
V: Clone + Val<A>,
A: Clone + Ord + Hash,
impl<K, V, A> Clone for Map<K, V, A>where
K: Clone + Ord,
V: Clone + Val<A>,
A: Clone + Ord + Hash,
sourceimpl<K, V, A> CmRDT for Map<K, V, A>where
K: Ord,
V: Val<A> + Debug,
A: Ord + Hash + Clone + Debug,
impl<K, V, A> CmRDT for Map<K, V, A>where
K: Ord,
V: Val<A> + Debug,
A: Ord + Hash + Clone + Debug,
type Op = Op<K, V, A>
type Op = Op<K, V, A>
type Validation = CmRDTValidation<V, A>
type Validation = CmRDTValidation<V, A>
validate_op.sourcefn validate_op(
&self,
op: &<Map<K, V, A> as CmRDT>::Op
) -> Result<(), <Map<K, V, A> as CmRDT>::Validation>
fn validate_op(
&self,
op: &<Map<K, V, A> as CmRDT>::Op
) -> Result<(), <Map<K, V, A> as CmRDT>::Validation>
sourceimpl<K, V, A> CvRDT for Map<K, V, A>where
K: Ord + Clone + Debug,
V: Val<A> + CvRDT + Debug,
A: Ord + Hash + Clone + Debug,
impl<K, V, A> CvRDT for Map<K, V, A>where
K: Ord + Clone + Debug,
V: Val<A> + CvRDT + Debug,
A: Ord + Hash + Clone + Debug,
type Validation = CvRDTValidation<K, V, A>
type Validation = CvRDTValidation<K, V, A>
validate_merge.