y_octo/doc/codec/
delete_set.rs1use std::{
2 collections::{hash_map::Entry, HashMap},
3 ops::{Deref, DerefMut, Range},
4};
5
6use super::*;
7use crate::doc::OrderRange;
8
9impl<R: CrdtReader> CrdtRead<R> for Range<u64> {
10 fn read(decoder: &mut R) -> JwstCodecResult<Self> {
11 let clock = decoder.read_var_u64()?;
12 let len = decoder.read_var_u64()?;
13 Ok(clock..clock + len)
14 }
15}
16
17impl<W: CrdtWriter> CrdtWrite<W> for Range<u64> {
18 fn write(&self, encoder: &mut W) -> JwstCodecResult {
19 encoder.write_var_u64(self.start)?;
20 encoder.write_var_u64(self.end - self.start)?;
21 Ok(())
22 }
23}
24
25impl<R: CrdtReader> CrdtRead<R> for OrderRange {
26 fn read(decoder: &mut R) -> JwstCodecResult<Self> {
27 let num_of_deletes = decoder.read_var_u64()? as usize;
28 if num_of_deletes == 1 {
29 Ok(OrderRange::Range(Range::<u64>::read(decoder)?))
30 } else {
31 let mut deletes = Vec::with_capacity(num_of_deletes);
32
33 for _ in 0..num_of_deletes {
34 deletes.push(Range::<u64>::read(decoder)?);
35 }
36
37 Ok(OrderRange::Fragment(deletes))
38 }
39 }
40}
41
42impl<W: CrdtWriter> CrdtWrite<W> for OrderRange {
43 fn write(&self, encoder: &mut W) -> JwstCodecResult {
44 match self {
45 OrderRange::Range(range) => {
46 encoder.write_var_u64(1)?;
47 range.write(encoder)?;
48 }
49 OrderRange::Fragment(ranges) => {
50 encoder.write_var_u64(ranges.len() as u64)?;
51 for range in ranges {
52 range.write(encoder)?;
53 }
54 }
55 }
56
57 Ok(())
58 }
59}
60
61#[derive(Debug, Default, Clone, PartialEq)]
62pub struct DeleteSet(pub HashMap<Client, OrderRange>);
63
64impl Deref for DeleteSet {
65 type Target = HashMap<Client, OrderRange>;
66
67 fn deref(&self) -> &Self::Target {
68 &self.0
69 }
70}
71
72impl<const N: usize> From<[(Client, Vec<Range<u64>>); N]> for DeleteSet {
73 fn from(value: [(Client, Vec<Range<u64>>); N]) -> Self {
74 let mut map = HashMap::with_capacity(N);
75 for (client, ranges) in value {
76 map.insert(client, ranges.into());
77 }
78 Self(map)
79 }
80}
81
82impl DerefMut for DeleteSet {
83 fn deref_mut(&mut self) -> &mut Self::Target {
84 &mut self.0
85 }
86}
87
88impl DeleteSet {
89 pub fn add(&mut self, client: Client, from: Clock, len: Clock) {
90 self.add_range(client, from..from + len);
91 }
92
93 pub fn add_range(&mut self, client: Client, range: Range<u64>) {
94 match self.0.entry(client) {
95 Entry::Occupied(e) => {
96 let r = e.into_mut();
97 if r.is_empty() {
98 *r = range.into();
99 } else {
100 r.push(range);
101 }
102 }
103 Entry::Vacant(e) => {
104 e.insert(range.into());
105 }
106 }
107 }
108
109 #[allow(dead_code)]
110 pub fn batch_push(&mut self, client: Client, ranges: Vec<Range<u64>>) {
111 match self.0.entry(client) {
112 Entry::Occupied(e) => {
113 e.into_mut().extends(ranges);
114 }
115 Entry::Vacant(e) => {
116 e.insert(ranges.into());
117 }
118 }
119 }
120
121 pub fn merge(&mut self, other: &Self) {
122 for (client, range) in &other.0 {
123 match self.0.entry(*client) {
124 Entry::Occupied(e) => {
125 e.into_mut().merge(range.clone());
126 }
127 Entry::Vacant(e) => {
128 e.insert(range.clone());
129 }
130 }
131 }
132 }
133}
134
135impl<R: CrdtReader> CrdtRead<R> for DeleteSet {
136 fn read(decoder: &mut R) -> JwstCodecResult<Self> {
137 let num_of_clients = decoder.read_var_u64()? as usize;
138 let mut map = HashMap::with_capacity(num_of_clients);
139
140 for _ in 0..num_of_clients {
141 let client = decoder.read_var_u64()?;
142 let deletes = OrderRange::read(decoder)?;
143 map.insert(client, deletes);
144 }
145
146 Ok(DeleteSet(map))
147 }
148}
149
150impl<W: CrdtWriter> CrdtWrite<W> for DeleteSet {
151 fn write(&self, encoder: &mut W) -> JwstCodecResult {
152 encoder.write_var_u64(self.len() as u64)?;
153 let mut clients = self.keys().copied().collect::<Vec<_>>();
154
155 clients.sort_by(|a, b| b.cmp(a));
157
158 for client in clients {
159 encoder.write_var_u64(client)?;
160 self.get(&client).unwrap().write(encoder)?;
161 }
162
163 Ok(())
164 }
165}
166
167#[cfg(test)]
168mod tests {
169 use super::*;
170
171 #[test]
172 fn test_delete_set_add() {
173 let delete_set = DeleteSet::from([
174 (1, vec![0..10, 20..30]),
175 (2, vec![0..5, 10..20]),
176 (3, vec![15..20, 30..35]),
177 (4, vec![0..10]),
178 ]);
179
180 {
181 let mut delete_set = delete_set.clone();
182 delete_set.add(1, 5, 25);
183 assert_eq!(delete_set.get(&1), Some(&OrderRange::Range(0..30)));
184 }
185
186 {
187 let mut delete_set = delete_set;
188 delete_set.add(1, 5, 10);
189 assert_eq!(delete_set.get(&1), Some(&OrderRange::Fragment(vec![0..15, 20..30])));
190 }
191 }
192
193 #[test]
194 fn test_delete_set_batch_push() {
195 let delete_set = DeleteSet::from([
196 (1, vec![0..10, 20..30]),
197 (2, vec![0..5, 10..20]),
198 (3, vec![15..20, 30..35]),
199 (4, vec![0..10]),
200 ]);
201
202 {
203 let mut delete_set = delete_set.clone();
204 delete_set.batch_push(1, vec![0..5, 10..20]);
205 assert_eq!(delete_set.get(&1), Some(&OrderRange::Range(0..30)));
206 }
207
208 {
209 let mut delete_set = delete_set;
210 delete_set.batch_push(1, vec![40..50, 10..20]);
211 assert_eq!(delete_set.get(&1), Some(&OrderRange::Fragment(vec![0..30, 40..50])));
212 }
213 }
214
215 #[test]
216 fn test_encode_decode() {
217 let delete_set = DeleteSet::from([(1, vec![0..10, 20..30]), (2, vec![0..5, 10..20])]);
218 let mut encoder = RawEncoder::default();
219 delete_set.write(&mut encoder).unwrap();
220 let mut decoder = RawDecoder::new(encoder.into_inner());
221 let decoded = DeleteSet::read(&mut decoder).unwrap();
222 assert_eq!(delete_set, decoded);
223 }
224}