Skip to content

Commit 079b565

Browse files
cty123mp911de
authored andcommitted
Add column name index mapping in PostgresqlRow.
Avoid looping through the fields unnecessarily. [resolves #636][#640]
1 parent d047276 commit 079b565

File tree

2 files changed

+27
-5
lines changed

2 files changed

+27
-5
lines changed

src/main/java/io/r2dbc/postgresql/PostgresqlRow.java

+26-5
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,9 @@
2424
import io.r2dbc.postgresql.message.backend.RowDescription;
2525
import io.r2dbc.postgresql.util.Assert;
2626
import io.r2dbc.spi.Row;
27+
import java.util.HashMap;
28+
import java.util.Locale;
29+
import java.util.Map;
2730
import reactor.core.publisher.Mono;
2831
import reactor.util.annotation.Nullable;
2932

@@ -47,6 +50,8 @@ final class PostgresqlRow implements io.r2dbc.postgresql.api.PostgresqlRow {
4750

4851
private volatile boolean isReleased = false;
4952

53+
private Map<String, Integer> columnNameIndexCacheMap;
54+
5055
PostgresqlRow(ConnectionResources context, io.r2dbc.postgresql.api.PostgresqlRowMetadata metadata, List<RowDescription.Field> fields, ByteBuf[] data) {
5156
this.context = Assert.requireNonNull(context, "context must not be null");
5257
this.metadata = Assert.requireNonNull(metadata, "metadata must not be null");
@@ -138,6 +143,15 @@ public String toString() {
138143
'}';
139144
}
140145

146+
static Map<String, Integer> createColumnNameIndexMap(List<RowDescription.Field> fields) {
147+
Map<String, Integer> columnNameIndexMap = new HashMap<>(fields.size() * 2);
148+
for (int i = fields.size() - 1; i >= 0; i--) {
149+
columnNameIndexMap.put(fields.get(i).getName().toLowerCase(Locale.US), i);
150+
}
151+
152+
return columnNameIndexMap;
153+
}
154+
141155
static PostgresqlRow toRow(ConnectionResources context, DataRow dataRow, Codecs codecs, RowDescription rowDescription) {
142156
Assert.requireNonNull(dataRow, "dataRow must not be null");
143157
Assert.requireNonNull(codecs, "rowDescription must not be null");
@@ -165,12 +179,19 @@ void release() {
165179
}
166180

167181
private int getColumn(String name) {
168-
for (int i = 0; i < this.fields.size(); i++) {
169-
RowDescription.Field field = this.fields.get(i);
182+
if (this.columnNameIndexCacheMap == null) {
183+
this.columnNameIndexCacheMap = createColumnNameIndexMap(this.fields);
184+
}
170185

171-
if (field.getName().equalsIgnoreCase(name)) {
172-
return i;
173-
}
186+
Integer index = this.columnNameIndexCacheMap.get(name);
187+
if (index != null) {
188+
return index;
189+
}
190+
191+
index = this.columnNameIndexCacheMap.get(name.toLowerCase(Locale.US));
192+
if (index != null) {
193+
this.columnNameIndexCacheMap.put(name, index);
194+
return index;
174195
}
175196

176197
throw new NoSuchElementException(String.format("Column name '%s' does not exist in column names %s", name, toColumnNames()));

src/test/java/io/r2dbc/postgresql/PostgresqlRowUnitTests.java

+1
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,7 @@ void getName() {
132132
.build();
133133

134134
assertThat(new PostgresqlRow(MockContext.builder().codecs(codecs).build(), new PostgresqlRowMetadata(Collections.emptyList()), this.columns, this.data).get("test-name-2", Object.class)).isSameAs(value);
135+
assertThat(new PostgresqlRow(MockContext.builder().codecs(codecs).build(), new PostgresqlRowMetadata(Collections.emptyList()), this.columns, this.data).get("tEsT-nAme-2", Object.class)).isSameAs(value);
135136
}
136137

137138
@Test

0 commit comments

Comments
 (0)