Skip to main content

A Rust-backed Python library for caching Arrow record-batch streams so they can be replayed multiple times

Project description

batchcorder

A Rust-backed Python library for caching Arrow record-batch streams so they can be replayed multiple times from a source that can only be read once.

The problem

Arrow RecordBatchReader is a single-use stream — once consumed, it is gone. Training loops and multi-pass data pipelines need to iterate the same stream repeatedly without re-reading from disk or the network each time.

What batchcorder does

StreamCache wraps any Arrow stream source (anything that implements __arrow_c_stream__) and stores each RecordBatch in a cache. Two storage modes are supported:

  • Memory-only (default): batches are stored as reference-counted pointers in RAM; reads are zero-copy and no IPC serialisation happens.
  • Hybrid memory+disk: batches are serialised to an append-only IPC file on disk; a configurable hot layer keeps recently ingested batches in RAM to reduce disk I/O.

Multiple independent readers can replay the stream concurrently, each maintaining their own position in the batch sequence.

flowchart LR
    U["upstream source<br/>(read once)"] --> D["StreamCache<br/>[mem cache / mem+disk cache]"]
    D --> R0["StreamCacheReader 0<br/>(from batch 0)"]
    D --> R1["StreamCacheReader 1<br/>(from batch 0)"]
    D --> R2["StreamCacheReader 2<br/>(from batch 3)"]

Installation

pip install batchcorder

Usage

import tempfile

import pyarrow as pa

from batchcorder import StreamCache

table = pa.table({"x": [1, 2, 3], "y": [4, 5, 6]})

# Memory-only (default capacity = total physical RAM)
ds = StreamCache(table.to_reader(max_chunksize=1))

# Memory-only with explicit capacity
ds = StreamCache(
    table.to_reader(max_chunksize=1),
    memory_capacity=64 * 1024 * 1024,  # 64 MB
)

# Hybrid memory+disk
tmp = tempfile.mkdtemp()
ds = StreamCache(
    table.to_reader(max_chunksize=1),
    memory_capacity=64 * 1024 * 1024,  # 64 MB in RAM
    disk_path=tmp,
    disk_capacity=512 * 1024 * 1024,  # 512 MB on disk
)

# Replay as many times as needed
for batch in ds:
    print(batch)

# Or get an independent reader handle
reader = ds.reader()
result = pa.RecordBatchReader.from_stream(reader).read_all()

# Bounded-memory: evict batches once all readers have passed them
ds = StreamCache(
    table.to_reader(max_chunksize=1),
    max_readers=2,  # at most 2 reads; batches evicted when both advance
)

# Pre-ingest everything upfront
ds.ingest_all()

Compatibility

StreamCache and StreamCacheReader implement both __arrow_c_stream__ and __arrow_c_schema__, so they work with any Arrow-compatible library:

import pyarrow as pa
import duckdb

pa.table(ds)  # PyArrow
pa.table(ds.reader())  # via StreamCacheReader
duckdb.table("ds")  # DuckDB

Key properties

  • Single-read source: the upstream stream is consumed exactly once; all subsequent reads come from the cache.
  • Concurrent readers: multiple StreamCacheReader instances from the same stream cache are fully independent and thread-safe.
  • Lazy ingestion: batches are fetched from the upstream source on demand as readers advance, not upfront.
  • Replay from any position: ds.reader(from_start=True) (default) replays from batch 0; ds.reader(from_start=False) starts from the current ingestion frontier (next batch not yet ingested).
  • Bounded-memory streaming: set max_readers=N to evict batches once all N readers exist and have advanced past them — eviction does not begin until all N readers have been created. max_readers is a hard cap on total readers ever created (dropping a reader does not free a slot). Once eviction has started, reader(from_start=True) raises ValueError. When unset, all batches are retained indefinitely.

Development

# Install dependencies and build the extension
uv sync --no-install-project --dev
uv run maturin develop --uv

# Run tests
uv run pytest

# Run all pre-commit checks
uv run pre-commit run --all-files

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

batchcorder-0.1.3.tar.gz (245.4 kB view details)

Uploaded Source

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

batchcorder-0.1.3-cp310-abi3-win_amd64.whl (1.0 MB view details)

Uploaded CPython 3.10+Windows x86-64

batchcorder-0.1.3-cp310-abi3-win32.whl (891.9 kB view details)

Uploaded CPython 3.10+Windows x86

batchcorder-0.1.3-cp310-abi3-manylinux_2_28_aarch64.whl (1.3 MB view details)

Uploaded CPython 3.10+manylinux: glibc 2.28+ ARM64

