Skip to main content

graphblas_sparse_linear_algebra/collections/serializer/
lz4hc_serializer.rs

1use std::{mem::MaybeUninit, sync::Arc};
2
3use suitesparse_graphblas_sys::{
4    GrB_Desc_Field_GxB_COMPRESSION, GrB_Descriptor, GrB_Descriptor_free, GrB_Descriptor_new,
5    GrB_Matrix, GrB_Vector, GxB_COMPRESSION_LZ4HC, GxB_Desc_set,
6};
7
8use crate::collections::sparse_matrix::operations::{
9    serialize_suitesparse_grapblas_sparse_matrix, SerializeSuitesparseGraphblasSparseMatrix,
10};
11use crate::collections::sparse_vector::operations::{
12    serialize_suitesparse_grapblas_sparse_vector, SerializeSuitesparseGraphblasSparseVector,
13};
14use crate::context::CallGraphBlasContext;
15use crate::{
16    context::{Context, GetContext},
17    error::SparseLinearAlgebraError,
18};
19
20use super::GetGraphblasSerializerDescriptor;
21
22/// Higher levels target higher compression ratios but take increasingly more time.
23pub enum LZ4HighCompressionLevel {
24    DEFAULT,
25    L0,
26    L1,
27    L2,
28    L3,
29    L4,
30    L5,
31    L6,
32    L7,
33    L8,
34    L9,
35}
36
37impl LZ4HighCompressionLevel {
38    fn to_graphblas_descriptor_offset(&self) -> u32 {
39        match self {
40            LZ4HighCompressionLevel::DEFAULT => 9,
41            LZ4HighCompressionLevel::L0 => 0,
42            LZ4HighCompressionLevel::L1 => 1,
43            LZ4HighCompressionLevel::L2 => 2,
44            LZ4HighCompressionLevel::L3 => 3,
45            LZ4HighCompressionLevel::L4 => 4,
46            LZ4HighCompressionLevel::L5 => 5,
47            LZ4HighCompressionLevel::L6 => 6,
48            LZ4HighCompressionLevel::L7 => 7,
49            LZ4HighCompressionLevel::L8 => 8,
50            LZ4HighCompressionLevel::L9 => 9,
51        }
52    }
53}
54
55pub struct LZ4HighCompressionSerializer {
56    context: Arc<Context>,
57    compression_level: LZ4HighCompressionLevel,
58    graphblas_descriptor: GrB_Descriptor,
59}
60
61impl GetContext for LZ4HighCompressionSerializer {
62    fn context(&self) -> Arc<Context> {
63        self.context.to_owned()
64    }
65
66    fn context_ref(&self) -> &Arc<Context> {
67        &self.context
68    }
69}
70
71impl GetGraphblasSerializerDescriptor for LZ4HighCompressionSerializer {
72    unsafe fn graphblas_serializer_descriptor(&self) -> GrB_Descriptor {
73        self.graphblas_descriptor
74    }
75
76    unsafe fn graphblas_serializer_descriptor_ref(&self) -> &GrB_Descriptor {
77        &self.graphblas_descriptor
78    }
79}
80
81impl LZ4HighCompressionSerializer {
82    pub fn new(
83        context: Arc<Context>,
84        compression_level: LZ4HighCompressionLevel,
85    ) -> Result<Self, SparseLinearAlgebraError> {
86        let mut graphblas_descriptor: MaybeUninit<GrB_Descriptor> = MaybeUninit::uninit();
87
88        context.call_without_detailed_error_information(|| unsafe {
89            GrB_Descriptor_new(graphblas_descriptor.as_mut_ptr())
90        })?;
91
92        let graphblas_descriptor = unsafe { graphblas_descriptor.assume_init() };
93
94        context.call(
95            || unsafe {
96                GxB_Desc_set(
97                    graphblas_descriptor,
98                    GrB_Desc_Field_GxB_COMPRESSION as i32,
99                    GxB_COMPRESSION_LZ4HC + compression_level.to_graphblas_descriptor_offset(),
100                )
101            },
102            &graphblas_descriptor,
103        )?;
104
105        Ok(Self {
106            context,
107            compression_level,
108            graphblas_descriptor,
109        })
110    }
111}
112
113impl Drop for LZ4HighCompressionSerializer {
114    fn drop(&mut self) {
115        let _ = self
116            .context
117            .call_without_detailed_error_information(|| unsafe {
118                GrB_Descriptor_free(&mut self.graphblas_descriptor)
119            });
120    }
121}
122
123impl SerializeSuitesparseGraphblasSparseMatrix for LZ4HighCompressionSerializer {
124    unsafe fn serialize_suitesparse_grapblas_sparse_matrix(
125        &self,
126        suitesparse_graphblas_sparse_matrix: GrB_Matrix,
127    ) -> Result<&[u8], SparseLinearAlgebraError> {
128        serialize_suitesparse_grapblas_sparse_matrix(self, suitesparse_graphblas_sparse_matrix)
129    }
130}
131
132impl SerializeSuitesparseGraphblasSparseVector for LZ4HighCompressionSerializer {
133    unsafe fn serialize_suitesparse_grapblas_sparse_vector(
134        &self,
135        suitesparse_graphblas_sparse_vector: GrB_Vector,
136    ) -> Result<&[u8], SparseLinearAlgebraError> {
137        serialize_suitesparse_grapblas_sparse_vector(self, suitesparse_graphblas_sparse_vector)
138    }
139}
140
141#[cfg(test)]
142mod tests {
143    use crate::collections::LZ4HighCompressionSerializer;
144
145    use super::*;
146
147    #[test]
148    fn new_serializer() {
149        let context = Context::init_default().unwrap();
150
151        let _zstd_serializer = LZ4HighCompressionSerializer::new(
152            context.clone(),
153            crate::collections::LZ4HighCompressionLevel::DEFAULT,
154        )
155        .unwrap();
156
157        assert!(true)
158    }
159}