apt_swarm/db/
compression.rs1use crate::errors::*;
2use std::io::{Read, Write};
3
4const CHUNK_SIZE: usize = 1024 * 1024 * 4; pub async fn compress(bytes: &[u8]) -> Result<Vec<u8>> {
7 let mut compressed = Vec::new();
8
9 let mut writer = lz4_flex::frame::FrameEncoder::new(&mut compressed);
10 for chunk in bytes.chunks(CHUNK_SIZE) {
11 writer.write_all(chunk)?;
12
13 tokio::task::yield_now().await;
15 }
16 writer.finish()?;
17
18 Ok(compressed)
19}
20
21pub async fn decompress(compressed: &[u8]) -> Result<Vec<u8>> {
22 let mut data = Vec::new();
23
24 let mut reader = lz4_flex::frame::FrameDecoder::new(compressed);
25 let mut buf = vec![0u8; CHUNK_SIZE];
27 loop {
28 let n = reader
29 .read(&mut buf[..])
30 .context("Failed to read from decompression stream")?;
31 if n == 0 {
32 break;
33 }
34 data.extend(&buf[..n]);
35
36 tokio::task::yield_now().await;
38 }
39
40 Ok(data)
41}
42
43#[cfg(test)]
44mod tests {
45 use super::*;
46
47 #[tokio::test]
48 async fn test_round_trip() {
49 let txt = b"hello world, around the world, around the world, around the world :)";
50 let compressed = compress(txt).await.unwrap();
51 let buf = decompress(&compressed).await.unwrap();
52 assert_eq!(&buf, txt);
53 }
54
55 #[tokio::test]
56 async fn test_compress() {
57 let buf = compress(b"hello world, around the world, around the world, around the world :)")
58 .await
59 .unwrap();
60 assert_eq!(
61 buf,
62 b"\x04\"M\x18`@\x82#\0\0\0\xff\x08hello world, around the\x12\0\x14`rld :)\0\0\0\0"
63 );
64 }
65
66 #[tokio::test]
67 async fn test_decompress() {
68 let compressed =
69 b"\x04\"M\x18`@\x82#\0\0\0\xff\x08hello world, around the\x12\0\x14`rld :)\0\0\0\0";
70 let buf = decompress(compressed).await.unwrap();
71 assert_eq!(
72 buf,
73 b"hello world, around the world, around the world, around the world :)"
74 );
75 }
76}