kumarUjjawal commented on code in PR #24476:
URL: https://github.com/apache/datafusion/pull/24476#discussion_r3874027199


##########
datafusion/physical-plan/src/aggregates/group_values/multi_group_by/dictionary.rs:
##########
@@ -733,6 +770,61 @@ mod tests {
         );
     }
 
+    #[test]
+    fn take_n_reuses_leftover_values_and_treats_emitted_values_as_new() {
+        let mut col = utf8_col();
+        col.vectorized_append(
+            &i32_dict(
+                &[Some(0), Some(1), Some(2)],
+                &[Some("a"), Some("b"), Some("c")],
+            ),
+            &[0, 1, 2],
+        )
+        .unwrap();
+        let _ = col.take_n(2);
+
+        let again = i32_dict(&[Some(0), Some(1)], &[Some("c"), Some("a")]);
+        col.vectorized_append(&again, &[0, 1]).unwrap();
+
+        let mut buf = all_true(2);
+        col.vectorized_equal_to(&[0, 1], &again, &[0, 1], &mut buf);
+        assert_eq!(bool_vec(&buf), vec![true, false]);
+
+        let out = Box::new(col).build();
+        assert_eq!(
+            str_values(&out),
+            vec![Some("c".into()), Some("c".into()), Some("a".into())]
+        );
+    }
+
+    #[test]
+    fn take_n_utf8_view_emits_and_interns_leftover_values() {

Review Comment:
    This test passes when you delete the `gc_array` call. It asserts on values 
and on equality, and `gc()` changes only the buffer layout, not the data. The 
three strings also hold about 60 bytes of
     non-inline data. `should_gc_view_array` needs more than 10 KB, so the 
compaction never runs here. Could the test build enough non-inline data to pass 
that limit, then assert on
     `get_buffer_memory_size()` of the emitted array?



##########
datafusion/physical-plan/src/aggregates/group_values/multi_group_by/dictionary.rs:
##########
@@ -500,6 +509,11 @@ impl<K: ArrowDictionaryKeyType + Send + Sync> GroupColumn
             Int64Array::from_iter(emit_new_to_old.iter().map(|&i| i as i64));
         let compact_emit_values =
             take(&*all_inner_values, &emit_indices, None).expect("take emit 
values");
+        // take() keeps original view buffers while spill's gc_array copies 
only when worth it
+        let gced_compact_emit_values = gc_array(&compact_emit_values)

Review Comment:
   Would it work to add a case with `Utf8View` values longer than twelve bytes, 
and enough of them to pass the 10 KB limit?



##########
datafusion/physical-plan/src/aggregates/group_values/multi_group_by/dictionary.rs:
##########
@@ -536,28 +552,33 @@ impl<K: ArrowDictionaryKeyType + Send + Sync> GroupColumn
             new_to_old.push(old);
         }
 
-        self.value_dedup = HashTable::new();
-        self.value_dedup_size = 0;
-        self.null_inner_slot = None;
-
-        self.hash_values(&all_inner_values);
+        let leftover_non_null_len = new_to_old.len() - null_old_slot.is_some() 
as usize;
+        let old_hashes = std::mem::take(&mut self.slot_hash);
+        // Remapping entries from current slot
+        self.value_dedup.retain(|(_, slot)| {

Review Comment:
   would a `shrink_to_fit` help here, with the accounting corrected to match?



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


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

Reply via email to