Skip to content

Commit 702b700

Browse files
committed
replace UninitRange for unpack decode
Signed-off-by: Connor Tsui <[email protected]>
1 parent 86f3bf9 commit 702b700

File tree

3 files changed

+23
-13
lines changed

3 files changed

+23
-13
lines changed

encodings/fastlanes/src/bitpacking/array/bitpack_decompress.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,15 +65,18 @@ pub(crate) fn unpack_into<T: BitPacked>(
6565
uninit_range.append_mask(array.validity_mask());
6666
}
6767

68+
// SAFETY: `decode_into` will initialize all values in this range.
69+
let uninit_slice = unsafe { uninit_range.slice_uninit_mut(0, array.len()) };
70+
6871
let mut bit_packed_iter = array.unpacked_chunks();
69-
bit_packed_iter.decode_into(&mut uninit_range);
72+
bit_packed_iter.decode_into(uninit_slice);
7073

7174
if let Some(patches) = array.patches() {
7275
apply_patches(&mut uninit_range, patches);
7376
};
7477

7578
// SAFETY: We have set a correct validity mask via `append_mask` with `array.len()` values and
76-
// initialized the same number of values needed via calls to `copy_from_slice`.
79+
// initialized the same number of values needed via `decode_into`.
7780
unsafe {
7881
uninit_range.finish();
7982
}

encodings/fastlanes/src/bitpacking/array/unpack_iter.rs

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ use lending_iterator::gat;
99
use lending_iterator::prelude::Item;
1010
#[gat(Item)]
1111
use lending_iterator::prelude::LendingIterator;
12-
use vortex_array::builders::UninitRange;
1312
use vortex_buffer::ByteBuffer;
1413
use vortex_dtype::PhysicalPType;
1514

@@ -159,29 +158,34 @@ impl<T: PhysicalPType, S: UnpackStrategy<T>> UnpackedChunks<T, S> {
159158

160159
/// Decode all chunks (initial, full, and trailer) into the output range.
161160
/// This consolidates the logic for handling all three chunk types in one place.
162-
pub fn decode_into(&mut self, output: &mut UninitRange<T>) {
161+
pub fn decode_into(&mut self, output: &mut [MaybeUninit<T>]) {
163162
let mut local_idx = 0;
164163

165164
// Handle initial partial chunk if present
166165
if let Some(initial) = self.initial() {
167-
output.copy_from_slice(0, initial);
168166
local_idx = initial.len();
167+
168+
// SAFETY: &[T] and &[MaybeUninit<T>] have the same layout.
169+
let uninit_initial: &[MaybeUninit<T>] = unsafe { mem::transmute(initial) };
170+
output[..uninit_initial.len()].copy_from_slice(uninit_initial);
169171
}
170172

171173
// Handle full chunks
172174
local_idx = self.decode_full_chunks_into_at(output, local_idx);
173175

174176
// Handle trailing partial chunk if present
175177
if let Some(trailer) = self.trailer() {
176-
output.copy_from_slice(local_idx, trailer);
178+
// SAFETY: &[T] and &[MaybeUninit<T>] have the same layout.
179+
let uninit_trailer: &[MaybeUninit<T>] = unsafe { mem::transmute(trailer) };
180+
output[local_idx..][..uninit_trailer.len()].copy_from_slice(uninit_trailer);
177181
}
178182
}
179183

180184
/// Unpack full chunks into output range starting at the given index.
181185
/// Returns the next local index to write to.
182186
fn decode_full_chunks_into_at(
183187
&mut self,
184-
output: &mut UninitRange<T>,
188+
output: &mut [MaybeUninit<T>],
185189
start_idx: usize,
186190
) -> usize {
187191
// If there's only one chunk it has been handled already by `initial` method
@@ -204,8 +208,7 @@ impl<T: PhysicalPType, S: UnpackStrategy<T>> UnpackedChunks<T, S> {
204208
let chunk = &packed_slice[i * elems_per_chunk..][..elems_per_chunk];
205209

206210
unsafe {
207-
// SAFETY: We're about to initialize CHUNK_SIZE elements at local_idx.
208-
let uninit_dst = output.slice_uninit_mut(local_idx, CHUNK_SIZE);
211+
let uninit_dst = &mut output[local_idx..local_idx + CHUNK_SIZE];
209212
// SAFETY: &[T] and &[MaybeUninit<T>] have the same layout
210213
let dst: &mut [T::Physical] = mem::transmute(uninit_dst);
211214
self.strategy.unpack_chunk(self.bit_width, chunk, dst);

encodings/fastlanes/src/for/compress.rs

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -124,19 +124,23 @@ fn fused_decompress<T: PhysicalPType<Physical = T> + UnsignedPType + FoR + Wrapp
124124

125125
let mut builder = PrimitiveBuilder::<T>::with_capacity(for_.dtype().nullability(), bp.len());
126126
let mut uninit_range = builder.uninit_range(bp.len());
127-
128-
// Decode all chunks (initial, full, and trailer) in one call
129-
unpacked.decode_into(&mut uninit_range);
130-
131127
unsafe {
132128
// Append a dense null Mask.
133129
uninit_range.append_mask(bp.validity_mask());
134130
}
135131

132+
// SAFETY: `decode_into` will initialize all values in this range.
133+
let uninit_slice = unsafe { uninit_range.slice_uninit_mut(0, bp.len()) };
134+
135+
// Decode all chunks (initial, full, and trailer) in one call
136+
unpacked.decode_into(uninit_slice);
137+
136138
if let Some(patches) = bp.patches() {
137139
bitpack_decompress::apply_patches_fn(&mut uninit_range, patches, |v| v.wrapping_add(&ref_));
138140
};
139141

142+
// SAFETY: We have set a correct validity mask via `append_mask` with `array.len()` values and
143+
// initialized the same number of values needed via `decode_into`.
140144
unsafe {
141145
uninit_range.finish();
142146
}

0 commit comments

Comments
 (0)