Skip to content

Commit d76aa02

Browse files
mtopolnikclaude
andcommitted
Remove redundant toString() in string/symbol columns
Pass CharSequence directly through the symbol and string column paths instead of eagerly converting to String. In stringColumn(), addString() already copies character data immediately via putUtf8(), so the toString() was pure waste. In the symbol path, propagate CharSequence through getOrAddGlobalSymbol() and addSymbolWithGlobalId() down to the dictionary lookup. GlobalSymbolDictionary.getOrAddSymbol() now accepts CharSequence and only calls toString() when a symbol is new and must be stored. CharSequenceIntHashMap.get() already accepts CharSequence for lookups, so repeated symbols incur zero allocation. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 50d3d0a commit d76aa02

3 files changed

Lines changed: 13 additions & 14 deletions

File tree

core/src/main/java/io/questdb/client/cutlass/qwp/client/GlobalSymbolDictionary.java

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ public int getId(String symbol) {
9494
* @return the global ID for this symbol (>= 0)
9595
* @throws IllegalArgumentException if symbol is null
9696
*/
97-
public int getOrAddSymbol(String symbol) {
97+
public int getOrAddSymbol(CharSequence symbol) {
9898
if (symbol == null) {
9999
throw new IllegalArgumentException("symbol cannot be null");
100100
}
@@ -104,10 +104,11 @@ public int getOrAddSymbol(String symbol) {
104104
return existingId;
105105
}
106106

107-
// Assign new ID
107+
// Assign new ID — toString() only for new symbols that must be stored
108+
String symbolStr = symbol.toString();
108109
int newId = idToSymbol.size();
109-
symbolToId.put(symbol, newId);
110-
idToSymbol.add(symbol);
110+
symbolToId.put(symbolStr, newId);
111+
idToSymbol.add(symbolStr);
111112
return newId;
112113
}
113114

core/src/main/java/io/questdb/client/cutlass/qwp/client/QwpWebSocketSender.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -636,7 +636,7 @@ public int getMaxSentSymbolId() {
636636
* @param symbol the symbol value to register
637637
* @return the global symbol ID
638638
*/
639-
public int getOrAddGlobalSymbol(String symbol) {
639+
public int getOrAddGlobalSymbol(CharSequence symbol) {
640640
int globalId = globalSymbolDictionary.getOrAddSymbol(symbol);
641641
if (globalId > currentBatchMaxSymbolId) {
642642
currentBatchMaxSymbolId = globalId;
@@ -801,7 +801,7 @@ public QwpWebSocketSender stringColumn(CharSequence columnName, CharSequence val
801801
checkNotClosed();
802802
checkTableSelected();
803803
QwpTableBuffer.ColumnBuffer col = currentTableBuffer.getOrCreateColumn(checkedColumnName(columnName), TYPE_STRING, true);
804-
col.addString(value != null ? value.toString() : null);
804+
col.addString(value);
805805
return this;
806806
}
807807

core/src/main/java/io/questdb/client/cutlass/qwp/protocol/QwpTableBuffer.java

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ public QwpTableBuffer(String tableName) {
7878
/**
7979
* Use this constructor overload to allow writing to a symbol column.
8080
* {@link ColumnBuffer#addSymbol(CharSequence)} needs the sender to
81-
* call {@link QwpWebSocketSender#getOrAddGlobalSymbol(String)}, registering
81+
* call {@link QwpWebSocketSender#getOrAddGlobalSymbol(CharSequence)}, registering
8282
* the symbol in the global dictionary shared with the server.
8383
*/
8484
public QwpTableBuffer(String tableName, QwpWebSocketSender sender) {
@@ -1063,9 +1063,8 @@ public void addSymbol(CharSequence value) {
10631063
return;
10641064
}
10651065
if (sender != null) {
1066-
String symbolValue = value.toString();
1067-
int globalId = sender.getOrAddGlobalSymbol(symbolValue);
1068-
addSymbolWithGlobalId(symbolValue, globalId);
1066+
int globalId = sender.getOrAddGlobalSymbol(value);
1067+
addSymbolWithGlobalId(value, globalId);
10691068
return;
10701069
}
10711070
ensureNullBitmapCapacity();
@@ -1092,9 +1091,8 @@ public void addSymbolUtf8(long ptr, int len) {
10921091
throw new AssertionError("unreachable");
10931092
}
10941093
if (sender != null) {
1095-
String symbolValue = lookupSink.toString();
1096-
int globalId = sender.getOrAddGlobalSymbol(symbolValue);
1097-
addSymbolWithGlobalId(symbolValue, globalId);
1094+
int globalId = sender.getOrAddGlobalSymbol(lookupSink);
1095+
addSymbolWithGlobalId(lookupSink, globalId);
10981096
return;
10991097
}
11001098
ensureNullBitmapCapacity();
@@ -1104,7 +1102,7 @@ public void addSymbolUtf8(long ptr, int len) {
11041102
size++;
11051103
}
11061104

1107-
public void addSymbolWithGlobalId(String value, int globalId) {
1105+
public void addSymbolWithGlobalId(CharSequence value, int globalId) {
11081106
if (value == null) {
11091107
addNull();
11101108
return;

0 commit comments

Comments
 (0)