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 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 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