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