Table of Contents

Class PitSymbolMap

Namespace
DatabentoDotNet.Dbn
Assembly
DatabentoDotNet.Dbn.dll

A point-in-time symbol map: resolves an instrument ID to its symbol with no date involved at all. Useful for live symbology, or a historical request over a single day where the mapping is known not to change.

public sealed class PitSymbolMap : ISymbolIndex
Inheritance
PitSymbolMap
Implements
Inherited Members

Examples

Live, where the map is grown from the mappings the stream interleaves with the data:

var symbols = new PitSymbolMap();

while (true)
{
    while (client.TryNextRecord(out RecordRef record))
    {
        // Ignores anything that is not a mapping, so it is safe to call on every record.
        symbols.OnRecord(record);

        if (symbols.TryGetSymbol(record.Header.InstrumentId, out string? symbol))
        {
            Console.WriteLine($"{symbol} {record.Header.RType}");
        }
    }

    if (await client.FillBufferAsync() == 0)
    {
        break;
    }
}

Historical, over a single day. No date takes part in the lookup, because the date was committed to when the map was built:

var symbols = PitSymbolMap.FromMetadata(decoder.Metadata!, new LocalDate(2024, 1, 2));
symbols.TryGetSymbol(12345u, out string? symbol);

Remarks

Port of upstream's PitSymbolMap (symbol_map.rs:73-374). Build one from a single day of a decoded stream's metadata with FromMetadata(Metadata, LocalDate), or grow one incrementally as a live or replayed stream is consumed with OnRecord(RecordRef). Resolve with TryGetSymbol(uint, out string?).

No date or timestamp is ever involved in resolution — this is the whole point of "point-in-time": the caller already committed to one date when the map was built (or has kept it current via OnRecord(RecordRef)), so TryGetSymbol(uint, out string?) is unconditional instrument_id -> symbol. This is a real, deliberate divergence from TsSymbolMap, not an oversight to "fix" into checking a timestamp too.

The incremental update path (OnRecord(RecordRef), OnSymbolMapping(in SymbolMappingMsg)) is what M2's live client depends on: called once per record as a stream is consumed, so it stays allocation-light — it allocates exactly the one string a genuine new mapping requires, the same as upstream's own to_owned(), and nothing else.

Constructors

PitSymbolMap()

Creates a new, empty point-in-time symbol map.

public PitSymbolMap()

Properties

Count

The number of instrument IDs currently mapped.

public int Count { get; }

Property Value

int

IsEmpty

true when there are no mappings.

public bool IsEmpty { get; }

Property Value

bool

Methods

FromMetadata(Metadata, LocalDate)

Builds a point-in-time symbol map from a decoded stream's metadata, resolved for one specific date.

public static PitSymbolMap FromMetadata(Metadata metadata, LocalDate date)

Parameters

metadata Metadata

The metadata to build the map from.

date LocalDate

The date to resolve every mapping for.

Returns

PitSymbolMap

The resulting map.

Remarks

Port of upstream's PitSymbolMap::from_metadata (symbol_map.rs:237-273), reached via Metadata::symbol_map_for_date() (metadata.rs:113-115).

The date-range check compares at full nanosecond precision, not date granularity. date is promoted to date at 00:00 UTC and compared against End — itself a nanosecond timestamp — directly, not against End truncated to a date. The upper bound is therefore exclusive at nanosecond granularity: an End of exactly midnight on day D excludes day D entirely (00:00 >= 00:00), while an End even one nanosecond past midnight on day D includes all of day D (00:00 < 00:00:00.000000001). Truncating End to a date before comparing gets this boundary backwards — pinned upstream by test_symbol_map_for_date_out_of_range (symbol_map.rs:870-890) and ported as SymbolMapTests' own midnight-exact / midnight-plus-one-nanosecond tests.

Exceptions

ArgumentNullException

metadata is null.

DbnDecodeException

Neither StypeIn nor StypeOut is InstrumentId; a mapping's instrument-ID string does not parse as a uint; or date falls outside metadata's query range.

OnInstrumentDef(in InstrumentDefMsg)

Updates this map from a current-version (DBN v3) instrument definition record.

public void OnInstrumentDef(in InstrumentDefMsg record)

