Skip to content

Commit d09d9ec

Browse files
committed
save
Signed-off-by: Andrew Duffy <andrew@a10y.dev>
1 parent d7e1145 commit d09d9ec

2 files changed

Lines changed: 43 additions & 6 deletions

File tree

vortex-array/src/arrays/patched/array.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,11 @@ impl PatchedArray {
7676
"Creating PatchedArray from Patches only supported for primitive arrays"
7777
);
7878

79+
vortex_ensure!(
80+
patches.num_patches() <= u32::MAX as usize,
81+
"PatchedArray does not support > u32::MAX patch values"
82+
);
83+
7984
let values_ptype = patches.dtype().as_ptype();
8085

8186
let TransposedPatches {

vortex-array/src/arrays/patched/vtable/mod.rs

Lines changed: 38 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ use vortex_error::VortexExpect;
1414
use vortex_error::VortexResult;
1515
use vortex_error::vortex_bail;
1616
use vortex_error::vortex_ensure;
17+
use vortex_error::vortex_err;
1718
use vortex_error::vortex_panic;
1819
use vortex_session::VortexSession;
1920

@@ -65,10 +66,29 @@ impl ValidityChild<Patched> for Patched {
6566

6667
#[derive(Clone, prost::Message)]
6768
pub struct PatchedMetadata {
68-
#[prost(uint32, tag = "1")]
69-
pub(crate) offset: u32,
69+
/// Length of the `inner` child.
70+
///
71+
/// This may not match the length of the wrapping PatchedArray, if for example
72+
/// in a filter or slice it may be sliced to the nearest chunk boundary.
73+
#[prost(uint64, tag = "1")]
74+
pub(crate) inner_len: u64,
75+
76+
/// Offset within the first chunk of `inner` where data begins.
77+
///
78+
/// This may become nonzero after slicing.
7079
#[prost(uint32, tag = "2")]
80+
pub(crate) offset: u32,
81+
82+
/// Number of patches. This is the length of the `indices` and `values` children.
83+
#[prost(uint32, tag = "3")]
7184
pub(crate) n_patches: u32,
85+
86+
/// Number of lanes the patches get spread over.
87+
///
88+
/// By default, this is either 16 or 32 depending on the width of the type, but may change
89+
/// in the future, so we save it on write.
90+
#[prost(uint32, tag = "4")]
91+
pub(crate) n_lanes: u32,
7292
}
7393

7494
impl VTable for Patched {
@@ -158,8 +178,10 @@ impl VTable for Patched {
158178
#[allow(clippy::cast_possible_truncation)]
159179
fn metadata(array: &Self::Array) -> VortexResult<Self::Metadata> {
160180
Ok(ProstMetadata(PatchedMetadata {
181+
inner_len: array.inner.len() as u64,
161182
offset: array.offset as u32,
162183
n_patches: array.indices.len() as u32,
184+
n_lanes: array.n_lanes as u32,
163185
}))
164186
}
165187

@@ -243,22 +265,32 @@ impl VTable for Patched {
243265
buffers: &[BufferHandle],
244266
children: &dyn ArrayChildren,
245267
) -> VortexResult<PatchedArray> {
246-
let n_chunks = len.div_ceil(1024);
247-
let n_lanes = match_each_native_ptype!(dtype.as_ptype(), |P| { patch_lanes::<P>() });
268+
let inner_len = usize::try_from(metadata.inner_len).map_err(|_| {
269+
vortex_err!(
270+
"PatchedMetadata inner_len overflows usize: {}",
271+
metadata.inner_len
272+
)
273+
})?;
274+
let offset = metadata.offset as usize;
275+
276+
// n_chunks should correspond to the chunk in the `inner`.
277+
// After slicing when offset > 0, there may be additional chunks.
278+
let n_chunks = (len + offset).div_ceil(1024);
279+
let n_lanes = metadata.n_lanes as usize;
248280

249281
let &[lane_offsets] = &buffers else {
250282
vortex_bail!("invalid buffer count for PatchedArray");
251283
};
252284

253-
let inner = children.get(0, dtype, len)?;
285+
let inner = children.get(0, dtype, inner_len)?;
254286
let indices = children.get(1, PType::U16.into(), metadata.n_patches as usize)?;
255287
let values = children.get(2, dtype, metadata.n_patches as usize)?;
256288

257289
Ok(PatchedArray {
258290
inner,
259291
n_chunks,
260292
n_lanes,
261-
offset: metadata.offset as usize,
293+
offset,
262294
len,
263295
lane_offsets: lane_offsets.clone(),
264296
indices,

0 commit comments

Comments
 (0)