Skip to content

Commit 26abc2c

Browse files
committed
add cache for arc ptr
1 parent 02ff545 commit 26abc2c

1 file changed

Lines changed: 27 additions & 8 deletions

File tree

  • datafusion/physical-plan/src/aggregates/group_values/multi_group_by

datafusion/physical-plan/src/aggregates/group_values/multi_group_by/dictionary.rs

Lines changed: 27 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ use crate::aggregates::group_values::multi_group_by::GroupColumn;
2020
use arrow::array::{
2121
Array, ArrayRef, AsArray, BooleanBufferBuilder, DictionaryArray, PrimitiveArray,
2222
};
23+
use arrow::compute::concat;
2324
use arrow::datatypes::{ArrowDictionaryKeyType, ArrowNativeType, Field};
2425
use datafusion_common::Result;
2526
use std::marker::PhantomData;
@@ -28,6 +29,8 @@ use std::sync::Arc;
2829
pub struct DictionaryGroupValuesColumn<K: ArrowDictionaryKeyType + Send + Sync> {
2930
inner: Box<dyn GroupColumn>,
3031
null_array: ArrayRef,
32+
cached_values: Option<ArrayRef>,
33+
cached_combined: Option<ArrayRef>,
3134
_phantom: PhantomData<K>,
3235
}
3336

@@ -37,10 +40,26 @@ impl<K: ArrowDictionaryKeyType + Send + Sync> DictionaryGroupValuesColumn<K> {
3740
Self {
3841
inner,
3942
null_array,
43+
cached_values: None,
44+
cached_combined: None,
4045
_phantom: PhantomData,
4146
}
4247
}
4348

49+
#[inline]
50+
fn get_combined(&mut self, values: &ArrayRef) -> Result<ArrayRef> {
51+
let is_cached = self
52+
.cached_values
53+
.as_ref()
54+
.is_some_and(|cached| Arc::ptr_eq(cached, values));
55+
if !is_cached {
56+
self.cached_combined =
57+
Some(concat(&[values.as_ref(), self.null_array.as_ref()])?);
58+
self.cached_values = Some(Arc::clone(values));
59+
}
60+
Ok(Arc::clone(self.cached_combined.as_ref().unwrap()))
61+
}
62+
4463
#[inline]
4564
fn into_dict(values: ArrayRef) -> ArrayRef {
4665
// at some point in the future we may want to support bumping the key types
@@ -119,14 +138,14 @@ impl<K: ArrowDictionaryKeyType + Send + Sync> GroupColumn
119138
rows.iter().map(|&r| keys.value(r).as_usize()).collect();
120139
self.inner.vectorized_append(dict.values(), &key_indices)
121140
} else {
122-
let values = dict.values();
123-
for &row in rows {
124-
match dict.key(row) {
125-
None => self.inner.append_val(&self.null_array, 0)?,
126-
Some(k) => self.inner.append_val(values, k)?,
127-
}
128-
}
129-
Ok(())
141+
let combined = self.get_combined(dict.values())?;
142+
// last element of combined is always the null sentinel appended by get_combined
143+
let null_idx = combined.len() - 1;
144+
let key_indices: Vec<usize> = rows
145+
.iter()
146+
.map(|&r| dict.key(r).unwrap_or(null_idx))
147+
.collect();
148+
self.inner.vectorized_append(&combined, &key_indices)
130149
}
131150
}
132151

0 commit comments

Comments
 (0)