reifydb_engine/function/math/aggregate/
min.rs1use std::collections::HashMap;
5
6use reifydb_core::value::column::ColumnData;
7use reifydb_type::Value;
8
9use crate::function::{AggregateFunction, AggregateFunctionContext};
10
11pub struct Min {
12 pub mins: HashMap<Vec<Value>, f64>,
13}
14
15impl Min {
16 pub fn new() -> Self {
17 Self {
18 mins: HashMap::new(),
19 }
20 }
21}
22
23impl AggregateFunction for Min {
24 fn aggregate(&mut self, ctx: AggregateFunctionContext) -> crate::Result<()> {
25 let column = ctx.column;
26 let groups = &ctx.groups;
27
28 match &column.data() {
29 ColumnData::Float8(container) => {
30 for (group, indices) in groups.iter() {
31 let min_val = indices
32 .iter()
33 .filter_map(|&i| container.get(i))
34 .min_by(|a, b| a.partial_cmp(b).unwrap());
35
36 if let Some(min_val) = min_val {
37 self.mins
38 .entry(group.clone())
39 .and_modify(|v| *v = f64::min(*v, *min_val))
40 .or_insert(*min_val);
41 }
42 }
43 Ok(())
44 }
45 ColumnData::Float4(container) => {
46 for (group, indices) in groups.iter() {
47 let min_val = indices
48 .iter()
49 .filter_map(|&i| container.get(i))
50 .min_by(|a, b| a.partial_cmp(b).unwrap());
51
52 if let Some(min_val) = min_val {
53 self.mins
54 .entry(group.clone())
55 .and_modify(|v| *v = f64::min(*v, *min_val as f64))
56 .or_insert(*min_val as f64);
57 }
58 }
59 Ok(())
60 }
61 ColumnData::Int2(container) => {
62 for (group, indices) in groups.iter() {
63 let min_val = indices
64 .iter()
65 .filter_map(|&i| container.get(i))
66 .min_by(|a, b| a.partial_cmp(b).unwrap());
67
68 if let Some(min_val) = min_val {
69 self.mins
70 .entry(group.clone())
71 .and_modify(|v| *v = f64::min(*v, *min_val as f64))
72 .or_insert(*min_val as f64);
73 }
74 }
75 Ok(())
76 }
77 ColumnData::Int4(container) => {
78 for (group, indices) in groups.iter() {
79 let min_val = indices
80 .iter()
81 .filter_map(|&i| container.get(i))
82 .min_by(|a, b| a.partial_cmp(b).unwrap());
83
84 if let Some(min_val) = min_val {
85 self.mins
86 .entry(group.clone())
87 .and_modify(|v| *v = f64::min(*v, *min_val as f64))
88 .or_insert(*min_val as f64);
89 }
90 }
91 Ok(())
92 }
93 _ => unimplemented!(),
94 }
95 }
96
97 fn finalize(&mut self) -> crate::Result<(Vec<Vec<Value>>, ColumnData)> {
98 let mut keys = Vec::with_capacity(self.mins.len());
99 let mut data = ColumnData::float8_with_capacity(self.mins.len());
100
101 for (key, min) in std::mem::take(&mut self.mins) {
102 keys.push(key);
103 data.push_value(Value::float8(min));
104 }
105
106 Ok((keys, data))
107 }
108}