Encode a single block of rows for a column.
(
col_data: &ColumnData,
_col_type: &ColumnType,
codec: ResolvedColumnCodec,
start: usize,
end: usize,
block_row_count: usize,
governor: Option<&Arc<MemoryGovernor>>,
)
| 66 | |
| 67 | /// Encode a single block of rows for a column. |
| 68 | fn encode_single_block( |
| 69 | col_data: &ColumnData, |
| 70 | _col_type: &ColumnType, |
| 71 | codec: ResolvedColumnCodec, |
| 72 | start: usize, |
| 73 | end: usize, |
| 74 | block_row_count: usize, |
| 75 | governor: Option<&Arc<MemoryGovernor>>, |
| 76 | ) -> Result<(Vec<u8>, BlockStats), ColumnarError> { |
| 77 | // Get validity slice — Cow::Owned(all-true) for non-nullable columns, |
| 78 | // Cow::Borrowed for nullable columns. Generated once per flush block. |
| 79 | let full_valid = col_data.validity_or_all_true(); |
| 80 | |
| 81 | match col_data { |
| 82 | ColumnData::Int64 { values, .. } => { |
| 83 | let slice = &values[start..end]; |
| 84 | let valid_slice = &full_valid[start..end]; |
| 85 | let null_count = valid_slice.iter().filter(|&&v| !v).count() as u32; |
| 86 | |
| 87 | let (min, max) = numeric_min_max_i64(slice, valid_slice); |
| 88 | let stats = BlockStats::integer(min, max, null_count, block_row_count as u32); |
| 89 | |
| 90 | let encoded = encode_i64_with_validity(slice, valid_slice, codec)?; |
| 91 | Ok((encoded, stats)) |
| 92 | } |
| 93 | ColumnData::Float64 { values, .. } => { |
| 94 | let slice = &values[start..end]; |
| 95 | let valid_slice = &full_valid[start..end]; |
| 96 | let null_count = valid_slice.iter().filter(|&&v| !v).count() as u32; |
| 97 | |
| 98 | let (min, max) = numeric_min_max_f64(slice, valid_slice); |
| 99 | let stats = BlockStats::numeric(min, max, null_count, block_row_count as u32); |
| 100 | |
| 101 | let encoded = encode_f64_with_validity(slice, valid_slice, codec)?; |
| 102 | Ok((encoded, stats)) |
| 103 | } |
| 104 | ColumnData::Timestamp { values, .. } => { |
| 105 | let slice = &values[start..end]; |
| 106 | let valid_slice = &full_valid[start..end]; |
| 107 | let null_count = valid_slice.iter().filter(|&&v| !v).count() as u32; |
| 108 | |
| 109 | let (min, max) = numeric_min_max_i64(slice, valid_slice); |
| 110 | let stats = BlockStats::integer(min, max, null_count, block_row_count as u32); |
| 111 | |
| 112 | let encoded = encode_i64_with_validity(slice, valid_slice, codec)?; |
| 113 | Ok((encoded, stats)) |
| 114 | } |
| 115 | ColumnData::Bool { values, .. } => { |
| 116 | let valid_slice = &full_valid[start..end]; |
| 117 | let null_count = valid_slice.iter().filter(|&&v| !v).count() as u32; |
| 118 | |
| 119 | let bool_slice = &values[start..end]; |
| 120 | let packed_len = bool_slice.len().div_ceil(8); |
| 121 | let _packed_guard = governor |
| 122 | .map(|g| g.reserve(EngineId::Columnar, packed_len)) |
| 123 | .transpose()?; |
| 124 | let mut packed = Vec::with_capacity(packed_len); |
| 125 | for chunk in bool_slice.chunks(8) { |
no test coverage detected