tsfile_writer/writer/encoding/
time_encoder.rs

1use crate::writer::encoding::Encoder;
2use crate::writer::{IoTDBValue, TsFileError};
3use std::cmp::max;
4use std::io::Write;
5
6impl TryFrom<&IoTDBValue> for i64 {
7    type Error = TsFileError;
8
9    fn try_from(value: &IoTDBValue) -> Result<Self, Self::Error> {
10        match value {
11            IoTDBValue::LONG(v) => Ok(*v),
12            _ => Err(TsFileError::WrongTypeForSeries),
13        }
14    }
15}
16
17impl TryFrom<&IoTDBValue> for i32 {
18    type Error = TsFileError;
19
20    fn try_from(value: &IoTDBValue) -> Result<Self, Self::Error> {
21        match value {
22            IoTDBValue::INT(v) => Ok(*v),
23            _ => Err(TsFileError::WrongTypeForSeries),
24        }
25    }
26}
27
28macro_rules! ts2diff_encoder {
29    ( $name:ident, $type:ty, $num_bits:expr ) => {
30        pub struct $name {
31            first_value: Option<$type>,
32            min_delta: $type,
33            previous_value: $type,
34            values: Vec<$type>,
35            buffer: Vec<u8>,
36        }
37
38        impl Encoder for $name {
39            fn write(&mut self, value: &IoTDBValue) -> Result<(), TsFileError> {
40                let value = value.try_into()?;
41                match self.first_value {
42                    None => {
43                        self.first_value = Some(value);
44                        self.previous_value = value;
45                    }
46                    Some(_) => {
47                        // calc delta
48                        let delta = value - self.previous_value;
49                        // If delta is min, store it
50                        if delta < self.min_delta {
51                            self.min_delta = delta;
52                        }
53                        // store delta
54                        self.values.push(delta);
55                        self.previous_value = value;
56                    }
57                }
58                if self.values.len() == 128 {
59                    self.flush();
60                }
61                Ok(())
62            }
63
64            fn size(&mut self) -> u32 {
65                self.buffer.len() as u32
66            }
67            fn get_max_byte_size(&self) -> u32 {
68                // The meaning of 24 is: index(4)+width(4)+minDeltaBase(8)+firstValue(8)
69                (24 + self.values.len() * $num_bits / 8) as u32
70            }
71
72            fn serialize(&mut self, buffer: &mut Vec<u8>) {
73                // Flush
74                self.flush();
75                // Copy internal buffer to out buffer
76                buffer.write_all(&self.buffer);
77            }
78
79            fn reset(&mut self) {
80                // Now reset everything
81                self.first_value = None;
82                self.min_delta = <$type>::MAX;
83                self.previous_value = <$type>::MAX;
84                self.values.clear();
85                self.buffer.clear();
86            }
87        }
88
89        impl $name {
90            pub(crate) fn new() -> $name {
91                Self {
92                    first_value: None,
93                    min_delta: <$type>::MAX,
94                    previous_value: <$type>::MAX,
95                    values: vec![],
96                    buffer: vec![],
97                }
98            }
99
100            fn get_value_width(v: $type) -> u32 {
101                $num_bits - v.leading_zeros()
102            }
103
104            fn calculate_bit_widths_for_delta_block_buffer(
105                &mut self,
106                delta_block_buffer: &[$type],
107            ) -> u32 {
108                let mut width = 0;
109
110                for i in 0..delta_block_buffer.len() {
111                    let v = *delta_block_buffer.get(i).expect("");
112                    let value_width = Self::get_value_width(v);
113                    width = max(width, value_width)
114                }
115
116                width
117            }
118
119            fn flush(&mut self) {
120                if self.first_value == None {
121                    return;
122                }
123                // Preliminary calculations
124                let mut delta_block_buffer: Vec<$type> = vec![];
125
126                for delta in &self.values {
127                    delta_block_buffer.push(delta - self.min_delta);
128                }
129
130                let write_width =
131                    self.calculate_bit_widths_for_delta_block_buffer(&delta_block_buffer);
132
133                // Write Header
134                // Write number of entries
135                let number_of_entries: u32 = self.values.len() as u32;
136                self.buffer.write_all(&number_of_entries.to_be_bytes());
137                // Write "write-width"
138                self.buffer.write_all(&write_width.to_be_bytes());
139
140                // Min Delta Base
141                self.buffer.write_all(&self.min_delta.to_be_bytes());
142                // First Value
143                self.buffer
144                    .write_all(&self.first_value.expect("").to_be_bytes());
145                // End Header
146
147                // now we can drop the long-to-bytes values here
148                let mut payload_buffer = vec![];
149                for (i, buffer) in delta_block_buffer.iter().enumerate() {
150                    Self::to_bytes(
151                        *buffer,
152                        &mut payload_buffer,
153                        (i * write_width as usize) as usize,
154                        write_width,
155                    );
156                }
157
158                // Copy over to "real" buffer
159                self.buffer.write_all(payload_buffer.as_slice());
160
161                // Now reset everything
162                self.values.clear();
163                self.first_value = None;
164                self.previous_value = 0;
165                self.min_delta = <$type>::MAX;
166            }
167        }
168    };
169}
170
171ts2diff_encoder!(LongTs2DiffEncoder, i64, 64);
172ts2diff_encoder!(IntTs2DiffEncoder, i32, 32);
173
174impl LongTs2DiffEncoder {
175    #[allow(unused_variables)]
176    pub(crate) fn to_bytes(number: i64, result: &mut Vec<u8>, pos: usize, width: u32) {
177        let mut cnt = (pos & 0x07) as u8;
178        let mut index = pos >> 3;
179
180        let mut my_width = width as u8;
181        let mut my_number = number;
182        while my_width > 0 {
183            let m = match my_width + cnt >= 8 {
184                true => 8 - cnt,
185                false => my_width,
186            };
187            my_width -= m;
188            let old_count = cnt;
189            cnt += m;
190            let y = (number >> my_width) as u8;
191            let y = y << (8 - cnt);
192
193            // We need a mask like that
194            // 0...0 (old-cnt-times) 1...1 (8-old-cnt-times)
195            let mut new_mask: u8 = 0;
196            for i in 0..(8 - old_count) {
197                new_mask |= 1 << i;
198            }
199            new_mask = !new_mask;
200
201            if index <= result.len() {
202                result.resize(index + 1, 0);
203            }
204            let masked_input = result[index] & new_mask;
205            let new_input = masked_input | y;
206            result[index] = new_input;
207            // Remove the written numbers
208            let mut mask: i64 = 0;
209            for i in 0..my_width {
210                mask |= 1 << i;
211            }
212            my_number &= mask;
213
214            if cnt == 8 {
215                index += 1;
216                cnt = 0;
217            }
218        }
219    }
220}
221
222impl IntTs2DiffEncoder {
223    pub(crate) fn to_bytes(number: i32, result: &mut Vec<u8>, pos: usize, width: u32) {
224        let mut cnt = (pos & 0x07) as u8;
225        let mut index = pos >> 3;
226
227        let mut my_width = width as u8;
228        let mut my_number = number;
229
230        while my_width > 0 {
231            let m = if my_width + cnt >= 8 {
232                8 - cnt
233            } else {
234                my_width
235            };
236            my_width -= m;
237            let mut mask = (1 << (8 - cnt)) as i32;
238            cnt += m;
239            let mut y = (my_number >> my_width) as u8;
240            y <<= 8 - cnt;
241            mask = !(mask - (1 << (8 - cnt)) as i32);
242
243            if index <= result.len() {
244                result.resize(index + 1, 0);
245            }
246
247            result[index] = result[index] & (mask as u8) | y;
248            my_number &= !(-1 << my_width);
249            if cnt == 8 {
250                index += 1;
251                cnt = 0;
252            }
253        }
254    }
255}
256
257#[cfg(test)]
258mod tests {
259    use crate::writer::encoding::time_encoder::{IntTs2DiffEncoder, LongTs2DiffEncoder};
260
261    #[test]
262    fn test_long_to_bytes() {
263        let mut result = vec![];
264        let width = 4;
265        LongTs2DiffEncoder::to_bytes(1, &mut result, width * 0, width as u32);
266        LongTs2DiffEncoder::to_bytes(1, &mut result, width * 1, width as u32);
267        LongTs2DiffEncoder::to_bytes(1, &mut result, width * 2, width as u32);
268
269        assert_eq!(result, [0b00010001, 0b00010000])
270    }
271
272    #[test]
273    fn test_long_to_bytes_2() {
274        let mut result = vec![];
275        let width = 7;
276        LongTs2DiffEncoder::to_bytes(0b0000001, &mut result, width * 0, width as u32);
277        LongTs2DiffEncoder::to_bytes(0b0000001, &mut result, width * 1, width as u32);
278        LongTs2DiffEncoder::to_bytes(0b0000001, &mut result, width * 2, width as u32);
279
280        assert_eq!(result, [0b00000010, 0b00000100, 0b00001000])
281    }
282
283    #[test]
284    fn test_long_to_bytes_3() {
285        let mut result = vec![];
286        let width = 7;
287        LongTs2DiffEncoder::to_bytes(0, &mut result, width * 0, width as u32);
288        LongTs2DiffEncoder::to_bytes(81, &mut result, width * 1, width as u32);
289
290        assert_eq!(result, [1, 68])
291    }
292
293    #[test]
294    fn test_int_to_bytes() {
295        let mut result = vec![];
296        let width = 4;
297        IntTs2DiffEncoder::to_bytes(1, &mut result, width * 0, width as u32);
298        IntTs2DiffEncoder::to_bytes(1, &mut result, width * 1, width as u32);
299        IntTs2DiffEncoder::to_bytes(1, &mut result, width * 2, width as u32);
300
301        assert_eq!(result, [0b00010001, 0b00010000])
302    }
303}