reifydb_core/value/column/view/
group_by.rs1use std::collections::HashMap;
5
6use reifydb_type::{Value, diagnostic::engine, error};
7
8use crate::value::column::{ColumnData, Columns};
9
10pub type GroupKey = Vec<Value>;
11pub type GroupByView = HashMap<GroupKey, Vec<usize>>;
12
13impl<'a> Columns<'a> {
14 pub fn group_by_view(&self, keys: &[&str]) -> crate::Result<GroupByView> {
15 let row_count = self.first().map_or(0, |c| c.data().len());
16
17 let mut key_columns: Vec<&ColumnData> = Vec::with_capacity(keys.len());
18
19 for &key in keys {
20 let column = self
21 .iter()
22 .find(|c| c.name() == key)
23 .ok_or_else(|| error!(engine::frame_error(format!("Column '{}' not found", key))))?;
24 key_columns.push(&column.data());
25 }
26
27 let mut result = GroupByView::new();
28
29 for row_numberx in 0..row_count {
30 let mut values = Vec::with_capacity(keys.len());
31
32 for col in &key_columns {
33 let value = col.get_value(row_numberx);
34 values.push(value);
35 }
36
37 result.entry(values).or_default().push(row_numberx);
38 }
39
40 Ok(result)
41 }
42}