2929
3030public abstract class ByteStreamSplitValuesWriter extends ValuesWriter {
3131
32+ /**
33+ * Batch size for buffered scatter writes. Values are accumulated in a batch buffer
34+ * and flushed as bulk {@code write(byte[], off, len)} calls to each stream.
35+ */
36+ private static final int BATCH_SIZE = 64 ;
37+
3238 protected final int numStreams ;
3339 protected final int elementSizeInBytes ;
34- private final CapacityByteArrayOutputStream [] byteStreams ;
40+ protected final CapacityByteArrayOutputStream [] byteStreams ;
3541
3642 public ByteStreamSplitValuesWriter (
3743 int elementSizeInBytes , int initialCapacity , int pageSize , ByteBufferAllocator allocator ) {
@@ -176,6 +182,8 @@ public String memUsageString(String prefix) {
176182
177183 public static class FixedLenByteArrayByteStreamSplitValuesWriter extends ByteStreamSplitValuesWriter {
178184 private final int length ;
185+ private byte [][] batchBufs ; // [stream][batchIndex] scratch buffers
186+ private int flbaBatchCount ;
179187
180188 public FixedLenByteArrayByteStreamSplitValuesWriter (
181189 int length , int initialCapacity , int pageSize , ByteBufferAllocator allocator ) {
@@ -187,7 +195,69 @@ public FixedLenByteArrayByteStreamSplitValuesWriter(
187195 public final void writeBytes (Binary v ) {
188196 assert (v .length () == length )
189197 : ("Fixed Binary size " + v .length () + " does not match field type length " + length );
190- super .scatterBytes (v .getBytesUnsafe ());
198+ if (batchBufs == null ) {
199+ batchBufs = new byte [length ][BATCH_SIZE ];
200+ }
201+ byte [] bytes = v .getBytesUnsafe ();
202+ for (int stream = 0 ; stream < length ; stream ++) {
203+ batchBufs [stream ][flbaBatchCount ] = bytes [stream ];
204+ }
205+ flbaBatchCount ++;
206+ if (flbaBatchCount == BATCH_SIZE ) {
207+ flushFlbaBatch ();
208+ }
209+ }
210+
211+ @ Override
212+ public void writeBinaries (Binary [] values , int offset , int len ) {
213+ if (batchBufs == null ) {
214+ batchBufs = new byte [length ][BATCH_SIZE ];
215+ }
216+ for (int i = offset ; i < offset + len ; i ++) {
217+ Binary v = values [i ];
218+ assert (v .length () == length )
219+ : ("Fixed Binary size " + v .length () + " does not match field type length " + length );
220+ byte [] bytes = v .getBytesUnsafe ();
221+ for (int stream = 0 ; stream < length ; stream ++) {
222+ batchBufs [stream ][flbaBatchCount ] = bytes [stream ];
223+ }
224+ flbaBatchCount ++;
225+ if (flbaBatchCount == BATCH_SIZE ) {
226+ flushFlbaBatch ();
227+ }
228+ }
229+ }
230+
231+ private void flushFlbaBatch () {
232+ if (flbaBatchCount == 0 ) return ;
233+ final int count = flbaBatchCount ;
234+ for (int stream = 0 ; stream < length ; stream ++) {
235+ byteStreams [stream ].write (batchBufs [stream ], 0 , count );
236+ }
237+ flbaBatchCount = 0 ;
238+ }
239+
240+ @ Override
241+ public BytesInput getBytes () {
242+ flushFlbaBatch ();
243+ return super .getBytes ();
244+ }
245+
246+ @ Override
247+ public void reset () {
248+ flbaBatchCount = 0 ;
249+ super .reset ();
250+ }
251+
252+ @ Override
253+ public void close () {
254+ flbaBatchCount = 0 ;
255+ super .close ();
256+ }
257+
258+ @ Override
259+ public long getBufferedSize () {
260+ return super .getBufferedSize () + (long ) flbaBatchCount * length ;
191261 }
192262
193263 @ Override
0 commit comments