Filter cells in `tile` to those whose coords pass every dim range. Result is a freshly-built [`SparseTile`] — dictionaries shrink to surviving values, MBR/attr_stats are recomputed.
(
schema: &ArraySchema,
tile: &SparseTile,
slice: &Slice,
)
| 90 | /// Result is a freshly-built [`SparseTile`] — dictionaries shrink to |
| 91 | /// surviving values, MBR/attr_stats are recomputed. |
| 92 | pub fn slice_sparse( |
| 93 | schema: &ArraySchema, |
| 94 | tile: &SparseTile, |
| 95 | slice: &Slice, |
| 96 | ) -> ArrayResult<SparseTile> { |
| 97 | use crate::tile::sparse_tile::RowKind; |
| 98 | let mut b = SparseTileBuilder::new(schema); |
| 99 | let n = tile.row_count(); |
| 100 | let mut live_idx = 0usize; |
| 101 | for row in 0..n { |
| 102 | // Sentinel rows carry no payload and must not be emitted into slice results. |
| 103 | if tile.row_kind(row)? != RowKind::Live { |
| 104 | continue; |
| 105 | } |
| 106 | let coord: Vec<CoordValue> = tile |
| 107 | .dim_dicts |
| 108 | .iter() |
| 109 | .map(|d| d.values[d.indices[row] as usize].clone()) |
| 110 | .collect(); |
| 111 | if !cell_in_slice(&coord, slice) { |
| 112 | live_idx += 1; |
| 113 | continue; |
| 114 | } |
| 115 | let attr_row = live_idx; |
| 116 | live_idx += 1; |
| 117 | let attrs: Vec<CellValue> = tile |
| 118 | .attr_cols |
| 119 | .iter() |
| 120 | .map(|col| col[attr_row].clone()) |
| 121 | .collect(); |
| 122 | let surrogate = tile |
| 123 | .surrogates |
| 124 | .get(row) |
| 125 | .copied() |
| 126 | .unwrap_or(nodedb_types::Surrogate::ZERO); |
| 127 | let valid_from_ms = tile.valid_from_ms.get(row).copied().unwrap_or(0); |
| 128 | let valid_until_ms = tile |
| 129 | .valid_until_ms |
| 130 | .get(row) |
| 131 | .copied() |
| 132 | .unwrap_or(nodedb_types::OPEN_UPPER); |
| 133 | b.push_row(SparseRow { |
| 134 | coord: &coord, |
| 135 | attrs: &attrs, |
| 136 | surrogate, |
| 137 | valid_from_ms, |
| 138 | valid_until_ms, |
| 139 | kind: crate::tile::sparse_tile::RowKind::Live, |
| 140 | })?; |
| 141 | } |
| 142 | Ok(b.build()) |
| 143 | } |
| 144 | |
| 145 | fn cell_in_slice(coord: &[CoordValue], slice: &Slice) -> bool { |
| 146 | for (i, range) in slice.dim_ranges.iter().enumerate() { |