Class Metadata
- Namespace
- DatabentoDotNet.Dbn
- Assembly
- DatabentoDotNet.Dbn.dll
The header that opens every DBN file and every live DBN stream: what the data is, what range it covers, and how its symbols resolve.
public sealed class Metadata
- Inheritance
-
Metadata
- Inherited Members
Examples
using var decoder = new DbnDecoder(File.OpenRead("data.dbn.zst"));
// Null only for a fragment opened with skipMetadata — a stream that has no metadata block.
Metadata metadata = decoder.Metadata!;
Console.WriteLine($"DBN v{metadata.Version} {metadata.Dataset}");
Console.WriteLine($"schema {(metadata.Schema is { } schema ? schema.ToWireString() : "mixed")}");
Console.WriteLine($"from {DbnTime.ToInstant(metadata.Start)}");
// End and Limit are both absent as null here, though the wire spells their two sentinels
// differently — UndefTimestamp for one, NullLimit for the other.
if (metadata.End is { } end)
{
Console.WriteLine($"to {DbnTime.ToInstant(end)}");
}
// The symbol mappings are what a symbol map is built from.
TsSymbolMap symbols = TsSymbolMap.FromMetadata(metadata);
Remarks
A class, not a struct, because it owns heap data — four lists whose contents are strings — so there is no value-type win to be had, and copying one by value would copy references anyway. This is also the one place in the codec where allocation is fine: metadata is decoded once per stream, ahead of the first record, and never on the per-record path the zero-copy rule is about.
Construction is by object initializer with required properties, not by a builder.
Upstream needs a generic type-state builder to make "you must set dataset, schema, start,
stype_in and stype_out" a compile-time error; C# has required for exactly that, and it
costs no extra type.
Two 64-bit "unset" sentinels that are not the same. End is absent when the wire holds UndefTimestamp; Limit is absent when the wire holds NullLimit, which is zero. Both surface here as null, so callers never have to remember which is which.
Properties
Dataset
The dataset code, for example GLBX.MDP3.
public required string Dataset { get; init; }
Property Value
End
UNIX nanoseconds: the query end, or the last record's timestamp when the file was split. null for an open-ended query.
public ulong? End { get; init; }
Property Value
Remarks
A raw zero on the wire also decodes to null, matching upstream, which treats both zero and UndefTimestamp as "no end". This is the one metadata field whose round-trip is not byte-identical, because re-encoding null always writes UndefTimestamp; upstream has the same behaviour, no stream in the conformance corpus carries a zero here, and both spellings mean the same thing to a reader.
Limit
The maximum number of records the query asked for, or null when it was unlimited.
public ulong? Limit { get; init; }
Property Value
Remarks
Zero and null are the same thing on the wire — 0 is the
"no limit" sentinel — so a zero set here encodes as unlimited and decodes back as
null.
Mappings
Each requested symbol paired with the dated intervals it resolved over. Never null.
public IReadOnlyList<SymbolMapping> Mappings { get; init; }
Property Value
NotFound
Symbols that failed to resolve on every day of the query range. Never null.
public IReadOnlyList<string> NotFound { get; init; }
Property Value
Partial
Symbols that failed to resolve on at least one day of the query range. Never null.
public IReadOnlyList<string> Partial { get; init; }
Property Value
Schema
The record schema every record in the stream conforms to, or null when the stream may mix record types — which is the normal case for live data.
public Schema? Schema { get; init; }
Property Value
Start
UNIX nanoseconds: the query start, or the first record's timestamp when the file was split.
public required ulong Start { get; init; }
Property Value
Remarks
Raw nanoseconds, matching the wire and the record structs. Convert with
ToInstant(ulong), which handles
UndefTimestamp; NodaTime's Instant represents a DBN
timestamp exactly, where a BCL tick of 100 ns cannot.
StypeIn
The input symbology the query's symbols were expressed in, or null when the stream mixes several — again the normal case for live data.
public SType? StypeIn { get; init; }
Property Value
StypeOut
The output symbology symbols resolve to. Never absent.
public required SType StypeOut { get; init; }
Property Value
SymbolCstrLength
The width in bytes of every fixed-length symbol field in this stream, NUL terminator included.
public required int SymbolCstrLength { get; init; }
Property Value
Remarks
Read from the wire in DBN v2 and later. DBN v1 has no such field, so a v1 stream is SymbolCstrLengthV1 by definition — see SymbolCstrLengthForVersion(byte). It is kept as decoded rather than re-derived from Version so that re-encoding reproduces the original bytes exactly.
Symbols
The symbols the original query asked for. Never null.
public IReadOnlyList<string> Symbols { get; init; }
Property Value
TsOut
true when every record in the stream carries an appended gateway send timestamp.
public bool TsOut { get; init; }
Property Value
Version
The DBN version this metadata describes: 1, 2, or 3.
public required byte Version { get; init; }
Property Value
Remarks
After decoding, this is the version the data is presented as, which is the input version only under AsIs. Under the default UpgradeToV3 a v1 or v2 stream reports 3 here.
Methods
SymbolCstrLengthForVersion(byte)
The fixed symbol-field width a DBN stream of the given version uses when the wire does not state one.
public static int SymbolCstrLengthForVersion(byte version)
Parameters
versionbyteA DBN version.
Returns
- int
SymbolCstrLengthV1 below version 2, otherwise SymbolCstrLength — v2 and v3 share the same width.