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; } }