Skip to content

Commit 0ea6472

Browse files
joseph-isaacsclaude
andcommitted
perf(array): share one probe across a chunked patch lookup's offset reads
`Patches::search_index_chunked` read three chunk offsets out of the same array through `chunk_offset_at`, which builds an execution context and a one-off probe per call — three of each per lookup, for three reads of one small array. Read them through a single `RepeatedArrayProbe` and a single context. `chunk_offset_at` stays as the public single-read accessor. Signed-off-by: Joe Isaacs <joe.isaacs@live.co.uk> Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01UPw4v7SA2A3Ab5t9zwGbRV
1 parent be6c55e commit 0ea6472

1 file changed

Lines changed: 16 additions & 3 deletions

File tree

‎vortex-array/src/patches.rs‎

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -487,6 +487,7 @@ impl Patches {
487487
/// or the insertion point if not found.
488488
///
489489
/// Returns an error if `chunk_offsets` or `offset_within_chunk` are not set.
490+
#[allow(clippy::disallowed_methods)]
490491
fn search_index_chunked(&self, index: usize) -> VortexResult<SearchResult> {
491492
let Some(chunk_offsets) = &self.chunk_offsets else {
492493
vortex_bail!("chunk_offsets is required to be set")
@@ -502,10 +503,22 @@ impl Patches {
502503

503504
let chunk_idx = (index + self.offset % PATCH_CHUNK_SIZE) / PATCH_CHUNK_SIZE;
504505

506+
// The three reads below are of the same array, so they share one probe and one context
507+
// rather than building a pair per read as `Self::chunk_offset_at` does.
508+
let mut probe = chunk_offsets.repeated_probe();
509+
let mut ctx = legacy_session().create_execution_ctx();
510+
let mut chunk_offset_at = |idx: usize| -> VortexResult<usize> {
511+
probe
512+
.execute_scalar(idx, &mut ctx)?
513+
.as_primitive()
514+
.as_::<usize>()
515+
.ok_or_else(|| vortex_err!("chunk offset does not fit in usize"))
516+
};
517+
505518
// Patch index offsets are absolute and need to be offset by the first chunk of the current slice.
506-
let base_offset = self.chunk_offset_at(0)?;
519+
let base_offset = chunk_offset_at(0)?;
507520

508-
let patches_start_idx = (self.chunk_offset_at(chunk_idx)? - base_offset)
521+
let patches_start_idx = (chunk_offset_at(chunk_idx)? - base_offset)
509522
// Chunk offsets are only sliced off in case the slice is fully
510523
// outside of the chunk range.
511524
//
@@ -515,7 +528,7 @@ impl Patches {
515528
.saturating_sub(offset_within_chunk);
516529

517530
let patches_end_idx = if chunk_idx < chunk_offsets.len() - 1 {
518-
(self.chunk_offset_at(chunk_idx + 1)? - base_offset)
531+
(chunk_offset_at(chunk_idx + 1)? - base_offset)
519532
.saturating_sub(offset_within_chunk)
520533
.min(self.indices.len())
521534
} else {

0 commit comments

Comments
 (0)