Scan a shared-format segment for timeseries data with time-range filtering. Uses block-level predicate pushdown: blocks whose timestamp range doesn't overlap `[start_ms, end_ms]` are skipped entirely (not decompressed). `ts_col_idx` is the timestamp column index (typically 0). `val_col_idx` is the value column index to read.
(
segment_data: &[u8],
ts_col_idx: usize,
val_col_idx: usize,
start_ms: i64,
end_ms: i64,
)
| 162 | /// `ts_col_idx` is the timestamp column index (typically 0). |
| 163 | /// `val_col_idx` is the value column index to read. |
| 164 | pub fn scan_shared_segment( |
| 165 | segment_data: &[u8], |
| 166 | ts_col_idx: usize, |
| 167 | val_col_idx: usize, |
| 168 | start_ms: i64, |
| 169 | end_ms: i64, |
| 170 | ) -> Result<TsScanResult, nodedb_columnar::ColumnarError> { |
| 171 | let reader = SegmentReader::open(segment_data)?; |
| 172 | |
| 173 | // Build predicates for block-level time-range skip. |
| 174 | // Timestamp blocks with max < start or min > end can be skipped. |
| 175 | // Use the lossless i64 constructors so that timestamps outside ±2^53 |
| 176 | // (which don't round-trip through f64 exactly) are compared correctly |
| 177 | // against the exact min_i64/max_i64 fields written by BlockStats::integer(). |
| 178 | let predicates = vec![ |
| 179 | ScanPredicate::gte_i64(ts_col_idx, start_ms), |
| 180 | ScanPredicate::lte_i64(ts_col_idx, end_ms), |
| 181 | ]; |
| 182 | |
| 183 | // Read timestamp column with predicate pushdown. |
| 184 | let ts_decoded = reader.read_column_filtered(ts_col_idx, &predicates)?; |
| 185 | let (timestamps, ts_valid) = decoded_to_i64(ts_decoded); |
| 186 | |
| 187 | // Read value column with same predicate pushdown (ensures row alignment). |
| 188 | let val_decoded = reader.read_column_filtered(val_col_idx, &predicates)?; |
| 189 | let (values, val_valid) = decoded_to_f64(val_decoded); |
| 190 | |
| 191 | Ok(TsScanResult { |
| 192 | timestamps, |
| 193 | values, |
| 194 | ts_valid, |
| 195 | val_valid, |
| 196 | }) |
| 197 | } |
| 198 | |
| 199 | /// Scan a shared-format segment, returning only rows within a time range. |
| 200 | /// |