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

Function decode_aggregate_response

nodedb/src/event/alert/executor.rs:197–257  ·  view source on GitHub ↗

Decode the Data Plane's MessagePack response into (group_key, agg_value) pairs. The response is an `rmpv::Value::Array` of `Map` rows. Each row contains the group-by columns and the aggregate value (e.g., `"avg_temperature"`).

(
    payload: &[u8],
    group_by: &[String],
    agg_func: &str,
)

Source from the content-addressed store, hash-verified

195/// The response is an `rmpv::Value::Array` of `Map` rows. Each row contains
196/// the group-by columns and the aggregate value (e.g., `"avg_temperature"`).
197fn decode_aggregate_response(
198 payload: &[u8],
199 group_by: &[String],
200 agg_func: &str,
201) -> crate::Result<Vec<(String, f64)>> {
202 if payload.is_empty() {
203 return Ok(Vec::new());
204 }
205
206 let value: rmpv::Value =
207 rmpv::decode::read_value(&mut &payload[..]).map_err(|e| crate::Error::Internal {
208 detail: format!("decode aggregate response: {e}"),
209 })?;
210
211 let rows = match value {
212 rmpv::Value::Array(rows) => rows,
213 _ => return Ok(Vec::new()),
214 };
215
216 let mut results = Vec::with_capacity(rows.len());
217 for row in &rows {
218 let rmpv::Value::Map(fields) = row else {
219 continue;
220 };
221
222 // Extract group key: concatenate group-by column values.
223 let group_key = if group_by.is_empty() {
224 "__all__".to_string()
225 } else {
226 group_by
227 .iter()
228 .filter_map(|col| {
229 fields.iter().find_map(|(k, v)| {
230 if k.as_str().is_some_and(|s| s == col) {
231 Some(v.as_str().unwrap_or("").to_string())
232 } else {
233 None
234 }
235 })
236 })
237 .collect::<Vec<_>>()
238 .join("\0")
239 };
240
241 // Extract aggregate value by matching the agg key pattern: "{func}_{column}".
242 let agg_value = fields.iter().find_map(|(k, v)| {
243 let key_str = k.as_str()?;
244 if key_str.starts_with(agg_func) {
245 v.as_f64().or_else(|| v.as_i64().map(|i| i as f64))
246 } else {
247 None
248 }
249 });
250
251 if let Some(val) = agg_value {
252 results.push((group_key, val));
253 }
254 }

Callers 4

execute_aggregate_scanFunction · 0.85
decode_empty_payloadFunction · 0.85
decode_grouped_responseFunction · 0.85
decode_no_group_responseFunction · 0.85

Calls 10

to_stringMethod · 0.80
joinMethod · 0.80
read_valueFunction · 0.50
is_emptyMethod · 0.45
lenMethod · 0.45
iterMethod · 0.45
as_strMethod · 0.45
as_f64Method · 0.45
as_i64Method · 0.45
pushMethod · 0.45

Tested by 3

decode_empty_payloadFunction · 0.68
decode_grouped_responseFunction · 0.68
decode_no_group_responseFunction · 0.68