MCPcopy Create free account
hub / github.com/NodeDB-Lab/nodedb / per_row_aggregate

Function per_row_aggregate

nodedb-query/src/window/aggregate.rs:56–107  ·  view source on GitHub ↗

Per-row frame evaluator. For each row position `pos` in the partition: 1. Resolve the concrete `[start_idx, end_idx]` frame slice via `evaluate_frame_bounds`. 2. Aggregate `field` over `indices[start_idx..=end_idx]`. 3. Write the result back under `spec.alias`.

(
    rows: &mut [(String, serde_json::Value)],
    indices: &[usize],
    spec: &WindowFuncSpec,
    field: &str,
)

Source from the content-addressed store, hash-verified

54/// 2. Aggregate `field` over `indices[start_idx..=end_idx]`.
55/// 3. Write the result back under `spec.alias`.
56fn per_row_aggregate(
57 rows: &mut [(String, serde_json::Value)],
58 indices: &[usize],
59 spec: &WindowFuncSpec,
60 field: &str,
61) {
62 let len = indices.len();
63 if len == 0 {
64 return;
65 }
66
67 // Extract order-by values for RANGE numeric offsets.
68 let order_expr = spec.order_by.first().map(|(expr, _)| expr);
69 let order_values: Vec<serde_json::Value> = indices
70 .iter()
71 .map(|&i| {
72 order_expr
73 .map(|expr| super::helpers::eval_expr_on_json(expr, &rows[i].1))
74 .unwrap_or(serde_json::Value::Null)
75 })
76 .collect();
77
78 // Peer groups needed for GROUPS mode (and for RANGE CurrentRow peer
79 // awareness — reused from the frame module which handles both).
80 let peer_groups: Vec<usize> = if spec.frame.mode == "groups" {
81 build_peer_groups(&order_values)
82 } else {
83 Vec::new()
84 };
85
86 // Pre-collect all numeric values to avoid repeated borrow issues.
87 let all_vals: Vec<Option<f64>> = indices
88 .iter()
89 .map(|&i| as_f64(&get_field(&rows[i].1, field)))
90 .collect();
91
92 // We need to write into `rows` after computing each result; collect
93 // results first so we only borrow `rows` immutably during computation.
94 let results: Vec<serde_json::Value> = (0..len)
95 .map(|pos| {
96 let (start_idx, end_idx) =
97 evaluate_frame_bounds(&spec.frame, pos, len, &order_values, &peer_groups);
98
99 aggregate_slice(&all_vals, indices, rows, field, spec, start_idx, end_idx)
100 })
101 .collect();
102
103 for (pos, result) in results.into_iter().enumerate() {
104 let row_idx = indices[pos];
105 set_window_col(&mut rows[row_idx].1, &spec.alias, result);
106 }
107}
108
109/// Aggregate `field` over the slice `indices[start_idx..=end_idx]`.
110fn aggregate_slice(

Callers 1

apply_aggregate_windowFunction · 0.85

Calls 11

eval_expr_on_jsonFunction · 0.85
build_peer_groupsFunction · 0.85
as_f64Function · 0.85
get_fieldFunction · 0.85
evaluate_frame_boundsFunction · 0.85
aggregate_sliceFunction · 0.85
set_window_colFunction · 0.85
firstMethod · 0.80
collectMethod · 0.80
lenMethod · 0.45
iterMethod · 0.45

Tested by

no test coverage detected