arrow-mlake · API

arrow_mlake.ipc

The Arrow IPC stream format: RecordBatches to bytes and back.

The C Data Interface hands buffers to another library in the same process. IPC is for everything else: a file, a socket, a shared mapping another process reads. pyarrow's ipc.open_stream reads what IpcWriter writes, and read_ipc_stream reads what pyarrow's ipc.new_stream writes.

var w = IpcWriter(batch)      # the schema comes from the first batch
w.write(batch)
var bytes = w^.finish()

var s = read_ipc_stream(Span(bytes))
print(len(s.batches), "batches of", s.schema.num_columns(), "columns")
The framing

Each message in a stream is:

ffffffff                  continuation marker
<int32 metadata_size>     little-endian, a multiple of 8
<flatbuffer Message>      padded out to metadata_size
<body>                    the buffers, each padded to a multiple of 8

and the stream ends with a continuation marker and a zero length. The first message is the Schema; every later one is a RecordBatch whose nodes and buffers list each array in pre-order, parent before children. The reader also accepts the pre-0.15 framing without the continuation marker.

What is supported

Every type ArrayData holds: null, bool, the eight integers, the three floats, utf8 and binary and their large forms, fixed-size binary, decimal128, date32, time32/64, timestamps with a unit and zone, list, large list, struct and map, nested to any depth. Fields carry their nullability and two metadata keys, ARROW:extension:name and PARQUET:field_id, which is where ArrowType.extension and ArrayData.field_id travel.

Dictionary encoding, compression, unions, run-end encoding, the view types and the IPC file format are not implemented; a stream that uses them is rejected with an error that names the feature.

A validity bitmap is only written when an array has nulls; otherwise the buffer is empty, which the format allows. Reading copies each buffer into the ArrayData's own lists.

Structs

IpcWriter

struct IpcWriter

Writes an Arrow IPC stream: the schema, then one message per batch.

Every batch must have the schema's columns, in order, with the same types; write checks the top-level types.

Implements Movable

__init__

def __init__(out self, schema: RecordBatch)

Starts a stream with schema's columns. Only the types and names are read; its rows are not written.

write

def write(mut self, batch: RecordBatch)

finish

def finish(deinit self) -> List[UInt8]

The finished stream, end-of-stream marker included.

IpcStream

struct IpcStream

What read_ipc_stream found: the schema, as a batch of no rows, and every record batch in order.

Implements Movable

Fields
schema: RecordBatch
batches: List[RecordBatch]

__init__

def __init__(out self, var schema: RecordBatch, var batches: List[RecordBatch])

Functions

encode_schema_message

def encode_schema_message(batch: RecordBatch) -> List[UInt8]

The flatbuffer Message holding batch's schema, unframed.

write_ipc_stream

def write_ipc_stream(batches: List[RecordBatch]) -> List[UInt8]

batches as one stream; the first batch gives the schema.

read_ipc_stream

def read_ipc_stream(data: Span[UInt8]) -> IpcStream

Reads a whole Arrow IPC stream. Every buffer is copied out of data.