1use crate::compression::{
4 AdvancedCompressionType, CompressedData, CompressionAlgorithm, CompressionMetadata,
5};
6use anyhow::{anyhow, Result};
7use std::collections::HashMap;
8use std::time::Instant;
9
10pub struct DeltaEncoder;
12
13impl DeltaEncoder {
14 pub fn encode_u64_sequence(values: &[u64]) -> Result<Vec<u8>> {
16 if values.is_empty() {
17 return Ok(Vec::new());
18 }
19
20 let mut encoded = Vec::new();
21
22 encoded.extend_from_slice(&values[0].to_le_bytes());
24
25 for i in 1..values.len() {
27 let delta = if values[i] >= values[i - 1] {
28 (values[i] - values[i - 1]) << 1 } else {
30 ((values[i - 1] - values[i]) << 1) | 1 };
32 encoded.extend_from_slice(&delta.to_le_bytes());
33 }
34
35 Ok(encoded)
36 }
37
38 pub fn decode_u64_sequence(encoded: &[u8]) -> Result<Vec<u64>> {
40 if encoded.is_empty() {
41 return Ok(Vec::new());
42 }
43
44 if encoded.len() % 8 != 0 {
45 return Err(anyhow!("Invalid delta encoded data length"));
46 }
47
48 let mut values = Vec::new();
49 let chunks: Vec<_> = encoded.chunks_exact(8).collect();
50
51 let first_value = u64::from_le_bytes([
53 chunks[0][0],
54 chunks[0][1],
55 chunks[0][2],
56 chunks[0][3],
57 chunks[0][4],
58 chunks[0][5],
59 chunks[0][6],
60 chunks[0][7],
61 ]);
62 values.push(first_value);
63
64 let mut current_value = first_value;
65
66 for chunk in &chunks[1..] {
68 let encoded_delta = u64::from_le_bytes([
69 chunk[0], chunk[1], chunk[2], chunk[3], chunk[4], chunk[5], chunk[6], chunk[7],
70 ]);
71
72 let is_negative = (encoded_delta & 1) == 1;
73 let delta = encoded_delta >> 1;
74
75 current_value = if is_negative {
76 current_value.saturating_sub(delta)
77 } else {
78 current_value.saturating_add(delta)
79 };
80
81 values.push(current_value);
82 }
83
84 Ok(values)
85 }
86
87 pub fn encode_byte_sequence(data: &[u8]) -> Result<Vec<u8>> {
89 if data.is_empty() {
90 return Ok(Vec::new());
91 }
92
93 let mut encoded = Vec::new();
94 encoded.push(data[0]);
95
96 for i in 1..data.len() {
97 let delta = data[i] as i16 - data[i - 1] as i16;
98 encoded.extend_from_slice(&delta.to_le_bytes());
99 }
100
101 Ok(encoded)
102 }
103
104 pub fn decode_byte_sequence(encoded: &[u8]) -> Result<Vec<u8>> {
106 if encoded.is_empty() {
107 return Ok(Vec::new());
108 }
109
110 let mut decoded = Vec::new();
111 decoded.push(encoded[0]);
112
113 let mut current_value = encoded[0] as i16;
114
115 for chunk in encoded[1..].chunks_exact(2) {
116 let delta = i16::from_le_bytes([chunk[0], chunk[1]]);
117 current_value = (current_value + delta).clamp(0, 255);
118 decoded.push(current_value as u8);
119 }
120
121 Ok(decoded)
122 }
123
124 pub fn estimate_byte_compression_ratio(data: &[u8]) -> f64 {
126 if data.len() < 2 {
127 return 1.0;
128 }
129
130 let compressed_size = 1 + (data.len() - 1) * 2; compressed_size as f64 / data.len() as f64
132 }
133
134 pub fn encode(values: &[u64]) -> Vec<u8> {
143 if values.is_empty() {
144 return Vec::new();
145 }
146
147 let mut out = Vec::new();
148
149 out.extend_from_slice(&values[0].to_le_bytes());
151
152 let mut prev = values[0];
153 for &v in &values[1..] {
154 let delta: i64 = if v >= prev {
156 (v - prev) as i64
157 } else {
158 -((prev - v) as i64)
159 };
160 let zigzag: u64 = if delta >= 0 {
162 (delta as u64) << 1
163 } else {
164 ((!delta as u64) << 1) | 1
165 };
166 encode_leb128(&mut out, zigzag);
168 prev = v;
169 }
170
171 out
172 }
173
174 pub fn decode(data: &[u8]) -> Result<Vec<u64>> {
176 if data.is_empty() {
177 return Ok(Vec::new());
178 }
179
180 if data.len() < 8 {
181 return Err(anyhow!("Delta-encoded data too short for first value"));
182 }
183
184 let first = u64::from_le_bytes(
185 data[..8]
186 .try_into()
187 .map_err(|_| anyhow!("Failed to read first value"))?,
188 );
189
190 let mut values = vec![first];
191 let mut prev = first;
192 let mut pos = 8;
193
194 while pos < data.len() {
195 let (zigzag, consumed) = decode_leb128(&data[pos..])
196 .ok_or_else(|| anyhow!("Invalid LEB128 encoding at byte {}", pos))?;
197 pos += consumed;
198
199 let delta: i64 = if (zigzag & 1) == 0 {
201 (zigzag >> 1) as i64
202 } else {
203 !((zigzag >> 1) as i64)
204 };
205
206 prev = if delta >= 0 {
207 prev.saturating_add(delta as u64)
208 } else {
209 prev.saturating_sub((-delta) as u64)
210 };
211 values.push(prev);
212 }
213
214 Ok(values)
215 }
216
217 pub fn estimate_u64_compression_ratio(values: &[u64]) -> f64 {
219 if values.len() < 2 {
220 return 1.0;
221 }
222
223 let mut small_deltas = 0;
225 for i in 1..values.len() {
226 let delta = values[i].abs_diff(values[i - 1]);
227 if delta < 65536 {
228 small_deltas += 1;
229 }
230 }
231
232 if small_deltas > values.len() / 2 {
235 0.5 } else {
237 1.0 }
239 }
240}
241
242fn encode_leb128(buf: &mut Vec<u8>, mut value: u64) {
248 loop {
249 let byte = (value & 0x7F) as u8;
250 value >>= 7;
251 if value == 0 {
252 buf.push(byte);
253 break;
254 } else {
255 buf.push(byte | 0x80);
256 }
257 }
258}
259
260fn decode_leb128(data: &[u8]) -> Option<(u64, usize)> {
264 let mut value: u64 = 0;
265 let mut shift: u32 = 0;
266 for (i, &byte) in data.iter().enumerate() {
267 let low = (byte & 0x7F) as u64;
268 value |= low.checked_shl(shift)?;
269 shift += 7;
270 if (byte & 0x80) == 0 {
271 return Some((value, i + 1));
272 }
273 if shift > 63 {
274 return None; }
276 }
277 None }
279
280impl CompressionAlgorithm for DeltaEncoder {
281 fn compress(&self, data: &[u8]) -> Result<CompressedData> {
282 let start = Instant::now();
283 let compressed_bytes = Self::encode_byte_sequence(data)?;
284 let compression_time = start.elapsed();
285
286 let mut metadata_map = HashMap::new();
287 if !data.is_empty() {
288 metadata_map.insert("first_value".to_string(), data[0].to_string());
289 metadata_map.insert(
290 "delta_count".to_string(),
291 (data.len().saturating_sub(1)).to_string(),
292 );
293 }
294
295 let metadata = CompressionMetadata {
296 algorithm: AdvancedCompressionType::Delta,
297 original_size: data.len() as u64,
298 compressed_size: compressed_bytes.len() as u64,
299 compression_time_us: compression_time.as_micros() as u64,
300 metadata: metadata_map,
301 };
302
303 Ok(CompressedData {
304 data: compressed_bytes,
305 metadata,
306 })
307 }
308
309 fn decompress(&self, compressed: &CompressedData) -> Result<Vec<u8>> {
310 if compressed.metadata.algorithm != AdvancedCompressionType::Delta {
311 return Err(anyhow!(
312 "Invalid compression algorithm: expected Delta, got {}",
313 compressed.metadata.algorithm
314 ));
315 }
316
317 Self::decode_byte_sequence(&compressed.data)
318 }
319
320 fn algorithm_type(&self) -> AdvancedCompressionType {
321 AdvancedCompressionType::Delta
322 }
323}
324
325#[cfg(test)]
326mod tests {
327 use super::*;
328
329 #[test]
330 fn test_u64_delta_encoding() {
331 let values = vec![100, 102, 105, 103, 110];
332 let encoded = DeltaEncoder::encode_u64_sequence(&values).unwrap();
333 let decoded = DeltaEncoder::decode_u64_sequence(&encoded).unwrap();
334 assert_eq!(values, decoded);
335 }
336
337 #[test]
338 fn test_byte_delta_encoding() {
339 let data = vec![50, 52, 55, 53, 60];
340 let encoded = DeltaEncoder::encode_byte_sequence(&data).unwrap();
341 let decoded = DeltaEncoder::decode_byte_sequence(&encoded).unwrap();
342 assert_eq!(data, decoded);
343 }
344
345 #[test]
346 fn test_empty_sequence() {
347 let data = vec![];
348 let encoded = DeltaEncoder::encode_byte_sequence(&data).unwrap();
349 assert!(encoded.is_empty());
350 }
351
352 #[test]
353 fn test_single_value() {
354 let data = vec![42];
355 let encoded = DeltaEncoder::encode_byte_sequence(&data).unwrap();
356 let decoded = DeltaEncoder::decode_byte_sequence(&encoded).unwrap();
357 assert_eq!(data, decoded);
358 }
359
360 #[test]
361 fn test_compression_algorithm_trait() {
362 let encoder = DeltaEncoder;
363 let data = vec![10, 12, 15, 13, 20];
364
365 let compressed = encoder.compress(&data).unwrap();
366 assert_eq!(
367 compressed.metadata.algorithm,
368 AdvancedCompressionType::Delta
369 );
370
371 let decompressed = encoder.decompress(&compressed).unwrap();
372 assert_eq!(data, decompressed);
373 }
374
375 #[test]
376 fn test_sorted_sequence() {
377 let values = vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
378 let encoded = DeltaEncoder::encode_u64_sequence(&values).unwrap();
379 let decoded = DeltaEncoder::decode_u64_sequence(&encoded).unwrap();
380 assert_eq!(values, decoded);
381 }
382
383 #[test]
384 fn test_decreasing_sequence() {
385 let values = vec![100, 90, 80, 70, 60];
386 let encoded = DeltaEncoder::encode_u64_sequence(&values).unwrap();
387 let decoded = DeltaEncoder::decode_u64_sequence(&encoded).unwrap();
388 assert_eq!(values, decoded);
389 }
390
391 #[test]
394 fn test_vle_encode_empty() {
395 let encoded = DeltaEncoder::encode(&[]);
396 assert!(encoded.is_empty());
397 }
398
399 #[test]
400 fn test_vle_decode_empty() {
401 let decoded = DeltaEncoder::decode(&[]).unwrap();
402 assert!(decoded.is_empty());
403 }
404
405 #[test]
406 fn test_vle_single_value() {
407 let values = vec![42u64];
408 let encoded = DeltaEncoder::encode(&values);
409 let decoded = DeltaEncoder::decode(&encoded).unwrap();
410 assert_eq!(decoded, values);
411 }
412
413 #[test]
414 fn test_vle_sorted_ascending() {
415 let values: Vec<u64> = (1..=20).collect();
416 let encoded = DeltaEncoder::encode(&values);
417 let decoded = DeltaEncoder::decode(&encoded).unwrap();
418 assert_eq!(decoded, values);
419 }
420
421 #[test]
422 fn test_vle_sorted_descending() {
423 let values: Vec<u64> = (1..=20).rev().collect();
424 let encoded = DeltaEncoder::encode(&values);
425 let decoded = DeltaEncoder::decode(&encoded).unwrap();
426 assert_eq!(decoded, values);
427 }
428
429 #[test]
430 fn test_vle_with_duplicates() {
431 let values = vec![5u64, 5, 5, 5, 10, 10, 15];
432 let encoded = DeltaEncoder::encode(&values);
433 let decoded = DeltaEncoder::decode(&encoded).unwrap();
434 assert_eq!(decoded, values);
435 }
436
437 #[test]
438 fn test_vle_large_sequence_roundtrip() {
439 let values: Vec<u64> = (0..1000).map(|i| i * 7).collect();
440 let encoded = DeltaEncoder::encode(&values);
441 let decoded = DeltaEncoder::decode(&encoded).unwrap();
442 assert_eq!(decoded, values);
443 }
444
445 #[test]
446 fn test_vle_large_gaps() {
447 let values = vec![0u64, 1_000_000, 2_000_000, 3_000_000];
448 let encoded = DeltaEncoder::encode(&values);
449 let decoded = DeltaEncoder::decode(&encoded).unwrap();
450 assert_eq!(decoded, values);
451 }
452
453 #[test]
454 fn test_vle_compact_for_small_deltas() {
455 let values: Vec<u64> = (100..200).collect(); let vle_encoded = DeltaEncoder::encode(&values);
459 assert!(vle_encoded.len() < 100 * 8, "VLE should be more compact");
462 }
463
464 #[test]
467 fn test_leb128_round_trip_small() {
468 let mut buf = Vec::new();
469 encode_leb128(&mut buf, 127);
470 let (v, n) = decode_leb128(&buf).unwrap();
471 assert_eq!(v, 127);
472 assert_eq!(n, 1);
473 }
474
475 #[test]
476 fn test_leb128_round_trip_large() {
477 let mut buf = Vec::new();
478 encode_leb128(&mut buf, u64::MAX);
479 let (v, _) = decode_leb128(&buf).unwrap();
480 assert_eq!(v, u64::MAX);
481 }
482
483 #[test]
484 fn test_leb128_zero() {
485 let mut buf = Vec::new();
486 encode_leb128(&mut buf, 0);
487 assert_eq!(buf.len(), 1);
488 let (v, _) = decode_leb128(&buf).unwrap();
489 assert_eq!(v, 0);
490 }
491}