carrow.mojo exports over the C Data Interface, which hands a consumer
pointers. That is why it cannot cross a process: a pointer means nothing
in another address space. This writes the same buffers — the same Arrow memory
layout, byte for byte — into a MappedRegion, and describes where each one
landed in a small JSON manifest.
A consumer maps the file, adds its own base to every offset, and wraps the
buffers where they lie. Nothing is decoded and nothing is copied on the
reading side:
base, _ = map_the_file(path)
buf = pa.foreign_buffer(base + off, length, owner)
col = pa.Array.from_buffers(pa.float64(), n, [validity, buf], null_count=k)
What it costs, honestly
One copy, on the producer's side: the decode wrote its buffers somewhere, and
this moves them into the mapping. That is the same copy export_c already
makes for an in-process handover — so this is a cross-process handover at
the price of the in-process one, not a free lunch.
Removing that copy as well means the decode allocating into the region in the
first place, which is a change to ArrayData's buffers rather than to this
file. memory_region is the half of that which already exists.
Flat columns only, for now
Primitive, utf8 and binary columns: validity, offsets and values. Nested
types — struct, list, map — have children, and a manifest that describes a
tree is a bigger thing than the one here. export_shared raises on them
rather than writing something a consumer would misread.