use d4_framefile::Directory;
use std::fs::File;
use std::io::Result;
use crate::header::Header;
mod sparse_array;
pub use sparse_array::RangeRecord;
pub(crate) use sparse_array::{
CompressionMethod, Record, RecordBlockParsingState, SparseArraryMetadata,
};
pub const SECONDARY_TABLE_NAME: &str = ".stab";
pub const SECONDARY_TABLE_METADATA_NAME: &str = ".metadata";
pub trait SecondaryTableWriter: Sized {
type Partition: SecondaryTablePartWriter;
fn create(root: &mut Directory<File>, header: &Header) -> Result<Self>;
fn split(&mut self, partitions: &[(&str, u32, u32)]) -> Result<Vec<Self::Partition>>;
fn enable_deflate_encoding(&mut self, level: u32) -> &mut Self;
}
pub trait SecondaryTablePartWriter: Send {
fn encode(&mut self, pos: u32, value: i32) -> Result<()>;
fn encode_record(&mut self, left: u32, right: u32, value: i32) -> Result<()>;
fn flush(&mut self) -> Result<()>;
fn finish(&mut self) -> Result<()> {
Ok(())
}
}
pub trait SecondaryTableReader: Sized {
type Partition: SecondaryTablePartReader;
fn create(root: &mut Directory<File>, header: &Header) -> Result<Self>;
fn split(&mut self, partitions: &[(&str, u32, u32)]) -> Result<Vec<Self::Partition>>;
}
pub trait SecondaryTablePartReader: Sized {
type IteratorState: Sized;
fn decode(&mut self, pos: u32) -> Option<i32>;
fn next_record(&self, state: &mut Self::IteratorState) -> Option<(u32, u32, i32)>;
fn iter(&self) -> RecordIterator<'_, Self>;
fn seek_state(&self, pos: u32) -> Self::IteratorState;
fn seek_iter(&self, pos: u32) -> RecordIterator<'_, Self> {
RecordIterator(self, self.seek_state(pos))
}
}
pub struct RecordIterator<'a, S: SecondaryTablePartReader>(&'a S, S::IteratorState);
impl<'a, S: SecondaryTablePartReader> RecordIterator<'a, S> {
pub fn into_state(self) -> S::IteratorState {
self.1
}
pub fn new(parent: &'a S, state: S::IteratorState) -> Self {
Self(parent, state)
}
}
impl<'a, S: SecondaryTablePartReader> Iterator for RecordIterator<'a, S> {
type Item = (u32, u32, i32);
fn next(&mut self) -> Option<Self::Item> {
self.0.next_record(&mut self.1)
}
}
#[cfg(all(feature = "mapped_io", not(target_arch = "wasm32")))]
pub mod mapped {
use super::sparse_array;
pub use sparse_array::RangeRecord;
pub use sparse_array::SparseArrayPartReader;
pub use sparse_array::SparseArrayPartWriter;
pub use sparse_array::SparseArrayReader;
pub use sparse_array::SparseArrayWriter;
}
#[cfg(all(feature = "mapped_io", not(target_arch = "wasm32")))]
pub use mapped::*;