@@ -583,7 +583,7 @@ public static class ColumnBuffer implements QuietCloseable {
583583 private byte [] arrayDims ;
584584 private int arrayShapeOffset ;
585585 private int [] arrayShapes ;
586- // Off-heap auxiliary buffer for global symbol IDs (SYMBOL type only)
586+ // Optional auxiliary buffer used by symbol encoders that need sideband IDs.
587587 private OffHeapAppendMemory auxBuffer ;
588588 // Off-heap data buffer for fixed-width types
589589 private OffHeapAppendMemory dataBuffer ;
@@ -601,10 +601,11 @@ public static class ColumnBuffer implements QuietCloseable {
601601 private long nullBufPtr ;
602602 private QwpWebSocketSender sender ;
603603 private int size ; // Total row count (including nulls)
604+ // Symbol specific (dictionary stays on-heap)
605+ private boolean storeGlobalSymbolIdsOnly ;
604606 private OffHeapAppendMemory stringData ;
605607 // Off-heap storage for string/varchar column data
606608 private OffHeapAppendMemory stringOffsets ;
607- // Symbol specific (dictionary stays on-heap)
608609 private CharSequenceIntHashMap symbolDict ;
609610 private ObjList <String > symbolList ;
610611 private StringSink symbolLookupSink ;
@@ -1087,6 +1088,9 @@ public void addSymbol(CharSequence value) {
10871088 addSymbolWithGlobalId (value , globalId );
10881089 return ;
10891090 }
1091+ if (storeGlobalSymbolIdsOnly ) {
1092+ throw new LineSenderException ("column '" + name + "' cannot mix global symbol IDs with local symbol dictionary values" );
1093+ }
10901094 int idx = getOrAddLocalSymbol (value );
10911095 dataBuffer .putInt (idx );
10921096 valueCount ++;
@@ -1114,6 +1118,9 @@ public void addSymbolUtf8(long ptr, int len) {
11141118 addSymbolWithGlobalId (lookupSink , globalId );
11151119 return ;
11161120 }
1121+ if (storeGlobalSymbolIdsOnly ) {
1122+ throw new LineSenderException ("column '" + name + "' cannot mix global symbol IDs with local symbol dictionary values" );
1123+ }
11171124 int idx = getOrAddLocalSymbol (lookupSink );
11181125 dataBuffer .putInt (idx );
11191126 valueCount ++;
@@ -1125,13 +1132,27 @@ public void addSymbolWithGlobalId(CharSequence value, int globalId) {
11251132 addNull ();
11261133 return ;
11271134 }
1128- int localIdx = getOrAddLocalSymbol (value );
1129- dataBuffer .putInt (localIdx );
1130-
11311135 if (auxBuffer == null ) {
11321136 auxBuffer = new OffHeapAppendMemory (64 );
11331137 }
1134- auxBuffer .putInt (globalId );
1138+ if (!storeGlobalSymbolIdsOnly ) {
1139+ if (symbolList != null && symbolList .size () > 0 ) {
1140+ int localIdx = getOrAddLocalSymbol (value );
1141+ dataBuffer .putInt (localIdx );
1142+ if (auxBuffer == null ) {
1143+ auxBuffer = new OffHeapAppendMemory (64 );
1144+ }
1145+ auxBuffer .putInt (globalId );
1146+ if (globalId > maxGlobalSymbolId ) {
1147+ maxGlobalSymbolId = globalId ;
1148+ }
1149+ valueCount ++;
1150+ size ++;
1151+ return ;
1152+ }
1153+ storeGlobalSymbolIdsOnly = true ;
1154+ }
1155+ dataBuffer .putInt (globalId );
11351156
11361157 if (globalId > maxGlobalSymbolId ) {
11371158 maxGlobalSymbolId = globalId ;
@@ -1174,6 +1195,18 @@ public void close() {
11741195 }
11751196 }
11761197
1198+ public void ensureNullBitmapCapacity (int minRows ) {
1199+ if (nullBufPtr == 0 || nullBufCapRows >= minRows ) {
1200+ return ;
1201+ }
1202+ int newCapRows = Math .max (nullBufCapRows * 2 , ((minRows + 63 ) >>> 6 ) << 6 );
1203+ long newSizeBytes = (long ) newCapRows >>> 3 ;
1204+ long oldSizeBytes = (long ) nullBufCapRows >>> 3 ;
1205+ nullBufPtr = Unsafe .realloc (nullBufPtr , oldSizeBytes , newSizeBytes , MemoryTag .NATIVE_ILP_RSS );
1206+ Vect .memset (nullBufPtr + oldSizeBytes , newSizeBytes - oldSizeBytes , 0 );
1207+ nullBufCapRows = newCapRows ;
1208+ }
1209+
11771210 public int getArrayDataOffset () {
11781211 return arrayDataOffset ;
11791212 }
@@ -1295,6 +1328,9 @@ public String[] getSymbolDictionary() {
12951328 }
12961329
12971330 public int getSymbolDictionarySize () {
1331+ if (storeGlobalSymbolIdsOnly ) {
1332+ return 0 ;
1333+ }
12981334 return symbolList != null ? symbolList .size () : 0 ;
12991335 }
13001336
@@ -1347,6 +1383,7 @@ public void reset() {
13471383 symbolDict .clear ();
13481384 symbolList .clear ();
13491385 }
1386+ storeGlobalSymbolIdsOnly = false ;
13501387 maxGlobalSymbolId = -1 ;
13511388 arrayShapeOffset = 0 ;
13521389 arrayDataOffset = 0 ;
@@ -1463,6 +1500,7 @@ public void truncateTo(int newSize) {
14631500 decimalScale = -1 ;
14641501 geohashPrecision = -1 ;
14651502 maxGlobalSymbolId = -1 ;
1503+ storeGlobalSymbolIdsOnly = false ;
14661504 if (symbolDict != null ) {
14671505 symbolDict .clear ();
14681506 symbolList .clear ();
@@ -1674,18 +1712,6 @@ private void ensureArrayCapacity(int nDims, int dataElements) {
16741712 }
16751713 }
16761714
1677- public void ensureNullBitmapCapacity (int minRows ) {
1678- if (nullBufPtr == 0 || nullBufCapRows >= minRows ) {
1679- return ;
1680- }
1681- int newCapRows = Math .max (nullBufCapRows * 2 , ((minRows + 63 ) >>> 6 ) << 6 );
1682- long newSizeBytes = (long ) newCapRows >>> 3 ;
1683- long oldSizeBytes = (long ) nullBufCapRows >>> 3 ;
1684- nullBufPtr = Unsafe .realloc (nullBufPtr , oldSizeBytes , newSizeBytes , MemoryTag .NATIVE_ILP_RSS );
1685- Vect .memset (nullBufPtr + oldSizeBytes , newSizeBytes - oldSizeBytes , 0 );
1686- nullBufCapRows = newCapRows ;
1687- }
1688-
16891715 private int getOrAddLocalSymbol (CharSequence value ) {
16901716 int idx = symbolDict .get (value );
16911717 if (idx == CharSequenceIntHashMap .NO_ENTRY_VALUE ) {
@@ -1709,6 +1735,7 @@ private void resetEmptyMetadata() {
17091735 decimalScale = -1 ;
17101736 geohashPrecision = -1 ;
17111737 maxGlobalSymbolId = -1 ;
1738+ storeGlobalSymbolIdsOnly = false ;
17121739 if (symbolDict != null ) {
17131740 symbolDict .clear ();
17141741 symbolList .clear ();
@@ -1778,6 +1805,11 @@ private void retainStringValue(int valueIndex) {
17781805 private void retainSymbolValue (int valueIndex ) {
17791806 retainFixedWidthValue (valueIndex );
17801807
1808+ if (storeGlobalSymbolIdsOnly ) {
1809+ maxGlobalSymbolId = Unsafe .getUnsafe ().getInt (dataBuffer .pageAddress ());
1810+ return ;
1811+ }
1812+
17811813 int localIndex = Unsafe .getUnsafe ().getInt (dataBuffer .pageAddress ());
17821814 String symbol = symbolList .get (localIndex );
17831815
0 commit comments