pub struct SegmentReader { /* private fields */ }Expand description
Reads data from a .csx segment file.
§I/O model
The segment file is memory-mapped (Mmap) so all column block
reads are zero-copy slices into the OS page cache. No per-column
File::read() calls are issued; instead the kernel pages data in on
first access and the MADV_WILLNEED advisory hint triggers
asynchronous prefetch of upcoming blocks while the current block is
being decoded. This means sequential scans benefit from kernel-level
read-ahead without any user-space prefetch thread or buffer.
§Predicate pushdown
read_projected_filtered_with_predicates
evaluates predicates at row-group granularity using per-block
ColumnStats before touching any
column bytes. This can skip entire row groups when the query’s
time window doesn’t overlap a row group’s timestamp range, or when
a tag column’s value_count proves it cannot match an equality
filter.
Implementations§
Source§impl SegmentReader
impl SegmentReader
Sourcepub fn open(path: impl AsRef<Path>) -> Result<Self>
pub fn open(path: impl AsRef<Path>) -> Result<Self>
Open a segment file, validate integrity, and parse metadata.
§Errors
Returns an error if the file doesn’t exist, is corrupt, or has an invalid checksum.
Sourcepub fn header(&self) -> &SegmentHeader
pub fn header(&self) -> &SegmentHeader
Returns the segment header.
Sourcepub fn column_metadata(&self) -> &[ColumnMeta]
pub fn column_metadata(&self) -> &[ColumnMeta]
Returns the column metadata.
Sourcepub fn row_group_count(&self) -> usize
pub fn row_group_count(&self) -> usize
Returns the number of row groups.
Sourcepub fn row_group_blocks(&self, row_group: usize) -> Option<&[ColumnBlockMeta]>
pub fn row_group_blocks(&self, row_group: usize) -> Option<&[ColumnBlockMeta]>
Returns the per-column block metadata for one row group.
Each entry carries the codec that was actually used for that block —
ColumnMeta::default_encoding
is only the writer’s initial guess — along with its on-disk length.
Together they answer “which encoding won, and what did it cost”, which
is what compression regressions and codec benchmarks need to see.
Returns None if row_group is out of range.
Sourcepub fn set_key_provider(&mut self, provider: Arc<dyn FieldKeyProvider>)
pub fn set_key_provider(&mut self, provider: Arc<dyn FieldKeyProvider>)
Set a field-level encryption key provider for decrypting encrypted column blocks. Must be called before reading any encrypted columns.
Sourcepub fn read_columns(
&self,
column_names: &[&str],
row_group: usize,
) -> Result<Vec<ArrayRef>>
pub fn read_columns( &self, column_names: &[&str], row_group: usize, ) -> Result<Vec<ArrayRef>>
Read specific columns from a specific row group as Arrow arrays.
§Read-ahead / prefetch
When reading column N, the reader issues an madvise(MADV_WILLNEED)
hint for column N+1’s byte range so the OS can begin paging it in
from disk while the current column is being decoded. Combined with
the Sequential advice set at open time, this reduces I/O stalls
on sequential scans.
§Errors
Returns an error if the row group index is out of range or a column is not found.
Sourcepub fn read_all(&self) -> Result<RecordBatch>
pub fn read_all(&self) -> Result<RecordBatch>
Read all data as a single Arrow RecordBatch.
This is a convenience wrapper around read_projected
that passes every column name. When only a subset of columns is
needed, prefer calling read_projected or
read_projected_filtered directly
— they skip I/O and decompression for unrequested columns (
column pruning).
§Errors
Returns an error if any column data is corrupt.
Sourcepub fn read_row_group(&self, row_group: usize) -> Result<RecordBatch>
pub fn read_row_group(&self, row_group: usize) -> Result<RecordBatch>
Read all columns from a single row group as a RecordBatch.
This is useful for reverse-order scanning (e.g. last_value)
where only one row group at a time needs to be materialised.
§Errors
Returns an error if row_group is out of range or column data is corrupt.
Sourcepub fn read_projected(&self, column_names: &[&str]) -> Result<RecordBatch>
pub fn read_projected(&self, column_names: &[&str]) -> Result<RecordBatch>
Read selected columns across all row groups as a single RecordBatch.
Only the byte ranges for the requested columns are decoded and
decompressed — all other column data on disk is skipped entirely.
The timestamp column is always included even if not listed.
§Errors
Returns an error if any requested column name is not found in the segment metadata, or if column data is corrupt.
Sourcepub fn read_projected_filtered(
&self,
column_names: &[&str],
time_range: Option<(i64, i64)>,
) -> Result<RecordBatch>
pub fn read_projected_filtered( &self, column_names: &[&str], time_range: Option<(i64, i64)>, ) -> Result<RecordBatch>
Read selected columns with optional row-group-level time-range predicate pushdown.
When time_range is Some((start_ns, end_ns)), row groups whose
timestamp range does not overlap [start_ns, end_ns] are skipped
entirely — no I/O or decompression is performed for them.
Both boundaries are inclusive, matching the semantics of
chronix_query::plan::TimeRange.
This is the primary entry point for query-time segment reads where the caller already knows the desired time window.
Sourcepub fn read_projected_filtered_with_predicates(
&self,
column_names: &[&str],
time_range: Option<(i64, i64)>,
tag_predicates: &[(&str, &str)],
) -> Result<RecordBatch>
pub fn read_projected_filtered_with_predicates( &self, column_names: &[&str], time_range: Option<(i64, i64)>, tag_predicates: &[(&str, &str)], ) -> Result<RecordBatch>
Read selected columns with row-group-level time-range and tag predicate pushdown.
In addition to time-range pruning, this method also pushes tag
equality predicates down to row-group level. A row group is
skipped when a tag column’s per-block statistics indicate that
it has zero non-null values (value_count == 0), which means it
cannot possibly match an equality filter on that tag.
§Arguments
column_names— Columns to read (empty = all).time_range— Optional inclusive time range(start, end).tag_predicates— Tag equality filters as(column_name, value)pairs.
Sourcepub fn read_projected_with_zone_maps(
&self,
column_names: &[&str],
time_range: Option<(i64, i64)>,
tag_predicates: &[(&str, &str)],
field_predicates: &[FieldPredicate],
) -> Result<RecordBatch>
pub fn read_projected_with_zone_maps( &self, column_names: &[&str], time_range: Option<(i64, i64)>, tag_predicates: &[(&str, &str)], field_predicates: &[FieldPredicate], ) -> Result<RecordBatch>
Read selected columns with full predicate pushdown: time-range, tag equality, and zone-map field predicates (late materialisation).
Zone-map field predicates evaluate per-row-group column min/max statistics to skip row groups that cannot possibly match numeric comparisons. This avoids decompressing and decoding column data for entire row groups.
§Arguments
column_names— Columns to read (empty = all).time_range— Optional inclusive time range(start, end).tag_predicates— Tag equality filters as(column_name, value)pairs.field_predicates— Numeric field predicates for zone-map pruning.
Auto Trait Implementations§
impl !RefUnwindSafe for SegmentReader
impl !UnwindSafe for SegmentReader
impl Freeze for SegmentReader
impl Send for SegmentReader
impl Sync for SegmentReader
impl Unpin for SegmentReader
impl UnsafeUnpin for SegmentReader
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
Source§fn in_current_span(self) -> Instrumented<Self> ⓘ
fn in_current_span(self) -> Instrumented<Self> ⓘ
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more