tsfile_writer/writer/encoding/
time_encoder.rs1use 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 let delta = value - self.previous_value;
49 if delta < self.min_delta {
51 self.min_delta = delta;
52 }
53 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 (24 + self.values.len() * $num_bits / 8) as u32
70 }
71
72 fn serialize(&mut self, buffer: &mut Vec<u8>) {
73 self.flush();
75 buffer.write_all(&self.buffer);
77 }
78
79 fn reset(&mut self) {
80 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 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 let number_of_entries: u32 = self.values.len() as u32;
136 self.buffer.write_all(&number_of_entries.to_be_bytes());
137 self.buffer.write_all(&write_width.to_be_bytes());
139
140 self.buffer.write_all(&self.min_delta.to_be_bytes());
142 self.buffer
144 .write_all(&self.first_value.expect("").to_be_bytes());
145 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 self.buffer.write_all(payload_buffer.as_slice());
160
161 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 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 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}