using MoShiro.Backend.Analysis;
namespace MoShiro.Backend.Application;
/// 把源行合并成查询步长的桶:计数相加、直方图逐桶相加,所以结果是精确的,不是各点的平均。
public sealed class BucketedRows
{
public BucketedRows(long[] t, MetricSet?[] sets, int[] rowCounts)
{
T = t;
Sets = sets;
RowCounts = rowCounts;
}
public long[] T { get; }
public MetricSet?[] Sets { get; }
/// 每个桶合并了多少个源行(用来估算持续时长和覆盖率)。
public int[] RowCounts { get; }
public int TotalRows => RowCounts.Sum();
public static BucketedRows Create(IReadOnlyList rows, QueryRange range)
{
int n = range.Points;
long[] t = new long[n];
for (int i = 0; i < n; i++)
{
t[i] = range.FromMs + (i * range.StepMs);
}
var sets = new MetricSet?[n];
int[] counts = new int[n];
foreach (SourceRow row in rows)
{
long index = (row.Start - range.FromMs) / range.StepMs;
if (row.Start < range.FromMs || index >= n)
{
continue;
}
int i = (int)index;
if (sets[i] is null)
{
sets[i] = row.Set.Clone();
}
else
{
sets[i]!.Merge(row.Set);
}
counts[i]++;
}
return new BucketedRows(t, sets, counts);
}
/// 整个时间段的精确合并。
public MetricSet Merge()
{
var merged = new MetricSet();
foreach (MetricSet? set in Sets)
{
if (set is not null)
{
merged.Merge(set);
}
}
return merged;
}
}