simple_direct_delta_encoding/
lib.rs1mod data_difference;
2#[cfg(test)]
3mod data_difference_tests;
4#[cfg(test)]
5mod tests;
6
7use std::collections::BTreeMap;
8
9use data_difference::*;
10use dispnet_hash::{DispnetHash, HashType};
11
12#[derive(Debug)]
13pub enum SDDEError {
14 CRC(String),
15 DifferenceInvalid(String),
16}
17
18#[derive(Clone)]
19pub struct SimpleDirectDeltaEncoding {
20 pub data_collection: BTreeMap<u8, IndexedData>,
21 pub crc: Vec<u8>,
22 index_mapping: BTreeMap<u8, Vec<u8>>,
23 last_index_mapping: BTreeMap<u8, HistoryValue>,
24}
25
26#[derive(Debug, Clone, Default)]
27pub struct HistoryValue {
28 pub current: Vec<u8>,
29 pub last: Vec<u8>,
30}
31
32impl HistoryValue {
33 pub fn new(current: Vec<u8>) -> HistoryValue {
34 HistoryValue {
35 current,
36 last: Vec::new(),
37 }
38 }
39
40 pub fn set(&mut self, current: Vec<u8>) {
41 self.last = self.current.clone();
42 self.current = current;
43 }
44}
45
46#[derive(Debug, Clone)]
47pub struct IndexedData {
48 pub index: u8,
49 pub data: Vec<u8>,
50}
51
52impl IndexedData {
53 pub fn new(index: u8, data: Vec<u8>) -> IndexedData {
54 IndexedData { index, data }
55 }
56}
57
58#[derive(Debug, Default)]
59pub struct EntryDifference {
60 pub remove_entry: bool,
61 pub diffs: Vec<Difference>,
62 pub map_name_changed: Option<Vec<Difference>>,
63}
64
65impl EntryDifference {
66 pub fn new(diffs: Vec<Difference>) -> EntryDifference {
67 EntryDifference {
68 remove_entry: false,
69 diffs,
70 map_name_changed: None,
71 }
72 }
73
74 pub fn remove_entry() -> EntryDifference {
75 EntryDifference {
76 remove_entry: true,
77 diffs: Vec::new(),
78 map_name_changed: None,
79 }
80 }
81}
82
83#[derive(Debug, Clone)]
84pub struct IndexedDataResult {
85 pub index: u8,
86 pub data: Vec<u8>,
87 pub map_name_changed: Option<Vec<u8>>,
88}
89
90impl IndexedDataResult {
91 pub fn new(index_data: &IndexedData) -> IndexedDataResult {
92 IndexedDataResult {
93 index: index_data.index,
94 data: index_data.data.clone(),
95 map_name_changed: None,
96 }
97 }
98}
99
100impl SimpleDirectDeltaEncoding {
101 pub fn new(data: &[IndexedData]) -> SimpleDirectDeltaEncoding {
102 let data = Self::get_sorted(data);
103 let bytes = Self::fold_indexed_data(&data);
104 let crc = DispnetHash::create(HashType::CRC, &bytes, None);
105 let mut data_map: BTreeMap<u8, IndexedData> = BTreeMap::new();
106 for indexed_data in data {
107 data_map.insert(indexed_data.index, indexed_data.clone());
108 }
109 SimpleDirectDeltaEncoding {
110 data_collection: data_map,
111 crc: crc.digest_value.clone(),
112 index_mapping: BTreeMap::new(),
113 last_index_mapping: BTreeMap::new(),
114 }
115 }
116
117 pub fn load(data: &[IndexedData], crc: Vec<u8>) -> SimpleDirectDeltaEncoding {
118 let data = Self::get_sorted(data);
119 let mut data_map: BTreeMap<u8, IndexedData> = BTreeMap::new();
120 for indexed_data in data {
121 data_map.insert(indexed_data.index, indexed_data.clone());
122 }
123 SimpleDirectDeltaEncoding {
124 data_collection: data_map,
125 crc,
126 index_mapping: BTreeMap::new(),
127 last_index_mapping: BTreeMap::new(),
128 }
129 }
130
131 pub fn get_state(&self) -> Vec<u8> {
137 let mut bytes = Self::fold_indexed_data(&self.data_collection.values().cloned().collect::<Vec<IndexedData>>());
138 for (_, value) in self.last_index_mapping.iter() {
139 bytes.extend(value.current.clone());
140 }
141 bytes
142 }
143
144 pub fn change_index_mapping(&mut self, index: u8, key: &[u8]) {
146 self.index_mapping.insert(index, key.to_owned());
147 }
148
149 pub fn apply_index_mappings(&mut self) {
155 for (index, key) in self.index_mapping.iter() {
156 if let Some(value) = self.last_index_mapping.get_mut(index) {
157 value.set(key.to_owned());
158 } else {
159 self.last_index_mapping.insert(*index, HistoryValue::new(key.to_owned()));
160 }
161 }
162 self.index_mapping.clear();
163 }
164
165 pub fn patch(&mut self, new_data: &[IndexedData]) -> Vec<u8> {
183 let new_data = Self::get_sorted(new_data);
184 let new_indexes: Vec<u8> = new_data.iter().map(|x| x.index).collect();
185 let mut diff_data: Vec<u8> = vec![self.crc.len() as u8];
187 diff_data.extend(self.crc.clone());
188
189 for data in new_data {
190 if let Some(old_data) = self.data_collection.get_mut(&data.index) {
191 let last_diff = DataDifference::diff(&old_data.data, &data.data);
192 old_data.data = data.data.to_owned();
193
194 let mut new_diff = Vec::new();
196 new_diff.push(b'v');
198 new_diff.push(data.index);
199 for diff in last_diff.iter() {
200 let bytes = diff.to_bytes();
201 new_diff.extend(Difference::get_usize_type_to_bytes(bytes.len()));
203 new_diff.extend(bytes);
204 }
205 if new_diff.len() > 2 {
207 diff_data.extend(new_diff);
208 }
209 } else {
210 self.data_collection.insert(data.index, data.clone());
212 let mut new_diff = Vec::new();
214 new_diff.push(b'v');
216 new_diff.push(data.index);
217 for diff in DataDifference::diff(&Vec::new(), &data.data).iter() {
218 let bytes = diff.to_bytes();
219 new_diff.extend(Difference::get_usize_type_to_bytes(bytes.len()));
221 new_diff.extend(bytes);
222 }
223 diff_data.extend(new_diff);
224 }
225 }
226
227 let src_indexes: Vec<u8> = self.data_collection.keys().copied().collect();
229 let removed_indexes: Vec<u8> = src_indexes
230 .iter()
231 .filter(|x| !new_indexes.contains(x))
232 .copied()
233 .collect();
234
235 for index in &removed_indexes {
236 self.data_collection.remove(index);
238
239 diff_data.extend(vec![b'v', index.to_owned(), b'r']);
241 }
242
243 for (index, new_data) in self.index_mapping.iter() {
245 if removed_indexes.contains(index) {
247 continue;
248 }
249 let new_diff = vec![b'v', *index, b'm'];
252
253 let mut is_new_mapping = false;
254 if let Some(old_value) = self.last_index_mapping.get(index) {
256 let last_diff = DataDifference::diff(&old_value.current, new_data);
257
258 let mut diff_only = Vec::new();
259 for diff in last_diff.iter() {
260 let bytes = diff.to_bytes();
261 diff_only.extend(Difference::get_usize_type_to_bytes(bytes.len()));
263 diff_only.extend(bytes);
264 }
265 if !diff_only.is_empty() {
267 diff_data.extend(new_diff);
268 diff_data.extend(Difference::get_usize_type_to_bytes(diff_only.len()));
269 diff_data.extend(diff_only);
270 }
271 } else {
272 is_new_mapping = true;
273 let mut diff_only = Vec::new();
275 for diff in DataDifference::diff(&Vec::new(), new_data).iter() {
276 let bytes = diff.to_bytes();
277 diff_only.extend(Difference::get_usize_type_to_bytes(bytes.len()));
279 diff_only.extend(bytes);
280 }
281 diff_data.extend(new_diff);
282 diff_data.extend(Difference::get_usize_type_to_bytes(diff_only.len()));
283 diff_data.extend(diff_only);
284 }
285 if is_new_mapping {
287 self.last_index_mapping
288 .insert(*index, HistoryValue::new(new_data.clone()));
289 } else {
290 self.last_index_mapping
291 .get_mut(index)
292 .unwrap()
293 .set(new_data.clone());
294 }
295 }
296 self.index_mapping.clear();
297
298 diff_data
299 }
300
301 pub fn apply_patch(&mut self, diff_data: &[u8]) -> Result<Vec<IndexedDataResult>, SDDEError> {
302 let crc_length = diff_data[0];
303 let crc_value = &diff_data[1..(1 + crc_length as usize)];
304 let bytes = Self::fold_indexed_data(
305 self.data_collection
306 .values()
307 .map(|x| x.to_owned())
308 .collect::<Vec<IndexedData>>()
309 .as_slice(),
310 );
311 let crc = DispnetHash::create(HashType::CRC, &bytes, None);
312 if crc.digest_value != crc_value {
313 return Err(SDDEError::CRC("CRC value does not match".to_owned()));
314 }
315
316 let mut return_data: Vec<IndexedDataResult> = Vec::new();
317 let diffs = Self::get_differences(diff_data);
318 for (index, diff) in diffs.iter() {
319 if diff.remove_entry {
321 self.data_collection.remove(index);
322 continue;
323 }
324 if let Some(src_data) = self.data_collection.get_mut(index) {
325 let data = DataDifference::apply_diff(&src_data.data, &diff.diffs);
326 src_data.data = data;
327 } else {
328 let new_data = Vec::new();
330 let data = DataDifference::apply_diff(&new_data, &diff.diffs);
331 let data = IndexedData::new(*index, data);
332 self.data_collection.insert(*index, data);
333 }
334
335 let mut index_data = IndexedDataResult::new(self.data_collection.get(index).unwrap());
336 if diff.map_name_changed.is_some() {
338 let last_index_map_bytes = self
339 .last_index_mapping
340 .get(index)
341 .cloned()
342 .unwrap_or_default()
343 .current;
344 let map_diffs_bytes = DataDifference::apply_diff(
345 &last_index_map_bytes,
346 diff.map_name_changed.as_ref().unwrap(),
347 );
348 index_data.map_name_changed = Some(map_diffs_bytes.clone());
349 if !self.last_index_mapping.contains_key(index) {
351 self.last_index_mapping
352 .insert(*index, HistoryValue::new(map_diffs_bytes));
353 } else {
354 self.last_index_mapping
355 .get_mut(index)
356 .unwrap()
357 .set(map_diffs_bytes);
358 }
359 }
360 return_data.push(index_data);
361 }
362
363 self.crc = crc.digest_value.clone();
364
365 Ok(return_data)
366 }
367
368 pub fn fold_bytes(bytes: &[Vec<u8>]) -> Vec<u8> {
369 bytes.iter().fold(Vec::new(), |mut acc, byte| {
370 acc.extend(byte.clone());
371 acc
372 })
373 }
374
375 pub fn fold_index_result(bytes: &[IndexedDataResult]) -> Vec<u8> {
376 bytes.iter().fold(Vec::new(), |mut acc, index| {
377 acc.extend(index.data.clone());
378 acc
379 })
380 }
381
382 pub fn fold_index(bytes: &[IndexedData]) -> Vec<u8> {
383 bytes.iter().fold(Vec::new(), |mut acc, index| {
384 acc.extend(index.data.clone());
385 acc
386 })
387 }
388
389 pub fn get_differences(diff_bytes: &[u8]) -> BTreeMap<u8, EntryDifference> {
390 Self::on_get_differences(diff_bytes, true)
391 }
392
393 pub fn get_index_mapping(&self) -> BTreeMap<u8, HistoryValue> {
394 self.last_index_mapping.clone()
395 }
396
397 fn on_get_differences(diff_bytes: &[u8], has_crc: bool) -> BTreeMap<u8, EntryDifference> {
398 let diff_bytes = if has_crc {
399 Self::get_differences_bytes_with_crc(diff_bytes)
400 } else {
401 diff_bytes
402 };
403 let mut diffs: BTreeMap<u8, EntryDifference> = BTreeMap::new();
404 let mut i = 0;
405 let mut index = 0;
406 while i < diff_bytes.len() {
407 if diff_bytes[i] == b'v' {
409 index = diff_bytes[i + 1];
410 i += 2;
411 }
412 if diff_bytes[i] == b'r' {
414 i += 1;
415 diffs.insert(index, EntryDifference::remove_entry());
416 continue;
417 }
418 if diff_bytes[i] == b'm' {
420 i += 1;
421 let map_diffs_length = Difference::get_usize_type_from_bytes(&diff_bytes[i..]);
422 i += map_diffs_length.1;
423 let bytes = &diff_bytes[i..(i + map_diffs_length.0)];
424 i += bytes.len();
425
426 let map_diffs_result = Self::on_get_differences(bytes, false);
428 let map_entry_diff = map_diffs_result.get(&0);
429 if map_entry_diff.is_none() {
430 continue;
431 }
432 let map_entry_diff = map_entry_diff.unwrap().to_owned().diffs.clone();
433
434 if let Some(d) = diffs.get_mut(&index) {
436 d.map_name_changed = Some(map_entry_diff);
437 } else {
438 diffs.insert(index, EntryDifference::new(Vec::new()));
439 diffs.get_mut(&index).unwrap().map_name_changed = Some(map_entry_diff);
440 }
441
442 continue;
443 }
444
445 let diff_length = Difference::get_usize_type_from_bytes(&diff_bytes[i..]);
446 i += diff_length.1;
447 let bytes = &diff_bytes[i..(i + diff_length.0)];
448 let diff = Difference::from_bytes(bytes);
449 i += diff_length.0;
450
451 if let Some(d) = diffs.get_mut(&index) {
452 d.diffs.push(diff);
453 } else {
454 diffs.insert(index, EntryDifference::new(vec![diff]));
455 }
456 }
457 diffs
458 }
459
460 pub fn get_differences_bytes_with_crc(diff_bytes: &[u8]) -> &[u8] {
461 let crc_length = diff_bytes[0];
462 let _crc_value = &diff_bytes[1..(1 + crc_length as usize)];
463 &diff_bytes[(1 + crc_length as usize)..]
464 }
465
466 fn fold_indexed_data(data: &[IndexedData]) -> Vec<u8> {
467 data.iter().fold(Vec::new(), |mut acc, indexed_data| {
468 acc.extend(indexed_data.data.clone());
469 acc
470 })
471 }
472
473 fn get_sorted(data: &[IndexedData]) -> Vec<IndexedData> {
474 let mut data = data.to_vec();
475 data.sort_by(|a, b| a.index.cmp(&b.index));
476 data
477 }
478}