pub struct Hlc {
pub wall: WallMicros,
pub counter: u32,
pub node: NodeId,
}Expand description
One hybrid logical clock stamp: a wall time, a logical counter, and the node that minted it.
The three fields give a total order over every event in the cluster.
Ord compares the wall time first, then the counter, then the node id.
The wall time keeps the order close to real time. The counter separates
events that share a microsecond. The node id breaks the remaining ties, so
two nodes that stamp the same wall time and the same counter still get one
order, and every node computes that same order.
The type is Copy, and it is 16 bytes wide in memory and 16 bytes wide on
the wire.
Fields§
§wall: WallMicrosThe wall time this stamp claims.
counter: u32The logical counter that separates events inside one microsecond.
node: NodeIdThe node that minted the stamp.
Implementations§
Source§impl Hlc
impl Hlc
Sourcepub const fn new(wall: WallMicros, counter: u32, node: NodeId) -> Self
pub const fn new(wall: WallMicros, counter: u32, node: NodeId) -> Self
A stamp built from its three parts.
Sourcepub fn encode(self) -> Result<[u8; 16], HlcError>
pub fn encode(self) -> Result<[u8; 16], HlcError>
The stamp as the exact bytes of the krabka.hlc header value.
The layout is big-endian and fixed-width: 8 bytes of wall time as an
i64, 4 bytes of counter as a u32, and 4 bytes of node id as a
u32. There is no varint framing and no length prefix. Java and Go
clients read this header by hand, and a plain big-endian layout is what
DataInputStream.readLong and binary.BigEndian.Uint32 already give
them.
§Errors
Returns HlcError::NodeIdTooLarge when the node id is above
u32::MAX, which is wider than the 4-byte field the layout gives it.
Sourcepub fn decode(bytes: &[u8]) -> Result<Self, HlcError>
pub fn decode(bytes: &[u8]) -> Result<Self, HlcError>
The stamp that bytes carries, with full validation.
This function reads a peer-supplied header value, so it validates the length before it reads a field. It never panics on malformed input, and it never allocates. Every 16-byte input is a valid stamp, because each of the three fields covers the whole range of its type.
Use extract_from_headers on an ingress
path, where a bad value must not fail the record that carried it. Use
this function where the caller wants to know why a value failed.
§Errors
Returns HlcError::Length when bytes is not exactly
HLC_ENCODED_LEN bytes long.
Sourcepub fn header(self) -> Result<(&'static str, [u8; 16]), HlcError>
pub fn header(self) -> Result<(&'static str, [u8; 16]), HlcError>
The stamp as a Kafka record header: the HLC_HEADER key and the
encoded value.
A producer attaches the pair to the record it writes. A record that carries no stamp gets no header, so an unstamped record costs zero bytes.
§Errors
Returns HlcError::NodeIdTooLarge when the node id is above
u32::MAX. See Hlc::encode.