use crate::metrics::MetricRecord;
use crate::aggregation::{AggregateFunction, GroupBy, build_aggregate_query};
use tonic::Status;
const METRIC_VALUE_COLUMNS: [&str; 3] = [
"value_running_window_sum",
"value_running_window_avg",
"value_running_window_count"
];
pub fn apply_function(function: AggregateFunction, metrics: &[MetricRecord]) -> Result<f64, Status> {
if metrics.is_empty() {
return Ok(0.0);
}
match function {
AggregateFunction::Sum => Ok(metrics.iter().map(|m| m.value_running_window_sum).sum()),
AggregateFunction::Avg => {
let sum: f64 = metrics.iter().map(|m| m.value_running_window_avg).sum();
Ok(sum / metrics.len() as f64)
},
AggregateFunction::Min => Ok(metrics
.iter()
.map(|m| m.value_running_window_sum)
.fold(f64::INFINITY, f64::min)),
AggregateFunction::Max => Ok(metrics
.iter()
.map(|m| m.value_running_window_sum)
.fold(f64::NEG_INFINITY, f64::max)),
AggregateFunction::Count => Ok(metrics.len() as f64),
}
}
pub fn build_metrics_query(
function: AggregateFunction,
group_by: &GroupBy,
from_timestamp: i64,
to_timestamp: Option<i64>,
) -> String {
let columns = METRIC_VALUE_COLUMNS.iter()
.map(|&c| c.to_string())
.collect::<Vec<_>>();
let column_refs: Vec<&str> = columns.iter().map(|s| s.as_str()).collect();
build_aggregate_query(
"metrics",
function,
group_by,
&column_refs,
Some(from_timestamp),
to_timestamp,
)
}