reifydb_engine/function/math/aggregate/
max.rs

1// Copyright (c) reifydb.com 2025
2// This file is licensed under the AGPL-3.0-or-later, see license.md file
3
4use 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}