@@ -84,6 +84,7 @@ public class QwpUdpSender implements Sender {
8484 private final UdpLineChannel channel ;
8585 private final QwpColumnWriter columnWriter = new QwpColumnWriter ();
8686 private final int maxDatagramSize ;
87+ private final boolean trackDatagramEstimate ;
8788 private final ObjList <ColumnEntry > rowJournal = new ObjList <>();
8889 private final CharSequenceObjHashMap <QwpTableBuffer > tableBuffers ;
8990
@@ -96,6 +97,8 @@ public class QwpUdpSender implements Sender {
9697 private QwpTableBuffer currentTableBuffer ;
9798 private String currentTableName ;
9899 private int estimateColumnCount ;
100+ private QwpTableBuffer .ColumnBuffer [] missingColumns = new QwpTableBuffer .ColumnBuffer [8 ];
101+ private int missingColumnCount ;
99102 private int rowJournalSize ;
100103 private long runningEstimate ;
101104
@@ -107,6 +110,7 @@ public QwpUdpSender(NetworkFacade nf, int interfaceIPv4, int sendToAddress, int
107110 this .channel = new UdpLineChannel (nf , interfaceIPv4 , sendToAddress , port , ttl );
108111 this .tableBuffers = new CharSequenceObjHashMap <>();
109112 this .maxDatagramSize = maxDatagramSize ;
113+ this .trackDatagramEstimate = maxDatagramSize > 0 ;
110114 }
111115
112116 @ Override
@@ -374,7 +378,7 @@ public Sender table(CharSequence tableName) {
374378 return this ;
375379 }
376380 ensureNoInProgressRow ("switch tables" );
377- if (maxDatagramSize > 0 && currentTableBuffer != null && currentTableBuffer .getRowCount () > 0 ) {
381+ if (trackDatagramEstimate && currentTableBuffer != null && currentTableBuffer .getRowCount () > 0 ) {
378382 flushSingleTable (currentTableName , currentTableBuffer );
379383 }
380384 cachedTimestampColumn = null ;
@@ -440,7 +444,7 @@ private void appendBooleanColumn(CharSequence name, boolean value, boolean addJo
440444 applyValueEstimate (col , sizeBefore , col .getSize (), payloadDelta );
441445 currentRowColumnCount ++;
442446
443- if (addJournal && maxDatagramSize > 0 ) {
447+ if (addJournal && trackDatagramEstimate ) {
444448 ColumnEntry e = nextJournalEntry ();
445449 e .kind = ENTRY_BOOL ;
446450 e .name = col .getName ();
@@ -458,7 +462,7 @@ private void appendDecimal128Column(CharSequence name, Decimal128 value, boolean
458462 applyValueEstimate (col , sizeBefore , col .getSize (), payloadDelta );
459463 currentRowColumnCount ++;
460464
461- if (addJournal && maxDatagramSize > 0 ) {
465+ if (addJournal && trackDatagramEstimate ) {
462466 ColumnEntry e = nextJournalEntry ();
463467 e .kind = ENTRY_DECIMAL128 ;
464468 e .name = col .getName ();
@@ -476,7 +480,7 @@ private void appendDecimal256Column(CharSequence name, Decimal256 value, boolean
476480 applyValueEstimate (col , sizeBefore , col .getSize (), payloadDelta );
477481 currentRowColumnCount ++;
478482
479- if (addJournal && maxDatagramSize > 0 ) {
483+ if (addJournal && trackDatagramEstimate ) {
480484 ColumnEntry e = nextJournalEntry ();
481485 e .kind = ENTRY_DECIMAL256 ;
482486 e .name = col .getName ();
@@ -494,7 +498,7 @@ private void appendDecimal64Column(CharSequence name, Decimal64 value, boolean a
494498 applyValueEstimate (col , sizeBefore , col .getSize (), payloadDelta );
495499 currentRowColumnCount ++;
496500
497- if (addJournal && maxDatagramSize > 0 ) {
501+ if (addJournal && trackDatagramEstimate ) {
498502 ColumnEntry e = nextJournalEntry ();
499503 e .kind = ENTRY_DECIMAL64 ;
500504 e .name = col .getName ();
@@ -527,7 +531,7 @@ private void appendDesignatedTimestamp(long value, boolean nanos, boolean addJou
527531 long payloadDelta = (long ) (col .getValueCount () - valueCountBefore ) * 8 ;
528532 applyValueEstimate (col , sizeBefore , col .getSize (), payloadDelta );
529533
530- if (addJournal && maxDatagramSize > 0 ) {
534+ if (addJournal && trackDatagramEstimate ) {
531535 ColumnEntry e = nextJournalEntry ();
532536 e .kind = nanos ? ENTRY_AT_NANOS : ENTRY_AT_MICROS ;
533537 e .longValue = value ;
@@ -563,7 +567,7 @@ private void appendDoubleArrayColumn(CharSequence name, Object value, boolean ad
563567 applyValueEstimate (col , sizeBefore , col .getSize (), payloadDelta );
564568 currentRowColumnCount ++;
565569
566- if (addJournal && maxDatagramSize > 0 ) {
570+ if (addJournal && trackDatagramEstimate ) {
567571 ColumnEntry e = nextJournalEntry ();
568572 e .kind = ENTRY_DOUBLE_ARRAY ;
569573 e .name = col .getName ();
@@ -581,7 +585,7 @@ private void appendDoubleColumn(CharSequence name, double value, boolean addJour
581585 applyValueEstimate (col , sizeBefore , col .getSize (), payloadDelta );
582586 currentRowColumnCount ++;
583587
584- if (addJournal && maxDatagramSize > 0 ) {
588+ if (addJournal && trackDatagramEstimate ) {
585589 ColumnEntry e = nextJournalEntry ();
586590 e .kind = ENTRY_DOUBLE ;
587591 e .name = col .getName ();
@@ -618,7 +622,7 @@ private void appendLongArrayColumn(CharSequence name, Object value, boolean addJ
618622 applyValueEstimate (col , sizeBefore , col .getSize (), payloadDelta );
619623 currentRowColumnCount ++;
620624
621- if (addJournal && maxDatagramSize > 0 ) {
625+ if (addJournal && trackDatagramEstimate ) {
622626 ColumnEntry e = nextJournalEntry ();
623627 e .kind = ENTRY_LONG_ARRAY ;
624628 e .name = col .getName ();
@@ -636,7 +640,7 @@ private void appendLongColumn(CharSequence name, long value, boolean addJournal)
636640 applyValueEstimate (col , sizeBefore , col .getSize (), payloadDelta );
637641 currentRowColumnCount ++;
638642
639- if (addJournal && maxDatagramSize > 0 ) {
643+ if (addJournal && trackDatagramEstimate ) {
640644 ColumnEntry e = nextJournalEntry ();
641645 e .kind = ENTRY_LONG ;
642646 e .name = col .getName ();
@@ -656,7 +660,7 @@ private void appendStringColumn(CharSequence name, CharSequence value, boolean a
656660 applyValueEstimate (col , sizeBefore , col .getSize (), payloadDelta );
657661 currentRowColumnCount ++;
658662
659- if (addJournal && maxDatagramSize > 0 ) {
663+ if (addJournal && trackDatagramEstimate ) {
660664 ColumnEntry e = nextJournalEntry ();
661665 e .kind = ENTRY_STRING ;
662666 e .name = col .getName ();
@@ -675,7 +679,7 @@ private void appendSymbolColumn(CharSequence name, CharSequence value, boolean a
675679 applyValueEstimate (col , sizeBefore , col .getSize (), payloadDelta );
676680 currentRowColumnCount ++;
677681
678- if (addJournal && maxDatagramSize > 0 ) {
682+ if (addJournal && trackDatagramEstimate ) {
679683 ColumnEntry e = nextJournalEntry ();
680684 e .kind = ENTRY_SYMBOL ;
681685 e .name = col .getName ();
@@ -693,15 +697,16 @@ private void appendTimestampColumn(CharSequence name, byte type, long value, byt
693697 applyValueEstimate (col , sizeBefore , col .getSize (), payloadDelta );
694698 currentRowColumnCount ++;
695699
696- if (addJournal && maxDatagramSize > 0 ) {
700+ if (addJournal && trackDatagramEstimate ) {
697701 ColumnEntry e = nextJournalEntry ();
698702 e .kind = journalKind ;
699703 e .name = col .getName ();
700704 e .longValue = value ;
701705 }
702706 }
703707
704- private void applyRowPaddingEstimate (int targetRows ) {
708+ private void collectMissingColumns (int targetRows ) {
709+ missingColumnCount = 0 ;
705710 for (int i = 0 , n = currentTableBuffer .getColumnCount (); i < n ; i ++) {
706711 QwpTableBuffer .ColumnBuffer col = currentTableBuffer .getColumn (i );
707712 int sizeBefore = col .getSize ();
@@ -710,6 +715,13 @@ private void applyRowPaddingEstimate(int targetRows) {
710715 continue ;
711716 }
712717
718+ ensureMissingColumnCapacity (missingColumnCount + 1 );
719+ missingColumns [missingColumnCount ++] = col ;
720+
721+ if (!trackDatagramEstimate ) {
722+ continue ;
723+ }
724+
713725 if (col .isNullable ()) {
714726 runningEstimate += bitmapBytes (sizeBefore + missing ) - bitmapBytes (sizeBefore );
715727 continue ;
@@ -721,6 +733,9 @@ private void applyRowPaddingEstimate(int targetRows) {
721733 }
722734
723735 private void applyValueEstimate (QwpTableBuffer .ColumnBuffer col , int sizeBefore , int sizeAfter , long payloadDelta ) {
736+ if (!trackDatagramEstimate ) {
737+ return ;
738+ }
724739 runningEstimate += payloadDelta ;
725740 if (col .isNullable ()) {
726741 runningEstimate += bitmapBytes (sizeAfter ) - bitmapBytes (sizeBefore );
@@ -761,16 +776,19 @@ private void commitCurrentRow() {
761776 }
762777
763778 int targetRows = currentTableBuffer .getRowCount () + 1 ;
764- applyRowPaddingEstimate (targetRows );
779+ collectMissingColumns (targetRows );
765780
766- if (maxDatagramSize > 0 ) {
781+ if (trackDatagramEstimate ) {
767782 maybeAutoFlush ();
768783 }
769784
770- currentTableBuffer .nextRow ();
771- committedEstimate = runningEstimate ;
772- committedEstimateColumnCount = estimateColumnCount ;
785+ currentTableBuffer .nextRow (missingColumns , missingColumnCount );
786+ if (trackDatagramEstimate ) {
787+ committedEstimate = runningEstimate ;
788+ committedEstimateColumnCount = estimateColumnCount ;
789+ }
773790 currentRowColumnCount = 0 ;
791+ missingColumnCount = 0 ;
774792 rowJournalSize = 0 ;
775793 }
776794
@@ -818,6 +836,21 @@ private long estimateArrayValueSize(LongArray array) {
818836 return arraySizeCounter .size ;
819837 }
820838
839+ private void ensureMissingColumnCapacity (int required ) {
840+ if (required <= missingColumns .length ) {
841+ return ;
842+ }
843+
844+ int newCapacity = missingColumns .length ;
845+ while (newCapacity < required ) {
846+ newCapacity *= 2 ;
847+ }
848+
849+ QwpTableBuffer .ColumnBuffer [] newArr = new QwpTableBuffer .ColumnBuffer [newCapacity ];
850+ System .arraycopy (missingColumns , 0 , newArr , 0 , missingColumnCount );
851+ missingColumns = newArr ;
852+ }
853+
821854 private long estimateSymbolPayloadDelta (
822855 QwpTableBuffer .ColumnBuffer col ,
823856 int valueCountBefore ,
@@ -908,7 +941,7 @@ private void maybeAutoFlush() {
908941
909942 flushSingleTable (currentTableName , currentTableBuffer );
910943 replayRowJournal ();
911- applyRowPaddingEstimate (currentTableBuffer .getRowCount () + 1 );
944+ collectMissingColumns (currentTableBuffer .getRowCount () + 1 );
912945
913946 if (runningEstimate > maxDatagramSize ) {
914947 throw singleRowTooLarge (runningEstimate );
@@ -983,6 +1016,7 @@ private void resetEstimateState() {
9831016 estimateColumnCount = 0 ;
9841017 committedEstimateColumnCount = 0 ;
9851018 currentRowColumnCount = 0 ;
1019+ missingColumnCount = 0 ;
9861020 }
9871021
9881022 private boolean hasInProgressRow () {
@@ -993,6 +1027,7 @@ private void rollbackEstimateToCommitted() {
9931027 runningEstimate = committedEstimate ;
9941028 estimateColumnCount = committedEstimateColumnCount ;
9951029 currentRowColumnCount = 0 ;
1030+ missingColumnCount = 0 ;
9961031 }
9971032
9981033 private LineSenderException singleRowTooLarge (long estimate ) {
@@ -1003,6 +1038,10 @@ private LineSenderException singleRowTooLarge(long estimate) {
10031038 }
10041039
10051040 private void syncSchemaEstimate () {
1041+ if (!trackDatagramEstimate ) {
1042+ return ;
1043+ }
1044+
10061045 int newColumnCount = currentTableBuffer .getColumnCount ();
10071046 if (newColumnCount == estimateColumnCount ) {
10081047 return ;
0 commit comments