pub struct YcdIndex { /* private fields */ }Expand description
An in-memory index over a contiguous set of YCD files.
Building the index reads every file’s header once and stores the
resulting metadata. Subsequent read_digits calls use binary search
to locate the relevant file(s) and seek directly to the target block,
skipping every other file entirely.
§Stale-index detection
Each time a file is actually read, its current file_size and
last-modified time are compared against the snapshot taken at build
time. If any difference is detected, read_digits returns
io::ErrorKind::InvalidData with an explicit “stale index” message.
There is no silent fallback to a full-scan path.
§Example
use std::io;
use ycd_reader::YcdIndex;
fn main() -> io::Result<()> {
let files = [
"Pi - Dec - Chudnovsky - 0.ycd",
"Pi - Dec - Chudnovsky - 1.ycd",
];
// Build the index once (reads all headers).
let index = YcdIndex::build(&files)?;
// Fast random-access — only the relevant file(s) are opened.
let digits = index.read_digits(999_995, 20)?;
assert_eq!(digits, "45815130927562832084");
Ok(())
}Implementations§
Source§impl YcdIndex
impl YcdIndex
Sourcepub fn build<P: AsRef<Path>>(files: &[P]) -> Result<Self>
pub fn build<P: AsRef<Path>>(files: &[P]) -> Result<Self>
Build an index from an ordered, contiguous slice of YCD file paths.
Every file’s header is read and validated (base-10 constraint,
contiguity, no duplicates, no gaps). On success the index is ready
for read_digits calls.
§Errors
Returns the same errors as YcdFileUtil::read_digits for header and
continuity problems. Additionally returns InvalidInput when files
is empty.
Sourcepub fn rebuild<P: AsRef<Path>>(&mut self, files: &[P]) -> Result<()>
pub fn rebuild<P: AsRef<Path>>(&mut self, files: &[P]) -> Result<()>
Discard the current index and rebuild it from a new file list.
On success self is replaced with the freshly built index. If the
rebuild fails, self is left unchanged.
Sourcepub fn entries(&self) -> &[YcdIndexEntry]
pub fn entries(&self) -> &[YcdIndexEntry]
Returns a slice of all index entries in digit order.
Sourcepub fn read_digits(
&self,
one_based_start_position: usize,
length: usize,
) -> Result<String>
pub fn read_digits( &self, one_based_start_position: usize, length: usize, ) -> Result<String>
Read exactly length decimal digits starting at 1-based position
one_based_start_position.
Binary search locates the first file that contains the start position. Only the file(s) actually needed are opened; all other files are skipped entirely.
Before reading each file, its current file_size and last-modified
time are compared against the index snapshot. A mismatch returns
io::ErrorKind::InvalidData with an “index is stale” message.
§Errors
| Condition | io::ErrorKind |
|---|---|
| Index is empty, position 0, or length 0 | InvalidInput |
| Start or end position outside the indexed range | InvalidInput |
start + length overflows usize | InvalidData |
| File size or mtime differs from index snapshot | InvalidData |
| File does not exist | NotFound |
| Payload truncated within logical range | UnexpectedEof |
| Output string pre-allocation failure | Other |