Skip to main content

lbzip2/
lib.rs

1//! lbzip2-rs — Pure Rust parallel bzip2 decompressor.
2//!
3//! Architecture:
4//!   1 reader thread fills a ChunkRevolver ring buffer (~100 MB slots)
5//!   with raw compressed bzip2 data.
6//!
7//!   Per slot the reader does a cheap SIMD bit-scan to locate bzip2 block
8//!   boundaries (magic 0x314159265359 at arbitrary bit offsets), then
9//!   dispatches N sub-ranges to a worker pool.
10//!
11//!   Each worker independently decodes its Burrows-Wheeler blocks and
12//!   produces decompressed output.  Results are reassembled in order and
13//!   emitted as a streaming `Read`.
14
15pub mod bitreader;
16pub mod block;
17pub mod block_scan;
18pub mod bwt;
19pub mod chunk;
20pub mod huffman;
21pub mod mtf;
22pub mod parallel;
23pub mod reader;
24pub mod stream;
25
26/// bzip2 block magic: π digits — 0x314159265359 (48 bits, bit-aligned).
27pub const BLOCK_MAGIC: u64 = 0x314159265359;
28
29/// bzip2 end-of-stream magic: √π digits — 0x177245385090 (48 bits).
30pub const FINAL_MAGIC: u64 = 0x177245385090;
31
32// ── Dedicated thread pool ────────────────────────────────────────────────────
33
34use std::sync::OnceLock;
35
36static POOL: OnceLock<rayon::ThreadPool> = OnceLock::new();
37
38/// Get (or create) lbzip2's dedicated rayon thread pool.
39///
40/// Sized to the number of physical cores — separate from the caller's
41/// global rayon pool so bzip2 decode doesn't compete with VTD parse,
42/// PBF encode, etc.
43///
44/// Override with `LBZIP2_THREADS` env var.
45pub fn thread_pool() -> &'static rayon::ThreadPool {
46    POOL.get_or_init(|| {
47        let n = std::env::var("LBZIP2_THREADS")
48            .ok()
49            .and_then(|v| v.parse().ok())
50            .unwrap_or_else(|| {
51                std::thread::available_parallelism()
52                    .map(|n| n.get())
53                    .unwrap_or(4)
54            });
55        rayon::ThreadPoolBuilder::new()
56            .num_threads(n)
57            .thread_name(|i| format!("lbzip2-{i}"))
58            .build()
59            .expect("failed to create lbzip2 thread pool")
60    })
61}