building_blocks_storage/array/
compression.rs1use crate::{Array, Compressed, Compression, FromBytesCompression};
2
3use building_blocks_core::prelude::*;
4
5#[derive(Clone, Copy, Debug)]
8pub struct FastArrayCompression<N, C> {
9 pub channels_compression: C,
10 marker: std::marker::PhantomData<N>,
11}
12
13impl<N, C> FastArrayCompression<N, C> {
14 pub fn new(channels_compression: C) -> Self {
15 Self {
16 channels_compression,
17 marker: Default::default(),
18 }
19 }
20
21 pub fn channels_compression(&self) -> &C {
22 &self.channels_compression
23 }
24}
25
26impl<N, C, B> FromBytesCompression<B> for FastArrayCompression<N, C>
27where
28 C: FromBytesCompression<B>,
29{
30 fn from_bytes_compression(bytes_compression: B) -> Self {
31 Self::new(C::from_bytes_compression(bytes_compression))
32 }
33}
34
35#[derive(Clone)]
37pub struct FastCompressedArray<N, C>
38where
39 C: Compression,
40{
41 compressed_channels: C::CompressedData,
42 extent: ExtentN<N>,
43}
44
45impl<N, C> FastCompressedArray<N, C>
46where
47 C: Compression,
48{
49 pub fn compressed_channels(&self) -> &C::CompressedData {
50 &self.compressed_channels
51 }
52
53 pub fn extent(&self) -> &ExtentN<N> {
54 &self.extent
55 }
56
57 pub fn into_parts(self) -> (C::CompressedData, ExtentN<N>) {
58 (self.compressed_channels, self.extent)
59 }
60}
61
62impl<N, C> Compression for FastArrayCompression<N, C>
63where
64 PointN<N>: Copy,
65 C: Compression,
66{
67 type Data = Array<N, C::Data>;
68 type CompressedData = FastCompressedArray<N, C>;
69
70 fn compress(&self, data: &Self::Data) -> Compressed<Self> {
71 let compressed_channels = self.channels_compression.compress(data.channels()).take();
72
73 Compressed::new(FastCompressedArray {
74 compressed_channels,
75 extent: data.extent,
76 })
77 }
78
79 fn decompress(compressed: &Self::CompressedData) -> Self::Data {
80 Array::new(
81 compressed.extent,
82 C::decompress(&compressed.compressed_channels),
83 )
84 }
85}
86
87pub mod multichannel_aliases {
88 use super::*;
89 use crate::array::channels::multichannel::multichannel_aliases::*;
90
91 pub type FastArrayCompressionNx1<N, By, A> =
92 FastArrayCompression<N, FastChannelsCompression1<By, A>>;
93 pub type FastArrayCompressionNx2<N, By, A, B> =
94 FastArrayCompression<N, FastChannelsCompression2<By, A, B>>;
95 pub type FastArrayCompressionNx3<N, By, A, B, C> =
96 FastArrayCompression<N, FastChannelsCompression3<By, A, B, C>>;
97 pub type FastArrayCompressionNx4<N, By, A, B, C, D> =
98 FastArrayCompression<N, FastChannelsCompression4<By, A, B, C, D>>;
99 pub type FastArrayCompressionNx5<N, By, A, B, C, D, E> =
100 FastArrayCompression<N, FastChannelsCompression5<By, A, B, C, D, E>>;
101 pub type FastArrayCompressionNx6<N, By, A, B, C, D, E, F> =
102 FastArrayCompression<N, FastChannelsCompression6<By, A, B, C, D, E, F>>;
103}
104
105pub use multichannel_aliases::*;
106
107#[cfg(test)]
115mod test {
116 use super::*;
117 use crate::{Array3x1, BytesCompression};
118
119 use crate::test_utilities::sphere_bit_array;
120 use utilities::test::test_print;
121
122 #[cfg(feature = "lz4")]
123 use crate::Lz4;
124 #[cfg(feature = "snap")]
125 use crate::Snappy;
126
127 #[cfg(feature = "snap")]
128 #[test]
129 fn sphere_array_compression_rate_snappy() {
130 sphere_array_compression_rate(Snappy, 32);
131 sphere_array_compression_rate(Snappy, 64);
132 sphere_array_compression_rate(Snappy, 128);
133 }
134
135 #[cfg(feature = "snap")]
136 #[test]
137 fn homogeneous_array_compression_rate_snappy() {
138 homogeneous_array_compression_rate(Snappy, 32);
139 homogeneous_array_compression_rate(Snappy, 64);
140 homogeneous_array_compression_rate(Snappy, 128);
141 }
142
143 #[cfg(feature = "lz4")]
144 #[test]
145 fn sphere_array_compression_rate_lz4() {
146 sphere_array_compression_rate(Lz4 { level: 10 }, 32);
147 sphere_array_compression_rate(Lz4 { level: 10 }, 64);
148 sphere_array_compression_rate(Lz4 { level: 10 }, 128);
149 }
150
151 #[cfg(feature = "lz4")]
152 #[test]
153 fn homogeneous_array_compression_rate_lz4() {
154 homogeneous_array_compression_rate(Lz4 { level: 10 }, 32);
155 homogeneous_array_compression_rate(Lz4 { level: 10 }, 64);
156 homogeneous_array_compression_rate(Lz4 { level: 10 }, 128);
157 }
158
159 fn homogeneous_array_compression_rate<B: BytesCompression>(compression: B, side_length: i32) {
160 let extent = Extent3i::from_min_and_shape(Point3i::ZERO, Point3i::fill(side_length));
161 let array = Array3x1::fill_with(extent, |_p| 0u16);
162 array_compression_rate(&array, compression);
163 }
164
165 fn sphere_array_compression_rate<B: BytesCompression>(compression: B, side_length: i32) {
166 let array = sphere_bit_array(side_length, 1u16, 0u16).0;
167 array_compression_rate(&array, compression);
168 }
169
170 fn array_compression_rate<B: BytesCompression>(array: &Array3x1<u16>, bytes_compression: B) {
171 let source_size_bytes = array.extent().num_points() * 2;
172
173 let compression = FastArrayCompressionNx1::from_bytes_compression(bytes_compression);
174
175 let compressed_array = compression.compress(array).take();
176
177 let compressed_size_bytes = compressed_array
178 .compressed_channels()
179 .compressed_bytes()
180 .len();
181
182 test_print(&format!(
183 "source = {} bytes, compressed = {} bytes; rate = {:.1}%\n",
184 source_size_bytes,
185 compressed_size_bytes,
186 100.0 * (compressed_size_bytes as f32 / source_size_bytes as f32)
187 ));
188 }
189}