Files
MoShiro/backend/shared/MoShiro.Protocol/Raw/StreamBuilder.cs
T
justme 2e146d4da7
ci/woodpecker/push/main-amd64-build Pipeline was successful
refactor!: rename the project from Monitor to MoShiro [CI]
Namespaces, assemblies, solution, binaries, images, systemd units, config paths, environment variables, protocol methods and the Linux user are all renamed. Breaking: existing databases, node identities and installed units must be recreated.
2026-10-07 02:03:25 +08:00

59 lines
1.8 KiB
C#

namespace MoShiro.Protocol;
/// <summary>按 <see cref="StreamSpec"/> 逐行构造一个 <see cref="RawStream"/>(用于测试、模拟器和离线工具,不用于节点热路径)。</summary>
public sealed class StreamBuilder
{
private readonly StreamSpec _spec;
private readonly List<long>[] _values;
private readonly List<bool>[] _valid;
public StreamBuilder(StreamSpec spec)
{
_spec = spec;
_values = new List<long>[spec.Columns.Count];
_valid = new List<bool>[spec.Columns.Count];
for (int i = 0; i < _values.Length; i++)
{
_values[i] = [];
_valid[i] = [];
}
}
public int Count { get; private set; }
/// <summary>添加一行;<c>null</c> 表示缺失值(只允许用于可空列)。</summary>
public StreamBuilder Add(params long?[] row)
{
if (row.Length != _values.Length)
{
throw new ArgumentException($"stream {_spec.Name} expects {_values.Length} values, got {row.Length}", nameof(row));
}
for (int i = 0; i < row.Length; i++)
{
if (row[i] is null && !_spec.Columns[i].Nullable)
{
throw new ArgumentException($"column {_spec.Columns[i].Name} is not nullable", nameof(row));
}
_values[i].Add(row[i] ?? 0);
_valid[i].Add(row[i] is not null);
}
Count++;
return this;
}
public RawStream Build()
{
var columns = new List<RawColumn>(_values.Length);
for (int i = 0; i < _values.Length; i++)
{
ColumnSpec spec = _spec.Columns[i];
columns.Add(new RawColumn(spec.Name, spec.Type, spec.Enc, spec.Nullable, spec.Role, [.. _values[i]], spec.Nullable ? [.. _valid[i]] : null));
}
return new RawStream(_spec.Name, Count, columns);
}
}