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