2018-09-10 14:19:22 -07:00

50 lines
1.6 KiB
TypeScript

/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
import { AggregatedMetric, Metric, MetricGroup } from './interfaces';
// Prefers to keep v1 when both are equal.
export const max = (v1: number, v2: number) => v2 > v1 ? v2 : v1;
export const cumulativeMovingAverage = (acc: number, val: number, accSize: number) =>
(val + accSize * acc) / (accSize + 1);
export const aggregateMetrics = (
m1: Metric | AggregatedMetric,
m2: Metric | AggregatedMetric,
): AggregatedMetric => {
if ((m1.name != m2.name) || (m1.unit != m2.unit)) {
throw new Error('Cannot aggregate metrics with different names or units:');
}
const m1Values = m1.componentValues ? m1.componentValues : [m1.value];
const m2Values = m2.componentValues ? m2.componentValues : [m2.value];
return {
name: m1.name,
unit: m1.unit,
// m1.value already holds an average if it has component values.
value: m2Values.reduce(
(acc, val, idx) => cumulativeMovingAverage(acc, val, idx + m1Values.length),
m1.value,
),
componentValues: [...m1Values, ...m2Values],
};
};
export const aggregateMetricGroups = (g1: MetricGroup, g2: MetricGroup): MetricGroup => {
if (g1.name != g2.name || g1.metrics.length != g2.metrics.length) {
throw new Error('Cannot aggregate metric groups with different names.');
}
return {
name: g1.name,
metrics: g1.metrics.map((_, idx) => aggregateMetrics(g1.metrics[idx], g2.metrics[idx])),
};
};