This is an automated email from the ASF dual-hosted git repository.

Rachelint pushed a commit to branch improve-compare-in-view-map
in repository https://gitbox.apache.org/repos/asf/datafusion.git


The following commit(s) were added to refs/heads/improve-compare-in-view-map by 
this push:
     new 8643ebe4e1 Cache byte view map batch lookups
8643ebe4e1 is described below

commit 8643ebe4e13142f9ca41f54b8e91b018fb5aeebb
Author: kamille <[email protected]>
AuthorDate: Thu Jul 9 06:52:41 2026 +0800

    Cache byte view map batch lookups
---
 .../physical-expr-common/src/binary_view_map.rs    | 89 +++++++---------------
 1 file changed, 29 insertions(+), 60 deletions(-)

diff --git a/datafusion/physical-expr-common/src/binary_view_map.rs 
b/datafusion/physical-expr-common/src/binary_view_map.rs
index 4cbf827e38..2c54998330 100644
--- a/datafusion/physical-expr-common/src/binary_view_map.rs
+++ b/datafusion/physical-expr-common/src/binary_view_map.rs
@@ -119,49 +119,6 @@ impl ArrowBytesViewSet {
 /// Max size of the in-progress buffer before flushing to completed buffers
 const BYTE_VIEW_MAX_BLOCK_SIZE: usize = 2 * 1024 * 1024;
 
-#[derive(Debug)]
-struct BatchNonInlineCompareStats<V>
-where
-    V: Debug + PartialEq + Eq + Clone + Copy + Default,
-{
-    num_non_inline_compares: usize,
-    target_group_counts: Vec<(V, usize)>,
-}
-
-impl<V> BatchNonInlineCompareStats<V>
-where
-    V: Debug + PartialEq + Eq + Clone + Copy + Default,
-{
-    fn new() -> Self {
-        Self {
-            num_non_inline_compares: 0,
-            target_group_counts: Vec::new(),
-        }
-    }
-
-    fn record(&mut self, target_group_id: V) {
-        self.num_non_inline_compares += 1;
-        if let Some((_, count)) = self
-            .target_group_counts
-            .iter_mut()
-            .find(|(group_id, _)| *group_id == target_group_id)
-        {
-            *count += 1;
-        } else {
-            self.target_group_counts.push((target_group_id, 1));
-        }
-    }
-
-    fn num_target_groups(&self) -> usize {
-        self.target_group_counts.len()
-    }
-
-    fn num_redundant_compares(&self) -> usize {
-        self.num_non_inline_compares
-            .saturating_sub(self.num_target_groups())
-    }
-}
-
 pub struct ArrowBytesViewMap<V>
 where
     V: Debug + PartialEq + Eq + Clone + Copy + Default,
@@ -316,7 +273,8 @@ where
         assert_eq!(values.len(), self.hashes_buffer.len());
 
         let input_has_buffers = !values.data_buffers().is_empty();
-        let mut batch_non_inline_compare_stats = 
BatchNonInlineCompareStats::new();
+        let mut input_view_to_payload =
+            hashbrown::hash_table::HashTable::<(u128, V)>::new();
         for i in 0..values.len() {
             let view_u128 = input_views[i];
             let hash = self.hashes_buffer[i];
@@ -340,6 +298,20 @@ where
             // Extract length from the view (first 4 bytes of u128 in 
little-endian)
             let len = view_u128 as u32;
 
+            let cached_payload = if input_has_buffers && len > 12 {
+                let view_hash = Self::hash_input_view(view_u128);
+                input_view_to_payload
+                    .find(view_hash, |(cached_view, _)| *cached_view == 
view_u128)
+                    .map(|(_, payload)| *payload)
+            } else {
+                None
+            };
+
+            if let Some(payload) = cached_payload {
+                observe_payload_fn(payload);
+                continue;
+            }
+
             // Check if value already exists
             let maybe_payload = {
                 let completed = &self.completed;
@@ -354,22 +326,18 @@ where
                         if input_has_buffers {
                             Self::view_equal_to_input::<B, true>(
                                 header.view,
-                                header.payload,
                                 completed,
                                 in_progress,
                                 values,
                                 i,
-                                &mut batch_non_inline_compare_stats,
                             )
                         } else {
                             Self::view_equal_to_input::<B, false>(
                                 header.view,
-                                header.payload,
                                 completed,
                                 in_progress,
                                 values,
                                 i,
-                                &mut batch_non_inline_compare_stats,
                             )
                         }
                     })
@@ -412,28 +380,31 @@ where
                     .insert_accounted(new_header, |h| h.hash, &mut 
self.map_size);
                 payload
             };
+            if input_has_buffers && len > 12 {
+                let view_hash = Self::hash_input_view(view_u128);
+                input_view_to_payload.insert_unique(
+                    view_hash,
+                    (view_u128, payload),
+                    |(cached_view, _)| Self::hash_input_view(*cached_view),
+                );
+            }
+
             observe_payload_fn(payload);
         }
+    }
 
-        dbg!((
-            "ArrowBytesViewMap::insert_if_new_inner",
-            values.len(),
-            batch_non_inline_compare_stats.num_non_inline_compares,
-            batch_non_inline_compare_stats.num_target_groups(),
-            batch_non_inline_compare_stats.num_redundant_compares(),
-            &batch_non_inline_compare_stats.target_group_counts,
-        ));
+    #[inline(always)]
+    fn hash_input_view(view: u128) -> u64 {
+        (view as u64) ^ ((view >> 64) as u64)
     }
 
     #[inline(always)]
     fn view_equal_to_input<B: ByteViewType, const HAS_BUFFERS: bool>(
         exist_view: u128,
-        target_group_id: V,
         completed: &[Buffer],
         in_progress: &[u8],
         array: &GenericByteViewArray<B>,
         rhs_row: usize,
-        batch_non_inline_compare_stats: &mut BatchNonInlineCompareStats<V>,
     ) -> bool {
         // SAFETY: caller ensures `rhs_row` is valid.
         let input_view = unsafe { *array.views().get_unchecked(rhs_row) };
@@ -460,8 +431,6 @@ where
             return false;
         }
 
-        batch_non_inline_compare_stats.record(target_group_id);
-
         let exist_full = {
             let byte_view = ByteView::from(exist_view);
             let buffer_index = byte_view.buffer_index as usize;


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to