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