viirya commented on code in PR #7234:
URL: https://github.com/apache/datafusion-comet/pull/7234#discussion_r4381374872


##########
native/shuffle/src/writers/shuffle_block_writer.rs:
##########
@@ -154,6 +192,17 @@ impl ShuffleBlockWriter {
         }
     }
 
+    /// True when the schema contains a view type at any depth; see 
[`contains_view_type`].
+    ///
+    /// Arrow's IPC writer serializes every data buffer a view array 
references, whatever the
+    /// views actually point at. A batch gathered by `interleave` from many 
buffered batches

Review Comment:
   Small accuracy point on this doc. `interleave_views` only carries over the 
data buffers that the selected views actually reference. It doesn't carry all 
of the source batches' buffers. The concern is still real when the strings are 
long and come from many source batches. But "shares all of their data buffers" 
overstates it. Could this say "every data buffer the selected views reference"?



##########
native/shuffle/src/writers/buf_batch_writer.rs:
##########
@@ -46,32 +56,68 @@ pub(crate) struct BufBatchWriter<S: 
Borrow<ShuffleBlockWriter>, W: Write> {
     writer: W,
     buffer_max_size: usize,
     /// Coalesces small batches into target_batch_size before serialization.
-    /// Lazily initialized on first write to capture the schema.
+    /// Lazily initialized on first write to capture the schema. Never set in 
passthrough mode.
     coalescer: Option<BatchCoalescer>,
-    /// Target batch size for coalescing
-    batch_size: usize,
+    /// Target batch size for coalescing; `None` selects passthrough mode.
+    coalesce_batch_size: Option<usize>,
     /// Address of the scratch `Vec` seen on first use; every later call must 
pass the same
     /// one, or unflushed bytes in the other buffer would be silently 
abandoned.
     #[cfg(debug_assertions)]
     scratch_addr: Option<usize>,
-    /// Running total of bytes serialized through this writer, used to report 
spilled bytes when
-    /// the underlying writer does not implement [`Seek`] (e.g. a `Box<dyn 
SpillWriter>`).
+    /// Running total of bytes serialized through this writer, used to report 
spilled bytes and
+    /// to track output offsets without a `Seek` on the underlying writer.
     total_bytes_written: u64,
 }
 
 impl<S: Borrow<ShuffleBlockWriter>, W: Write> BufBatchWriter<S, W> {
+    /// A coalescing writer; see the type-level docs for when to use which 
mode.
     pub(crate) fn new(
         shuffle_block_writer: S,
         writer: W,
         buffer_max_size: usize,
         batch_size: usize,
+    ) -> Self {
+        Self::with_mode(
+            shuffle_block_writer,
+            writer,
+            buffer_max_size,
+            Some(batch_size),
+        )
+    }
+
+    /// A writer for one output partition of a multi-partition shuffle: 
passthrough, except for
+    /// schemas with view types, which still need the coalescer to compact 
sparse views (see
+    /// [`ShuffleBlockWriter::has_view_types`]).
+    pub(crate) fn new_for_partition(

Review Comment:
   I'm not sure the view-type exception buys much here. Three things make me 
doubt it:
   
   - Even on the coalescing path, full `batch_size` chunks skip the coalescer 
because of `with_biggest_coalesce_batch_size(Some(batch_size - 1))`, as the 
comment in `write` says. So for a view schema, only the one tail per partition 
per cycle is ever compacted. Every full chunk is written with whatever buffers 
`interleave` gave it, both before and after this PR.
   - `BatchCoalescer` only gc's top-level `Utf8View`/`BinaryView` columns, 
through `InProgressByteViewArray`. Everything else goes through 
`GenericInProgressArray`, whose `concat` returns the input slice unchanged when 
there is only one input. That includes a view nested in a struct or list, a 
dictionary of views, and `ListView`/`LargeListView`. Yet `has_view_types` 
matches all of those, so for them we keep the coalescer and get nothing for it.
   - As far as I can tell, view types can't reach the shuffle writer today. 
`planner.rs` casts `Utf8View` results back to `Utf8` with the note that Comet 
does not support view types yet.
   
   Would it be simpler to make the per-partition writer always pass through? 
That would mean dropping `has_view_types`, the `coalesce_batch_size` branch, 
and `for_partition_coalesces_only_view_schemas`, and leaving view handling to 
the existing round-robin planner check. If you'd rather keep the guard as 
future-proofing, could the docs say it only helps the tail of top-level view 
columns?



##########
native/shuffle/src/writers/local/spill.rs:
##########
@@ -334,7 +321,8 @@ mod tests {
         let block_writer =
             ShuffleBlockWriter::try_new(batch.schema_ref().as_ref(), 
CompressionCodec::None)
                 .unwrap();
-        // batch_size below the row count so a write serializes into the 
scratch
+        // batch_size below the row count so a view-schema write, which 
coalesces, serializes into

Review Comment:
   This helper builds an `Int64` schema, so there's no view-schema write here. 
With passthrough, every write serializes into the scratch whatever the batch 
size. Could the comment be removed or reworded? Otherwise it reads as if these 
tests exercise the coalescing path. It also means `batch_size = 10` no longer 
matters to these tests.



-- 
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