Skip to content

Commit

Permalink
Add column name index mapping in PostgresqlRow.
Browse files Browse the repository at this point in the history
Avoid looping through the fields unnecessarily.

[resolves #636][#640]
  • Loading branch information
cty123 authored and mp911de committed Feb 28, 2024
1 parent d047276 commit 079b565
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 5 deletions.
31 changes: 26 additions & 5 deletions src/main/java/io/r2dbc/postgresql/PostgresqlRow.java
Expand Up @@ -24,6 +24,9 @@
import io.r2dbc.postgresql.message.backend.RowDescription;
import io.r2dbc.postgresql.util.Assert;
import io.r2dbc.spi.Row;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import reactor.core.publisher.Mono;
import reactor.util.annotation.Nullable;

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

private volatile boolean isReleased = false;

private Map<String, Integer> columnNameIndexCacheMap;

PostgresqlRow(ConnectionResources context, io.r2dbc.postgresql.api.PostgresqlRowMetadata metadata, List<RowDescription.Field> fields, ByteBuf[] data) {
this.context = Assert.requireNonNull(context, "context must not be null");
this.metadata = Assert.requireNonNull(metadata, "metadata must not be null");
Expand Down Expand Up @@ -138,6 +143,15 @@ public String toString() {
'}';
}

static Map<String, Integer> createColumnNameIndexMap(List<RowDescription.Field> fields) {
Map<String, Integer> columnNameIndexMap = new HashMap<>(fields.size() * 2);
for (int i = fields.size() - 1; i >= 0; i--) {
columnNameIndexMap.put(fields.get(i).getName().toLowerCase(Locale.US), i);
}

return columnNameIndexMap;
}

static PostgresqlRow toRow(ConnectionResources context, DataRow dataRow, Codecs codecs, RowDescription rowDescription) {
Assert.requireNonNull(dataRow, "dataRow must not be null");
Assert.requireNonNull(codecs, "rowDescription must not be null");
Expand Down Expand Up @@ -165,12 +179,19 @@ void release() {
}

private int getColumn(String name) {
for (int i = 0; i < this.fields.size(); i++) {
RowDescription.Field field = this.fields.get(i);
if (this.columnNameIndexCacheMap == null) {
this.columnNameIndexCacheMap = createColumnNameIndexMap(this.fields);
}

if (field.getName().equalsIgnoreCase(name)) {
return i;
}
Integer index = this.columnNameIndexCacheMap.get(name);
if (index != null) {
return index;
}

index = this.columnNameIndexCacheMap.get(name.toLowerCase(Locale.US));
if (index != null) {
this.columnNameIndexCacheMap.put(name, index);
return index;
}

throw new NoSuchElementException(String.format("Column name '%s' does not exist in column names %s", name, toColumnNames()));
Expand Down
Expand Up @@ -132,6 +132,7 @@ void getName() {
.build();

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

@Test
Expand Down

0 comments on commit 079b565

Please sign in to comment.