use std::fs::File;
use std::io::{self, BufRead, BufReader};
use std::path::{Path, PathBuf};
use bzip2::read::MultiBzDecoder;
use crate::dump::multistream;
use crate::error::Result;
const BUFFER_SIZE: usize = 64 * 1024;
pub enum PageSource {
Sequential(Box<dyn BufRead + Send>),
Multistream(MultistreamSource),
}
pub struct MultistreamSource {
pub path: PathBuf,
pub offsets: Vec<u64>,
}
impl PageSource {
pub fn open(path: &Path) -> Result<Self> {
if path.extension().is_some_and(|e| e == "bz2") {
if let Some(index_path) = multistream::index_path_for(path) {
let offsets = multistream::read_stream_offsets(&index_path)?;
log::info!(
"using multistream index {} ({} streams)",
index_path.display(),
offsets.len()
);
return Ok(Self::Multistream(MultistreamSource {
path: path.to_path_buf(),
offsets,
}));
}
let file = BufReader::with_capacity(BUFFER_SIZE, File::open(path)?);
Ok(Self::Sequential(Box::new(BufReader::with_capacity(
BUFFER_SIZE,
MultiBzDecoder::new(file),
))))
} else {
Ok(Self::Sequential(Box::new(BufReader::with_capacity(
BUFFER_SIZE,
File::open(path)?,
))))
}
}
pub fn stdin() -> Self {
Self::Sequential(Box::new(BufReader::with_capacity(BUFFER_SIZE, io::stdin())))
}
}