Expand description
Hand-rolled, 1-copy Arrow IPC stream encoder.
Arrow’s official StreamWriter always
stages the record-batch body in an internal Vec before writing it out, so
encoding a message through it copies the payload at least twice. This module
provides a fast path that writes the IPC flatbuffer headers and copies each
array buffer directly into a caller-provided &mut [u8] — exactly one
copy of the payload, straight into the (shared-memory) sample. For types the
fast path does not handle it falls back to the official writer.
The fast-path output is a normal Arrow IPC stream and decodes through the
official StreamDecoder — including the
zero-copy decode_arrow_ipc_zero_copy
receive path — because every body buffer is placed at a 64-byte-aligned
offset, matching what the official writer produces with its default
alignment = 64.
§How the fast path stays correct with minimal slice handling
Arrow’s writer contains a lot of per-type code to truncate and rebase buffers for sliced arrays. We avoid most of it with two rules:
- Require
offset() == 0on every node — so logical elementilives at physical positioni. Any array (or child) with a non-zero offset routes to the fallback. So do offset-carrying arrays (Binary,Utf8,Listand theirLargevariants) whose first offset is not 0, which would need their offsets rebased. - Copy each buffer’s prefix, never rewrite it. A buffer is copied from
its start up to the bytes the node’s
lenelements use:len * widthfor fixed-width data,len + 1offsets, and values up to the last offset. Slicing an offset-carrying array keepsoffset() == 0but leaves the parent’s whole values buffer (orListchild) attached, so without that cut every sliced send would ship the entire parent. The only generated buffer is the all-ones validity bitmap for a node with no nulls, exactly as arrow emits.
Children are sliced before recursion to the length the parent implies:
Struct fields to the struct’s len, a FixedSizeList child to
len * value_size, and a List/LargeList child to its last offset.
Structs§
- Input
Decoder - Per-input receive state for the schema-once zenoh path: one persistent
StreamDecoderprimed from the schema published on the output’s@schemasubtopic (or in-band, from the schema block of a full self-describing stream on the data topic), then reused to decode the schema-less batch messages that flow on the data topic. - Prepared
Ipc - A prepared Arrow IPC fast-path encode.
- Prepared
Uint8 Ipc - A prepared no-null
UInt8IPC fast-path encode.
Functions§
- batch_
fast_ path_ len - Exact byte length of the schema-less batch message
encode_batch_intowould write, orNoneifarrayis not fast-path eligible. - batch_
slice - Given a full IPC stream, return the schema-less record-batch slice —
everything after the schema block, including the trailing 8-byte
end-of-stream marker. The marker is what lets the receiver’s persistent
decoder flush a 0-row batch (whose body is empty); a non-empty batch never
reads it.
Noneifstreamis malformed. See [decode_one_batch]. - encode_
batch_ into - Encode
arrayas a schema-less Arrow IPC batch message intodst.dst.len()must equalbatch_fast_path_len(array). - encode_
ipc_ into - Encode
arrayas a complete Arrow IPC stream directly intodst, copying each array buffer exactly once. - encode_
ipc_ to_ vec - Fallback encoder for any array (including non-fast-path types): produce a
full Arrow IPC stream
Vecvia the official writer. The caller copies this into the sample, so this path costs two payload copies. - encode_
schema_ message - Encode the IPC schema message for
data_typeas a framed, 64-byte-aligned block (one nullable field nameddata). - encode_
uint8_ ipc_ header - Write a complete no-null
UInt8IPC stream intodstexcept the data region, and return the byte offset at which the caller must write thedata_lendata bytes (the buffer-protocol “construct in place” path). - ipc_
fast_ path_ len - Exact byte length of the Arrow IPC stream
encode_ipc_intowould write forarray, orNoneifarrayis not fast-path eligible. - schema_
block_ and_ hash - Schema identity of a full IPC stream: the FNV-1a hash of its leading schema
block, plus the block itself. This pairing IS the schema-once wire contract
— the producer (
publish_schema_once), the node receive path (in-band priming), and the daemon’sdora topicrebuild all derive the hash from exactly these bytes via this function; independent re-derivations could drift and silently break batch↔schema matching. - schema_
block_ len - Length of the leading schema-message block of a full IPC stream produced by
encode_ipc_into(so a receiver can split it into the schema prefix and the record-batch+body), orNoneifstreamis not a framed IPC message. - uint8_
ipc_ len - Total IPC stream length for a no-null
UInt8array ofdata_lenelements. Lets a caller size the sample before constructing the message in place viaencode_uint8_ipc_header.