1use im::{OrdMap, OrdSet};
2use ossa_typeable::Typeable;
3use serde::de::{MapAccess, Visitor};
4use serde::ser::{SerializeStruct, Serializer};
5use serde::{Deserialize, Serialize};
6use std::fmt::{self, Debug};
7use std::marker::PhantomData;
8
9use crate::time::CausalState;
10use crate::CRDT;
11
12#[derive(Clone, Typeable)]
15pub struct TwoPMap<K, V> {
16 map: OrdMap<K, V>,
18 tombstones: OrdSet<K>,
19}
20
21impl<K: Serialize + Ord + Clone, V: Serialize + Clone> Serialize for TwoPMap<K, V> {
23 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
24 where
25 S: Serializer,
26 {
27 let mut s = serializer.serialize_struct("TwoPMap", 2)?;
28 s.serialize_field("map", &self.map)?;
29 s.serialize_field("tombstones", &self.tombstones)?;
30 s.end()
31 }
32}
33
34impl<'d, K: Clone + Ord + Deserialize<'d>, V: Clone + Deserialize<'d>> Deserialize<'d>
35 for TwoPMap<K, V>
36{
37 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
38 where
39 D: serde::Deserializer<'d>,
40 {
41 struct SVisitor<K, V>(PhantomData<(K, V)>);
42
43 #[derive(Deserialize)]
44 #[serde(field_identifier, rename_all = "lowercase")]
45 enum Field {
46 Map,
47 Tombstones,
48 }
49
50 impl<'d, K: Ord + Clone + Deserialize<'d>, V: Clone + Deserialize<'d>> Visitor<'d>
51 for SVisitor<K, V>
52 {
53 type Value = TwoPMap<K, V>;
54
55 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
56 formatter.write_str("struct TwoPMap")
57 }
58
59 fn visit_map<M>(self, mut m: M) -> Result<TwoPMap<K, V>, M::Error>
60 where
61 M: MapAccess<'d>,
62 {
63 let mut map = None;
64 let mut tombstones = None;
65 while let Some(key) = m.next_key()? {
66 match key {
67 Field::Map => {
68 if map.is_some() {
69 return Err(serde::de::Error::duplicate_field("map"));
70 }
71 map = Some(m.next_value()?);
72 }
73 Field::Tombstones => {
74 if tombstones.is_some() {
75 return Err(serde::de::Error::duplicate_field("tombstones"));
76 }
77 tombstones = Some(m.next_value()?);
78 }
79 }
80 }
81
82 let map = map.ok_or_else(|| serde::de::Error::missing_field("map"))?;
83 let tombstones =
84 tombstones.ok_or_else(|| serde::de::Error::missing_field("tombstones"))?;
85
86 Ok(TwoPMap { map, tombstones })
87 }
88 }
89
90 deserializer.deserialize_struct("TwoPMap", &["map", "tombstones"], SVisitor(PhantomData))
91 }
92}
93
94impl<K: Ord + Debug, V: Debug> Debug for TwoPMap<K, V> {
95 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
96 self.map.fmt(f)
97 }
98}
99
100#[derive(Debug, Serialize, Deserialize)]
102pub enum TwoPMapOp<K, V, Op> {
103 Insert { key: K, value: V },
104 Apply { key: K, operation: Op },
105 Delete { key: K },
106}
107
108impl<K, V, Op> TwoPMapOp<K, V, Op> {
109 fn key(&self) -> &K {
110 match self {
111 TwoPMapOp::Insert { key, .. } => key,
112 TwoPMapOp::Apply { key, .. } => key,
113 TwoPMapOp::Delete { key } => key,
114 }
115 }
116}
117
118impl<K: Ord + Clone, V: CRDT<Time = K> + Clone> CRDT for TwoPMap<K, V> {
119 type Op = TwoPMapOp<K, V, V::Op>;
120 type Time = V::Time; fn apply<CS: CausalState<Time = Self::Time>>(self, st: &CS, op: Self::Op) -> Self {
123 let is_deleted = {
125 let key = op.key();
126 self.tombstones.contains(key)
127 };
128 if is_deleted {
129 self
130 } else {
131 match op {
132 TwoPMapOp::Insert { key, value } => {
133 let TwoPMap { map, tombstones } = self;
134 let map = map.update_with(key, value, |_, _| {
135 unreachable!("Invariant violated. Key already exists in TwoPMap.");
136 });
137
138 TwoPMap { map, tombstones }
139 }
140 TwoPMapOp::Apply { key, operation } => {
141 let TwoPMap { map, tombstones } = self;
142 let map = map.alter(|v| {
143 if let Some(v) = v {
144 Some(v.apply(st, operation))
145 } else {
146 unreachable!("Invariant violated. Key must already exist when applyting an update to a TwoPMap.")
147 }
148 }, key);
149
150 TwoPMap { map, tombstones }
151 }
152 TwoPMapOp::Delete { key } => {
153 let TwoPMap { map, tombstones } = self;
154 let map = map.without(&key);
155 let tombstones = tombstones.update(key);
156
157 TwoPMap { map, tombstones }
158 }
159 }
160 }
161 }
162}
163
164impl<K: Ord, V: CRDT> TwoPMap<K, V> {
165 pub fn new() -> TwoPMap<K, V> {
166 TwoPMap {
167 map: OrdMap::new(),
168 tombstones: OrdSet::new(),
169 }
170 }
171
172 pub fn get(&self, key: &K) -> Option<&V> {
173 self.map.get(key)
174 }
175
176 pub fn iter(&self) -> im::ordmap::Iter<'_, K, V> {
177 self.map.iter()
178 }
179
180 pub fn insert(key: K, value: V) -> TwoPMapOp<K, V, V::Op> {
181 TwoPMapOp::Insert { key, value }
182 }
183}
184
185