crdt: Implement `GSet` type, based on `GMap`
This commit is contained in:
parent
0a93fa833e
commit
5c0505e221
|
|
@ -1,4 +1,4 @@
|
||||||
use std::collections::btree_map::{Entry, IntoIter};
|
use std::collections::btree_map::{Entry, IntoIter, IntoKeys};
|
||||||
use std::collections::BTreeMap;
|
use std::collections::BTreeMap;
|
||||||
use std::ops::Deref;
|
use std::ops::Deref;
|
||||||
|
|
||||||
|
|
@ -35,6 +35,12 @@ impl<K: Ord, V: Semilattice> GMap<K, V> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<K, V> GMap<K, V> {
|
||||||
|
pub fn into_keys(self) -> IntoKeys<K, V> {
|
||||||
|
self.inner.into_keys()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<K: Ord, V: Semilattice> FromIterator<(K, V)> for GMap<K, V> {
|
impl<K: Ord, V: Semilattice> FromIterator<(K, V)> for GMap<K, V> {
|
||||||
fn from_iter<I: IntoIterator<Item = (K, V)>>(iter: I) -> Self {
|
fn from_iter<I: IntoIterator<Item = (K, V)>>(iter: I) -> Self {
|
||||||
let mut map = GMap::default();
|
let mut map = GMap::default();
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,97 @@
|
||||||
|
use std::collections::btree_map::{IntoKeys, Keys};
|
||||||
|
use std::ops::Deref;
|
||||||
|
|
||||||
|
use crate::GMap;
|
||||||
|
use crate::Semilattice;
|
||||||
|
|
||||||
|
/// Grow-only set.
|
||||||
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
|
pub struct GSet<K> {
|
||||||
|
inner: GMap<K, ()>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<K: Ord> GSet<K> {
|
||||||
|
pub fn singleton(key: K) -> Self {
|
||||||
|
Self {
|
||||||
|
inner: GMap::from_iter([(key, ())]),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn insert(&mut self, key: K) {
|
||||||
|
self.inner.insert(key, ());
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn iter(&self) -> Keys<'_, K, ()> {
|
||||||
|
self.inner.keys()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<K: Ord> FromIterator<K> for GSet<K> {
|
||||||
|
fn from_iter<I: IntoIterator<Item = K>>(iter: I) -> Self {
|
||||||
|
let mut map = GSet::default();
|
||||||
|
for k in iter.into_iter() {
|
||||||
|
map.insert(k);
|
||||||
|
}
|
||||||
|
map
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<K: Ord> Extend<K> for GSet<K> {
|
||||||
|
fn extend<I: IntoIterator<Item = K>>(&mut self, iter: I) {
|
||||||
|
for k in iter.into_iter() {
|
||||||
|
self.insert(k);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<K> IntoIterator for GSet<K> {
|
||||||
|
type Item = K;
|
||||||
|
type IntoIter = IntoKeys<K, ()>;
|
||||||
|
|
||||||
|
fn into_iter(self) -> Self::IntoIter {
|
||||||
|
self.inner.into_keys()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<K> Default for GSet<K> {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self {
|
||||||
|
inner: GMap::default(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<K: Ord> Semilattice for GSet<K> {
|
||||||
|
fn merge(&mut self, other: Self) {
|
||||||
|
for k in other.into_iter() {
|
||||||
|
self.insert(k);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<K> Deref for GSet<K> {
|
||||||
|
type Target = GMap<K, ()>;
|
||||||
|
|
||||||
|
fn deref(&self) -> &Self::Target {
|
||||||
|
&self.inner
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use qcheck_macros::quickcheck;
|
||||||
|
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[quickcheck]
|
||||||
|
fn prop_semilattice(a: Vec<u8>, b: Vec<u8>, c: Vec<u8>, mix: Vec<u8>) {
|
||||||
|
let mut a = GSet::from_iter(a);
|
||||||
|
let mut b = GSet::from_iter(b);
|
||||||
|
let c = GSet::from_iter(c);
|
||||||
|
|
||||||
|
a.extend(mix.clone());
|
||||||
|
b.extend(mix);
|
||||||
|
|
||||||
|
crate::test::assert_laws(&a, &b, &c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -4,6 +4,7 @@
|
||||||
#![allow(clippy::type_complexity)]
|
#![allow(clippy::type_complexity)]
|
||||||
pub mod clock;
|
pub mod clock;
|
||||||
pub mod gmap;
|
pub mod gmap;
|
||||||
|
pub mod gset;
|
||||||
pub mod lwwmap;
|
pub mod lwwmap;
|
||||||
pub mod lwwreg;
|
pub mod lwwreg;
|
||||||
pub mod lwwset;
|
pub mod lwwset;
|
||||||
|
|
@ -17,6 +18,7 @@ pub mod test;
|
||||||
|
|
||||||
pub use clock::Lamport;
|
pub use clock::Lamport;
|
||||||
pub use gmap::GMap;
|
pub use gmap::GMap;
|
||||||
|
pub use gset::GSet;
|
||||||
pub use lwwmap::LWWMap;
|
pub use lwwmap::LWWMap;
|
||||||
pub use lwwreg::LWWReg;
|
pub use lwwreg::LWWReg;
|
||||||
pub use lwwset::LWWSet;
|
pub use lwwset::LWWSet;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue