density_rs/algorithms/chameleon/
chameleon.rs

1use crate::algorithms::PLAIN_FLAG;
2use crate::codec::codec::Codec;
3use crate::codec::decoder::Decoder;
4use crate::codec::quad_encoder::QuadEncoder;
5use crate::errors::decode_error::DecodeError;
6use crate::errors::encode_error::EncodeError;
7use crate::io::read_buffer::ReadBuffer;
8use crate::io::read_signature::ReadSignature;
9use crate::io::write_buffer::WriteBuffer;
10use crate::io::write_signature::WriteSignature;
11use crate::{BIT_SIZE_U16, BIT_SIZE_U32, BYTE_SIZE_U32};
12use std::slice::{from_raw_parts, from_raw_parts_mut};
13
14pub(crate) const CHAMELEON_HASH_BITS: usize = BIT_SIZE_U16;
15pub(crate) const CHAMELEON_HASH_MULTIPLIER: u32 = 0x9D6EF916;
16
17pub(crate) const FLAG_SIZE_BITS: u8 = 1;
18pub(crate) const MAP_FLAG: u64 = 0x1;
19
20pub(crate) const PLAIN_PLAIN_FLAGS: u64 = (PLAIN_FLAG << 1) | PLAIN_FLAG;
21pub(crate) const MAP_PLAIN_FLAGS: u64 = (PLAIN_FLAG << 1) | MAP_FLAG;
22pub(crate) const PLAIN_MAP_FLAGS: u64 = (MAP_FLAG << 1) | PLAIN_FLAG;
23// pub(crate) const _MAP_MAP_FLAGS: u64 = (MAP_FLAG << 1) | MAP_FLAG;
24
25pub(crate) const DECODE_TWIN_FLAG_MASK: u64 = 0x3;
26pub(crate) const DECODE_TWIN_FLAG_MASK_BITS: u8 = 2;
27pub(crate) const DECODE_FLAG_MASK: u64 = 0x1;
28pub(crate) const DECODE_FLAG_MASK_BITS: u8 = 1;
29
30pub struct State {
31    pub(crate) chunk_map: Vec<u32>,
32}
33
34pub struct Chameleon {
35    pub state: State,
36}
37
38impl Chameleon {
39    pub fn new() -> Self {
40        Chameleon {
41            state: State { chunk_map: vec![0; 1 << CHAMELEON_HASH_BITS] },
42        }
43    }
44
45    pub fn encode(input: &[u8], output: &mut [u8]) -> Result<usize, EncodeError> {
46        let mut chameleon = Chameleon::new();
47        chameleon.encode(input, output)
48    }
49
50    pub fn decode(input: &[u8], output: &mut [u8]) -> Result<usize, DecodeError> {
51        let mut chameleon = Chameleon::new();
52        chameleon.decode(input, output)
53    }
54
55    #[inline(always)]
56    fn decode_plain(&mut self, in_buffer: &mut ReadBuffer) -> u32 {
57        let quad = in_buffer.read_u32_le();
58        let hash = (quad.wrapping_mul(CHAMELEON_HASH_MULTIPLIER) >> (BIT_SIZE_U32 - CHAMELEON_HASH_BITS)) as u16;
59        self.state.chunk_map[hash as usize] = quad;
60        quad
61    }
62
63    #[inline(always)]
64    fn decode_map(&mut self, in_buffer: &mut ReadBuffer) -> u32 {
65        let hash = in_buffer.read_u16_le();
66        let quad = self.state.chunk_map[hash as usize];
67        quad
68    }
69
70    #[unsafe(no_mangle)]
71    pub extern "C" fn chameleon_encode(input: *const u8, input_size: usize, output: *mut u8, output_size: usize) -> usize {
72        unsafe { Self::encode(from_raw_parts(input, input_size), from_raw_parts_mut(output, output_size)).unwrap_or(0) }
73    }
74
75    #[unsafe(no_mangle)]
76    pub extern "C" fn chameleon_decode(input: *const u8, input_size: usize, output: *mut u8, output_size: usize) -> usize {
77        unsafe { Self::decode(from_raw_parts(input, input_size), from_raw_parts_mut(output, output_size)).unwrap_or(0) }
78    }
79
80    #[unsafe(no_mangle)]
81    pub extern "C" fn chameleon_safe_encode_buffer_size(size: usize) -> usize {
82        Self::safe_encode_buffer_size(size)
83    }
84}
85
86impl QuadEncoder for Chameleon {
87    #[inline(always)]
88    fn encode_quad(&mut self, quad: u32, out_buffer: &mut WriteBuffer, signature: &mut WriteSignature) {
89        let hash_u16 = (quad.wrapping_mul(CHAMELEON_HASH_MULTIPLIER) >> (BIT_SIZE_U32 - CHAMELEON_HASH_BITS)) as u16;
90        let dictionary_value = &mut self.state.chunk_map[hash_u16 as usize];
91        if *dictionary_value != quad {
92            signature.push_bits(PLAIN_FLAG, FLAG_SIZE_BITS);
93            out_buffer.push(&quad.to_le_bytes());
94
95            *dictionary_value = quad;
96        } else {
97            signature.push_bits(MAP_FLAG, FLAG_SIZE_BITS);
98            out_buffer.push(&hash_u16.to_le_bytes());
99        }
100    }
101}
102
103impl Decoder for Chameleon {
104    #[inline(always)]
105    fn decode_unit(&mut self, in_buffer: &mut ReadBuffer, signature: &mut ReadSignature, out_buffer: &mut WriteBuffer) {
106        let (quad_a, quad_b) = match signature.read_bits(DECODE_TWIN_FLAG_MASK, DECODE_TWIN_FLAG_MASK_BITS) {
107            PLAIN_PLAIN_FLAGS => { (self.decode_plain(in_buffer), self.decode_plain(in_buffer)) }
108            MAP_PLAIN_FLAGS => { (self.decode_map(in_buffer), self.decode_plain(in_buffer)) }
109            PLAIN_MAP_FLAGS => { (self.decode_plain(in_buffer), self.decode_map(in_buffer)) }
110            _ => { (self.decode_map(in_buffer), self.decode_map(in_buffer)) }
111        };
112        out_buffer.push(&quad_a.to_le_bytes());
113        out_buffer.push(&quad_b.to_le_bytes());
114    }
115
116    #[inline(always)]
117    fn decode_partial_unit(&mut self, in_buffer: &mut ReadBuffer, signature: &mut ReadSignature, out_buffer: &mut WriteBuffer) -> bool {
118        for _ in 0..Self::decode_unit_size() / BYTE_SIZE_U32 {
119            let quad = match signature.read_bits(DECODE_FLAG_MASK, DECODE_FLAG_MASK_BITS) {
120                PLAIN_FLAG => {
121                    match in_buffer.remaining() {
122                        0 => { return true; }
123                        1..=3 => {
124                            out_buffer.push(in_buffer.read(in_buffer.remaining()));
125                            return true;
126                        }
127                        _ => { self.decode_plain(in_buffer) }
128                    }
129                }
130                _ => { self.decode_map(in_buffer) }
131            };
132            out_buffer.push(&quad.to_le_bytes());
133        }
134        false
135    }
136}
137
138impl Codec for Chameleon {
139    #[inline(always)]
140    fn block_size() -> usize { BYTE_SIZE_U32 * (Self::signature_significant_bytes() << 3) }
141
142    #[inline(always)]
143    fn decode_unit_size() -> usize { 8 }
144
145    #[inline(always)]
146    fn signature_significant_bytes() -> usize { 8 }
147
148    fn clear_state(&mut self) {
149        self.state.chunk_map.fill(0);
150    }
151}