You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@datafusion.apache.org by gi...@apache.org on 2026/04/20 19:54:23 UTC

(datafusion) 01/01: test: add tests for spill file sizes to verify View GC (#21750)

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

github-merge-queue[bot] pushed a commit to branch gh-readonly-queue/main/pr-21750-a311d149bf7ee345c9c9db5486b67ff98d8ce708
in repository https://gitbox.apache.org/repos/asf/datafusion.git

commit 7acbe03efb853274aac1bdd31c1dfdc8ea647642
Author: Ratul Dawar <ra...@gmail.com>
AuthorDate: Tue Apr 21 01:24:00 2026 +0530

    test: add tests for spill file sizes to verify View GC (#21750)
    
    ## Summary
    This PR adds unit tests to verify that `StringView` and `BinaryView`
    arrays are correctly compacted (garbage collected) before being spilled
    to disk.
    
    The tests address [Issue
    #21683](https://github.com/apache/datafusion/issues/21683) by:
    1. Creating "bloated" batches with large underlying buffers.
    2. Slicing them to a small number of rows (1%).
    3. Spilling them to disk.
    4. Asserting that the resulting file size is small (proving that GC
    removed the unused "ghost" data).
    
    ## Test plan
    - Run `cargo test -p datafusion-physical-plan --lib
    spill::mod::tests::test_spill_file_size_gc_verification_string_view`
    - Run `cargo test -p datafusion-physical-plan --lib
    spill::mod::tests::test_spill_file_size_gc_verification_binary_view`
    
    Made with [Cursor](https://cursor.com)
---
 datafusion/physical-plan/src/spill/mod.rs | 88 +++++++++++++++++++++++++++++++
 1 file changed, 88 insertions(+)

diff --git a/datafusion/physical-plan/src/spill/mod.rs b/datafusion/physical-plan/src/spill/mod.rs
index 1c900b7579..e8c9e9167b 100644
--- a/datafusion/physical-plan/src/spill/mod.rs
+++ b/datafusion/physical-plan/src/spill/mod.rs
@@ -1421,4 +1421,92 @@ mod tests {
 
         Ok(())
     }
+
+    #[tokio::test]
+    async fn test_spill_file_size_gc_verification_string_view() -> Result<()> {
+        use arrow::array::StringViewArray;
+        use std::fs;
+
+        // 1. Setup bloated data (large buffers)
+        let num_rows = 1000;
+        let string_array: StringViewArray = (0..num_rows)
+            .map(|i| Some(format!("this_is_a_long_string_to_ensure_it_is_not_inlined_and_causes_waste_{i}")))
+            .collect();
+        let schema = Arc::new(Schema::new(vec![Field::new(
+            "s",
+            DataType::Utf8View,
+            false,
+        )]));
+        let batch = RecordBatch::try_new(
+            Arc::clone(&schema),
+            vec![Arc::new(string_array.clone()) as ArrayRef],
+        )?;
+
+        // 2. Slice it heavily (1% of the data)
+        let sliced_batch = batch.slice(0, 10);
+
+        // 3. Spill to disk using SpillManager
+        let env = Arc::new(RuntimeEnv::default());
+        let metrics = SpillMetrics::new(&ExecutionPlanMetricsSet::new(), 0);
+        let spill_manager = SpillManager::new(env, metrics, schema);
+        let spill_file = spill_manager
+            .spill_record_batch_and_finish(&[sliced_batch], "TestGC")?
+            .unwrap();
+
+        // 4. Check file size on disk
+        let file_size = fs::metadata(spill_file.path())?.len();
+
+        // The original buffer size is around 70KB.
+        // Without GC, the spill file would be > 70KB.
+        // With GC, it should be much smaller (only 10 rows of ~70 bytes each + metadata).
+        assert!(
+            file_size < 10 * 1024,
+            "Spill file is too large ({file_size} bytes)! GC might not be working."
+        );
+
+        Ok(())
+    }
+
+    #[tokio::test]
+    async fn test_spill_file_size_gc_verification_binary_view() -> Result<()> {
+        use arrow::array::BinaryViewArray;
+        use std::fs;
+
+        // 1. Setup bloated data (large buffers)
+        let num_rows = 1000;
+        let binary_array: BinaryViewArray =
+            (0..num_rows).map(|i| Some(vec![i as u8; 100])).collect();
+        let schema = Arc::new(Schema::new(vec![Field::new(
+            "b",
+            DataType::BinaryView,
+            false,
+        )]));
+        let batch = RecordBatch::try_new(
+            Arc::clone(&schema),
+            vec![Arc::new(binary_array.clone()) as ArrayRef],
+        )?;
+
+        // 2. Slice it heavily (1% of the data)
+        let sliced_batch = batch.slice(0, 10);
+
+        // 3. Spill to disk using SpillManager
+        let env = Arc::new(RuntimeEnv::default());
+        let metrics = SpillMetrics::new(&ExecutionPlanMetricsSet::new(), 0);
+        let spill_manager = SpillManager::new(env, metrics, schema);
+        let spill_file = spill_manager
+            .spill_record_batch_and_finish(&[sliced_batch], "TestGCBinary")?
+            .unwrap();
+
+        // 4. Check file size on disk
+        let file_size = fs::metadata(spill_file.path())?.len();
+
+        // Original buffer is 100KB.
+        // With GC, it should be much smaller.
+        assert!(
+            file_size < 10 * 1024,
+            "Spill file is too large ({file_size} bytes)! GC might not be working."
+        );
+
+        Ok(())
+    }
 }


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@datafusion.apache.org
For additional commands, e-mail: commits-help@datafusion.apache.org