OCaml bindings to liblzma (xz-utils) for XZ/LZMA2 compression and decompression
with multithreaded support.
- OCaml 72.7%
- C 22%
- Shell 3.1%
- Dune 2.2%
| .forgejo/workflows | ||
| .gear | ||
| bench | ||
| bin | ||
| lib | ||
| test | ||
| .gitignore | ||
| AUTHORS | ||
| CLAUDE.md | ||
| COPYING | ||
| dune-project | ||
| lzma.opam | ||
| README.md | ||
| README.ru.md | ||
lzma — OCaml bindings to liblzma for XZ compression and decompression
OCaml bindings to liblzma (xz-utils) for XZ/LZMA2 compression and decompression with multithreaded support.
Features
- Full
.xzformat support including concatenated streams - Multithreaded compression via
lzma_stream_encoder_mt(liblzma pthreads) - Parallel decompression of concatenated
.xzstreams via OCaml 5 Domains - Integrity verification: CRC32, CRC64, SHA-256 (handled by liblzma)
- Compression presets 0-9, configurable integrity check type
- Domain-safe: releases OCaml runtime during compression/decompression
- Configurable output size limit (decompression bomb protection)
- All errors returned as
resultvalues — no exceptions leak through the API - Includes
oxzCLI tool for.xzdecompression
Installation
opam install lzma
Or add to your dune-project:
(depends (lzma (>= 0.1.0)))
Requires OCaml >= 5.0.0 and liblzma-devel (xz-utils).
Library usage
open Lzma
(* Compress *)
let compressed = Xz.compress data (* preset=6, auto threads *)
let compressed = Xz.compress ~preset:1 ~threads:8 data (* fast, 8 threads *)
let result = Xz.compress_file_to ~src:"input" ~dst:"input.xz" ()
(* Decompress *)
let decompressed = Xz.decompress compressed
let decompressed = Xz.decompress_file "data.xz"
let result = Xz.decompress_file_to ~src:"input.xz" ~dst:"output" ()
(* Streaming decompression *)
let result = Xz.decompress_stream
~read:(fun buf off len -> input ic buf off len)
~write:(fun buf off len -> output oc buf off len)
()
Configuration
type config = {
threads : int; (* 0 = auto-detect CPU count *)
verify_integrity : bool; (* reserved, liblzma always verifies *)
max_output_size : int; (* 0 = unlimited, default 10 GiB *)
}
Error handling
All public API functions return (value, Types.error) result and never raise
exceptions. Error variants:
| Error | Description |
|---|---|
Invalid_header |
Malformed XZ stream header |
Corrupted_data |
Compressed data does not conform to spec |
Checksum_mismatch |
CRC32/CRC64/SHA-256 check failed |
Unsupported_filter |
Unsupported compression options |
Unsupported_check |
Unknown integrity check type |
Truncated_input |
Input data is incomplete |
Output_limit_exceeded |
Output would exceed max_output_size |
Resource_exhausted |
Out of memory |
CLI tool
The oxz command-line tool is installed alongside the library:
oxz -d file.xz # decompress (removes .xz)
oxz -d -k file.xz # decompress (keeps .xz)
oxz -dc file.xz # decompress to stdout
oxz -t file.xz # test integrity
oxz -l file.xz # list file info
oxz -t -v file.xz # verbose test (shows speed)
Performance
Compression of pkglist.classic (140.8 MiB, preset=6):
| Threads | Time | Speedup |
|---|---|---|
| 1 | 40.6s | 1.0x |
| 4 | 14.2s | 2.8x |
| auto (14 cores) | 9.2s | 4.4x |
Decompression of pkglist.classic.xz (27 MiB compressed, 2 concatenated streams):
| Wall time | Throughput | |
|---|---|---|
| oxz (2 streams parallel) | 1.33s | 108 MB/s |
| xz -t (single-threaded) | 1.28s | 110 MB/s |
Building from source
git clone https://altlinux.space/rider/ocaml-lzma2.git
cd ocaml-lzma2
dune build
dune runtest
Dependencies
- OCaml >= 5.0.0
- dune >= 3.0
- liblzma-devel (xz-utils)
Generate API documentation:
opam install odoc
dune build @doc
Architecture
Xz (public API)
└── lzma_stubs.c (C bindings to liblzma)
├── lzma_stream_encoder_mt (multithreaded compression)
└── lzma_stream_decoder (decompression)
└── Parallel (OCaml 5 Domain pool for multi-stream decompression)
└── Types (error types, configuration)
License
Author
Anton Farygin rider@altlinux.org