path — addressing (L4)

In one paragraph

A path_t parses /sensor/temp (with an optional :field.sub[N] tail) into the canonical PATH-TLV payload bytes — the concatenated NAME children. Those bytes, not the string, are the vertex-map key: dispatch is a byte compare, never a string parse on the hot path.

What it does

path_t::parse validates and canonicalizes per the addressing rules (reference/03): strip a trailing /, reject empty segments (//) and unrooted paths, enforce the limits (≤64 B/segment, ≤1024 B total, ≤32 segments, ≤8 field steps). It emits the canonical key — e.g. /sensor/temp02 00 06 00 'sensor' 02 00 04 00 'temp' (18 bytes) — and parses the :-tail into a field_path_t (settings.deadline_ns, subscribers[], subscribers[3]) for the field-write surface. path_key_t + path_key_hash_t (FNV-1a over the bytes) key the unordered_map.

Interface

struct field_step_t { std::string name; bool indexed, append; std::uint16_t index; };
struct field_path_t { std::vector<field_step_t> steps; };

class path_t {
    static result_t<path_t> parse(std::string_view);  // result_t = expected<T, status_t>
    std::span<const std::byte> key() const;          // canonical PATH payload bytes
    const field_path_t& field() const;               // the :field.sub[N] tail
    std::size_t segment_count() const;
};
struct path_key_t { std::vector<std::byte> bytes; };  struct path_key_hash_t { /* FNV-1a */ };

String → bytes, once

        flowchart LR
    S["/sensor/temp:settings.deadline_ns"] --> P[path_t::parse]
    P --> K["key bytes<br/>NAME sensor · NAME temp"]
    P --> F["field<br/>settings → deadline_ns"]
    K --> M{{"vertex map<br/>(byte-keyed)"}}
    classDef e fill:#dbeafe,stroke:#1e40af
    class M e
    

Benefits

  • No strings on the hot path — parse once at registration; every read/write compares canonical bytes. A build-time PATH literal needs no parse at all.

  • One key everywhere — the same bytes key the local map and travel on the wire (a PATH TLV), so local and remote addressing are byte-identical.

  • Validated — malformed paths fail at parse with a typed status_t, not deep in dispatch.

API reference

Generated from core/include/libtracer/path.hpp by Doxygen.

class path_t

A parsed, canonical path: the PATH-TLV payload bytes (NAME children) plus the optional field_path_t tail. The payload bytes are the vertex-map key.

Dispatch keys on the parsed bytes (key), never the string form — parse once, hold the value, and every read/write compares bytes (docs/reference/02 §dispatch).

Public Functions

path_t() = default

An empty path (no segments, no field tail).

inline explicit path_t(std::string_view text)

Construct from a compile-site / known-good path LITERAL, parsing ONCE.

path_t p("/sensor/temp"); write(p, a); write(p, b); — parse the string a single time, then hold the value and reuse the handle; the graph API takes const path_t& so a held path never re-parses on the hot path (docs/reference/02 §dispatch keys on the parsed PATH-TLV bytes, never the string). A malformed literal is a source bug, so this hard-aborts rather than yielding a fallible result_t the caller would only *-deref unchecked. For a RUNTIME string whose validity is a genuine runtime condition, use parse (fallible). explicit — construction is always a visible, deliberate parse, never an implicit per-call one. No exceptions (usable under -fno-exceptions).

inline std::span<const std::byte> key() const noexcept

The vertex-map key: the canonical PATH-TLV payload bytes (NAME children).

inline const field_path_t &field() const noexcept

The parsed :field tail (empty when the path addresses the vertex value).

inline std::size_t segment_count() const noexcept

The number of NAME segments in the path.

Public Static Functions

static result_t<path_t> parse(std::string_view text)

Parse and canonicalize a path string (fallible — for a RUNTIME string).

Accepts "/sensor/temp" or "/sensor/temp:settings.deadline_ns". Canonicalizes: strip a trailing /, reject empty segments (//) and unrooted paths, enforce the kMaxSegmentBytes / kMaxPathBytes / kMaxSegments / kMaxFieldDepth limits. A known-good literal uses the parse-once path_t(std::string_view) constructor instead.

Parameters:

text – The path string to parse.

Returns:

The parsed path_t, or a status_t error (e.g. INVALID_PATH).

struct field_path_t

The parsed :field.sub[N] tail of a path — a sequence of field_step_t.

Empty when the path addresses the vertex value itself (no : tail). Drives the field-write / field-read control surface (docs/reference/04).

Public Functions

inline bool empty() const noexcept

True when there is no field tail (addresses the vertex value).

bool operator==(const field_path_t&) const = default

Value equality over the step sequence.

Public Members

std::vector<field_step_t> steps

The .-separated steps; empty ⇒ the vertex value itself.

struct field_step_t

One step of a field path: a NAME and an optional [index] / [] append / [*] wildcard selector.

The parsed form of one .-separated component of a :field.sub[N] tail (docs/reference/03 §addressing). Exactly one of indexed (with index), append, or wildcard is meaningful when a [...] selector is present.

Public Functions

bool operator==(const field_step_t&) const = default

Value equality over every field.

Public Members

std::string name

The step’s NAME (the text before any [...]).

bool indexed = false

True if a [...] selector was present.

bool append = false

True for [] — append to a sequence.

bool wildcard = false

True for [*] — FIELD index_mode=WILDCARD (RFC-0004 §C).

std::uint16_t index = 0

The [N] index; valid when indexed && !append && !wildcard.

See: graph, wire-format-bits.