batchcorder-0.1.3-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (1.4 MB view details)

Uploaded CPython 3.10+manylinux: glibc 2.17+ x86-64

batchcorder-0.1.3-cp310-abi3-macosx_11_0_arm64.whl (1.1 MB view details)

Uploaded CPython 3.10+macOS 11.0+ ARM64

batchcorder-0.1.3-cp310-abi3-macosx_10_12_x86_64.whl (1.2 MB view details)

Uploaded CPython 3.10+macOS 10.12+ x86-64

File details

Details for the file batchcorder-0.1.3.tar.gz.

File metadata

  • Download URL: batchcorder-0.1.3.tar.gz
  • Upload date:
  • Size: 245.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: maturin/1.13.3

File hashes

Hashes for batchcorder-0.1.3.tar.gz
Algorithm Hash digest
SHA256 bd74b90c83d146bf1bbf4582c1e7e04b312fe17df8bf1b034c0ba90532bf2b14
MD5 b6eebda7924260b8f4896da2f9f0a2de
BLAKE2b-256 114def6ee4f348b31736c34dc81c327052a61e77f31fe1bf862ccb28364d4410

See more details on using hashes here.

File details

Details for the file batchcorder-0.1.3-cp310-abi3-win_amd64.whl.

File metadata

File hashes

Hashes for batchcorder-0.1.3-cp310-abi3-win_amd64.whl
Algorithm Hash digest
SHA256 90c8a5155020213bcda2e5a9d533a429aee04cde4ec5cd032da932b8341d83f2
MD5 55b35e74a8652254b5d37bceb6b7d92d
BLAKE2b-256 68ae36b740b070a756d31ada6d46636918fab3aa0f89b809ccdde32a773ae2c9

See more details on using hashes here.

File details

Details for the file batchcorder-0.1.3-cp310-abi3-win32.whl.

File metadata

  • Download URL: batchcorder-0.1.3-cp310-abi3-win32.whl
  • Upload date:
  • Size: 891.9 kB
  • Tags: CPython 3.10+, Windows x86
  • Uploaded using Trusted Publishing? No
  • Uploaded via: maturin/1.13.3

File hashes

Hashes for batchcorder-0.1.3-cp310-abi3-win32.whl
Algorithm Hash digest
SHA256 47c5a1846f9e28cc6d1d6ec802525d64244e9df7f6a2f396b9ece8ee66b690f3
MD5 9ac57f894350aa6ff14c5a634b8d4866
BLAKE2b-256 a5fd66e46d2a6e82e074abd03b49d53ff6b55acd2c2b634733beea86aa2a8d4d

See more details on using hashes here.

File details

Details for the file batchcorder-0.1.3-cp310-abi3-manylinux_2_28_aarch64.whl.

File metadata

File hashes

Hashes for batchcorder-0.1.3-cp310-abi3-manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 24a3825c707149851bc2271a93a3873842bb282f1fc031c41a022c38ed8c857a
MD5 86d55fc06b5bd4a620feebc5929920c8
BLAKE2b-256 c34fe92d207da271016428f2dbb4bae1d23e5d6ffb2f4120131ef69d8bbdda7c

See more details on using hashes here.

File details

Details for the file batchcorder-0.1.3-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for batchcorder-0.1.3-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 703d2ac6e1409e4c199ad71042600b4e27a658847883fe173dbfd65e7a5fff49
MD5 9700d87cb8e67b470b011b5f3a81dca9
BLAKE2b-256 aee15049542d85de2ec3753655e11224a9fa0422eb135228670886d5eb9ab339

See more details on using hashes here.

File details

Details for the file batchcorder-0.1.3-cp310-abi3-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for batchcorder-0.1.3-cp310-abi3-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 024f07f8daa8f5fe00eb577abd8e80baecb5a74374579df68194ac3eff77ea29
MD5 cc385eb935377d72ea4f8f42ad060b08
BLAKE2b-256 e2a5ecafe8a525d507d2b49ee612da2cf119832674cb535318f2092d033935cc

See more details on using hashes here.

File details

Details for the file batchcorder-0.1.3-cp310-abi3-macosx_10_12_x86_64.whl.

File metadata

File hashes

Hashes for batchcorder-0.1.3-cp310-abi3-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 8971845bb2b92e318d19d39b373e13b40c1fa98b0eeed37b8aee63a59ce7c975
MD5 76e181923162fae5341cf7c891e9bb9a
BLAKE2b-256 768bf13bb954e848b868e8a3bfa9116bfa7cbf541e665c3575852815757e5fe6

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page