tsfile_writer/writer/
statistics.rs

1use crate::writer::utils::size_var_u32;
2use crate::writer::{
3    write_var_u32, IoTDBValue, PositionedWrite, Serializable, TSDataType, TsFileError,
4};
5
6#[derive(Clone, Debug)]
7#[allow(clippy::upper_case_acronyms)]
8pub enum Statistics {
9    INT32(StatisticsStruct<i32, i64>),
10    INT64(StatisticsStruct<i64, f64>),
11    FLOAT(StatisticsStruct<f32, f64>),
12}
13
14impl Statistics {
15    pub(crate) fn count(&self) -> u32 {
16        match self {
17            Statistics::INT32(s) => s.count,
18            Statistics::INT64(s) => s.count,
19            Statistics::FLOAT(s) => s.count,
20        }
21    }
22    pub(crate) fn get_serialized_size(&self) -> u32 {
23        match self {
24            Statistics::INT32(s) => s.get_serialized_size(),
25            Statistics::INT64(s) => s.get_serialized_size(),
26            Statistics::FLOAT(s) => s.get_serialized_size(),
27        }
28    }
29}
30
31impl Statistics {
32    pub(crate) fn update(&mut self, timestamp: i64, value: &IoTDBValue) {
33        match (self, value) {
34            (Statistics::INT32(s), IoTDBValue::INT(v)) => s.update(timestamp, *v),
35            (Statistics::INT64(s), IoTDBValue::LONG(v)) => s.update(timestamp, *v),
36            (Statistics::FLOAT(s), IoTDBValue::FLOAT(v)) => s.update(timestamp, *v),
37            _ => todo!(),
38        }
39    }
40}
41
42impl Statistics {
43    pub(crate) fn merge(&mut self, other: &Statistics) {
44        match self {
45            Statistics::INT32(s) => match other {
46                Statistics::INT32(othr) => s.merge(othr),
47                _ => {
48                    panic!("...")
49                }
50            },
51            Statistics::INT64(s) => match other {
52                Statistics::INT64(othr) => s.merge(othr),
53                _ => {
54                    panic!("...")
55                }
56            },
57            Statistics::FLOAT(s) => match other {
58                Statistics::FLOAT(othr) => s.merge(othr),
59                _ => {
60                    panic!("...")
61                }
62            },
63        }
64    }
65}
66
67impl Statistics {
68    pub fn new(data_type: TSDataType) -> Statistics {
69        match data_type {
70            TSDataType::INT32 => Statistics::INT32(StatisticsStruct::<i32, i64>::new()),
71            TSDataType::INT64 => Statistics::INT64(StatisticsStruct::<i64, f64>::new()),
72            TSDataType::FLOAT => Statistics::FLOAT(StatisticsStruct::<f32, f64>::new()),
73        }
74    }
75}
76
77impl Serializable for Statistics {
78    fn serialize(&self, file: &mut dyn PositionedWrite) -> Result<(), TsFileError> {
79        match self {
80            Statistics::INT32(s) => s.serialize(file),
81            Statistics::INT64(s) => s.serialize(file),
82            Statistics::FLOAT(s) => s.serialize(file),
83        }
84    }
85}
86
87#[derive(Copy, Clone, Debug)]
88pub struct StatisticsStruct<T, S> {
89    ts_first: i64,
90    ts_last: i64,
91
92    min_value: T,
93    max_value: T,
94    first_value: T,
95    last_value: T,
96    count: u32,
97    sum_value: S,
98}
99
100impl StatisticsStruct<i64, f64> {
101    pub(crate) fn get_serialized_size(&self) -> u32 {
102        // return ReadWriteForEncodingUtils.uVarIntSize(count) // count
103        // + 16 // startTime, endTime
104        // + getStatsSize();
105        // 40 -> stat size for int
106        size_var_u32(self.count) as u32 + 16 + 40
107    }
108}
109
110impl StatisticsStruct<i32, i64> {
111    pub(crate) fn get_serialized_size(&self) -> u32 {
112        size_var_u32(self.count) as u32 + 16 + 24
113    }
114}
115
116impl StatisticsStruct<f32, f64> {
117    pub(crate) fn get_serialized_size(&self) -> u32 {
118        size_var_u32(self.count) as u32 + 16 + 24
119    }
120}
121
122macro_rules! implement_statistics {
123    ( $type:ty, $sum:ty ) => {
124        impl StatisticsStruct<$type, $sum> {
125            pub(crate) fn new() -> StatisticsStruct<$type, $sum> {
126                StatisticsStruct {
127                    ts_first: i64::MAX,
128                    ts_last: i64::MIN,
129                    min_value: <$type>::MAX,
130                    max_value: <$type>::MIN,
131                    first_value: 0 as $type,
132                    last_value: 0 as $type,
133                    count: 0,
134                    sum_value: 0 as $sum,
135                }
136            }
137
138            pub(crate) fn merge(&mut self, statistics: &StatisticsStruct<$type, $sum>) {
139                if statistics.ts_first < self.ts_first {
140                    self.ts_first = statistics.ts_first;
141                    self.first_value = statistics.first_value;
142                }
143                if statistics.ts_last > self.ts_last {
144                    self.ts_last = statistics.ts_last;
145                    self.last_value = statistics.last_value;
146                }
147                if statistics.max_value > self.max_value {
148                    self.max_value = statistics.max_value;
149                }
150                if statistics.min_value < self.min_value {
151                    self.min_value = statistics.min_value;
152                }
153                self.count += statistics.count;
154                self.sum_value += statistics.sum_value;
155            }
156
157            pub(crate) fn update(&mut self, timestamp: i64, value: $type) {
158                if timestamp < self.ts_first {
159                    self.ts_first = timestamp;
160                    self.first_value = value;
161                }
162                if timestamp > self.ts_last {
163                    self.ts_last = timestamp;
164                    self.last_value = value;
165                }
166                if value < self.min_value {
167                    self.min_value = value;
168                }
169                if value > self.max_value {
170                    self.max_value = value;
171                }
172                self.count += 1;
173                self.sum_value += value as $sum;
174            }
175        }
176
177        impl Serializable for StatisticsStruct<$type, $sum> {
178            fn serialize(&self, file: &mut dyn PositionedWrite) -> Result<(), TsFileError> {
179                // Header for statistics
180                write_var_u32(self.count as u32, file)?;
181                file.write_all(&self.ts_first.to_be_bytes())?;
182                file.write_all(&self.ts_last.to_be_bytes())?;
183
184                file.write_all(&self.min_value.to_be_bytes())?;
185                file.write_all(&self.max_value.to_be_bytes())?;
186                file.write_all(&self.first_value.to_be_bytes())?;
187                file.write_all(&self.last_value.to_be_bytes())?;
188                file.write_all(&self.sum_value.to_be_bytes())?;
189
190                Ok(())
191            }
192        }
193    };
194}
195
196implement_statistics!(i32, i64);
197implement_statistics!(i64, f64);
198implement_statistics!(f32, f64);
199// TODO Implement / use
200// implement_statistics!(f64);