Parameters

record InstrumentDefMsg

The instrument definition record.

Remarks

Port of upstream's PitSymbolMap::on_instrument_def (symbol_map.rs:310-318). An alternate incremental-update path to OnSymbolMapping(in SymbolMappingMsg): a definition record carries its own raw_symbol, so a stream of definitions can keep a map current without any symbol-mapping records at all. Neither this method nor its two sibling overloads is called from OnRecord(RecordRef) — a caller who wants this path must call it explicitly, matching upstream.

OnInstrumentDef(in InstrumentDefMsgV1)

Updates this map from a DBN v1 instrument definition record.

public void OnInstrumentDef(in InstrumentDefMsgV1 record)

Parameters

record InstrumentDefMsgV1

The instrument definition record.

Remarks

OnInstrumentDef(in InstrumentDefMsgV2)

Updates this map from a DBN v2 instrument definition record.

public void OnInstrumentDef(in InstrumentDefMsgV2 record)

Parameters

record InstrumentDefMsgV2

The instrument definition record.

Remarks

OnRecord(RecordRef)

Updates this map from one record if it carries a symbol mapping; otherwise does nothing.

public void OnRecord(RecordRef record)

Parameters

record RecordRef

The record to inspect.

Remarks

Port of upstream's PitSymbolMap::on_record (symbol_map.rs:280-288). Tries the current-version SymbolMappingMsg layout first, then the DBN v1 layout (SymbolMappingMsgV1); any other record type — including an instrument definition — is a silent no-op. Definition records update the map only through the separate OnInstrumentDef(in InstrumentDefMsg) family, which a caller must call explicitly; upstream does not fold that path into on_record either.

OnSymbolMapping(in SymbolMappingMsg)

Updates this map from a current-version (DBN v2/v3) symbol-mapping record.

public void OnSymbolMapping(in SymbolMappingMsg record)

Parameters

record SymbolMappingMsg

The symbol-mapping record.

Remarks

Port of upstream's PitSymbolMap::on_symbol_mapping (symbol_map.rs:294-304). Maps InstrumentId to StypeOutSymbol — the output symbol, since a live symbol-mapping record always resolves an input symbol to an instrument ID and reports back what that instrument's output symbol is.

OnSymbolMapping(in SymbolMappingMsgV1)

Updates this map from a DBN v1 symbol-mapping record.

public void OnSymbolMapping(in SymbolMappingMsgV1 record)

Parameters

record SymbolMappingMsgV1

The symbol-mapping record.

Remarks

TryGetSymbol(RecordRef, out string?)

Looks up the symbol for a decoded record.

public bool TryGetSymbol(RecordRef record, out string? symbol)

Parameters

record RecordRef

The record to resolve.

symbol string

Receives the resolved symbol, or null when the map has no mapping for this record.

Returns

bool

true if a mapping was found.

Remarks

This is the overload a decoder loop uses, since RecordRef is what TryNextRecord hands out and no downcast is needed to resolve a symbol.

TryGetSymbol(uint, out string?)

Looks up the symbol currently mapped to an instrument ID.

public bool TryGetSymbol(uint instrumentId, out string? symbol)

Parameters

instrumentId uint

The instrument ID to resolve.

symbol string

Receives the resolved symbol, or null when instrumentId has no mapping.

Returns

bool

true if a mapping was found.

Remarks

Port of upstream's PitSymbolMap::get (symbol_map.rs:321-323), shaped as a Try* member because an unmapped instrument ID is an expected outcome, not an exceptional one.

TryGetSymbol<TRecord>(in TRecord, out string?)

Looks up the symbol for a decoded record of a known type.

public bool TryGetSymbol<TRecord>(in TRecord record, out string? symbol) where TRecord : unmanaged, IRecord<TRecord>

Parameters

record TRecord

The record to resolve.

symbol string

Receives the resolved symbol, or null when the map has no mapping for this record.

Returns

bool

true if a mapping was found.

Type Parameters

TRecord

The record struct.

Remarks

For a record that has been downcast or copied out of the read buffer — one held in a collection, say, where no RecordRef survives to call the other overload with. Takes the record by in so a 520-byte InstrumentDefMsg is read in place rather than copied to be asked its symbol.