Skip to content

Commit 48e46b9

Browse files
committed
[core] Add lazied fields in RowType to improve performance
1 parent 11ce51c commit 48e46b9

File tree

1 file changed

+72
-36
lines changed
  • paimon-api/src/main/java/org/apache/paimon/types

1 file changed

+72
-36
lines changed

paimon-api/src/main/java/org/apache/paimon/types/RowType.java

Lines changed: 72 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,10 @@
3434
import java.util.ArrayList;
3535
import java.util.Arrays;
3636
import java.util.Collections;
37+
import java.util.HashMap;
3738
import java.util.HashSet;
3839
import java.util.List;
40+
import java.util.Map;
3941
import java.util.Objects;
4042
import java.util.Set;
4143
import java.util.concurrent.atomic.AtomicInteger;
@@ -61,6 +63,12 @@ public final class RowType extends DataType {
6163

6264
private final List<DataField> fields;
6365

66+
private transient Map<String, DataField> laziedNameToField;
67+
private transient Map<String, Integer> laziedNameToIndex;
68+
69+
private transient Map<Integer, DataField> laziedFieldIdToField;
70+
private transient Map<Integer, Integer> laziedFieldIdToIndex;
71+
6472
public RowType(boolean isNullable, List<DataField> fields) {
6573
super(isNullable, DataTypeRoot.ROW);
6674
this.fields =
@@ -101,71 +109,51 @@ public int getFieldCount() {
101109
}
102110

103111
public int getFieldIndex(String fieldName) {
104-
for (int i = 0; i < fields.size(); i++) {
105-
if (fields.get(i).name().equals(fieldName)) {
106-
return i;
107-
}
108-
}
109-
return -1;
112+
return nameToIndex().getOrDefault(fieldName, -1);
110113
}
111114

112115
public int[] getFieldIndices(List<String> projectFields) {
113-
List<String> fieldNames = getFieldNames();
114116
int[] projection = new int[projectFields.size()];
115117
for (int i = 0; i < projection.length; i++) {
116-
projection[i] = fieldNames.indexOf(projectFields.get(i));
118+
projection[i] = getFieldIndex(projectFields.get(i));
117119
}
118120
return projection;
119121
}
120122

121123
public boolean containsField(String fieldName) {
122-
for (DataField field : fields) {
123-
if (field.name().equals(fieldName)) {
124-
return true;
125-
}
126-
}
127-
return false;
124+
return nameToField().containsKey(fieldName);
128125
}
129126

130127
public boolean containsField(int fieldId) {
131-
for (DataField field : fields) {
132-
if (field.id() == fieldId) {
133-
return true;
134-
}
135-
}
136-
return false;
128+
return fieldIdToField().containsKey(fieldId);
137129
}
138130

139131
public boolean notContainsField(String fieldName) {
140132
return !containsField(fieldName);
141133
}
142134

143135
public DataField getField(String fieldName) {
144-
for (DataField field : fields) {
145-
if (field.name().equals(fieldName)) {
146-
return field;
147-
}
136+
DataField field = nameToField().get(fieldName);
137+
if (field == null) {
138+
throw new RuntimeException("Cannot find field: " + fieldName);
148139
}
149-
150-
throw new RuntimeException("Cannot find field: " + fieldName);
140+
return field;
151141
}
152142

153143
public DataField getField(int fieldId) {
154-
for (DataField field : fields) {
155-
if (field.id() == fieldId) {
156-
return field;
157-
}
144+
DataField field = fieldIdToField().get(fieldId);
145+
if (field == null) {
146+
throw new RuntimeException("Cannot find field by field id: " + fieldId);
158147
}
159-
throw new RuntimeException("Cannot find field by field id: " + fieldId);
148+
return field;
160149
}
161150

162151
public int getFieldIndexByFieldId(int fieldId) {
163-
for (int i = 0; i < fields.size(); i++) {
164-
if (fields.get(i).id() == fieldId) {
165-
return i;
166-
}
152+
Integer index = fieldIdToIndex().get(fieldId);
153+
if (index == null) {
154+
throw new RuntimeException("Cannot find field index by FieldId " + fieldId);
167155
}
168-
throw new RuntimeException("Cannot find field index by FieldId " + fieldId);
156+
return index;
169157
}
170158

171159
@Override
@@ -331,6 +319,54 @@ public RowType project(String... names) {
331319
return project(Arrays.asList(names));
332320
}
333321

322+
private Map<String, DataField> nameToField() {
323+
Map<String, DataField> nameToField = this.laziedNameToField;
324+
if (nameToField == null) {
325+
nameToField = new HashMap<>();
326+
for (DataField field : fields) {
327+
nameToField.put(field.name(), field);
328+
}
329+
this.laziedNameToField = nameToField;
330+
}
331+
return nameToField;
332+
}
333+
334+
private Map<String, Integer> nameToIndex() {
335+
Map<String, Integer> nameToIndex = this.laziedNameToIndex;
336+
if (nameToIndex == null) {
337+
nameToIndex = new HashMap<>();
338+
for (int i = 0; i < fields.size(); i++) {
339+
nameToIndex.put(fields.get(i).name(), i);
340+
}
341+
this.laziedNameToIndex = nameToIndex;
342+
}
343+
return nameToIndex;
344+
}
345+
346+
private Map<Integer, DataField> fieldIdToField() {
347+
Map<Integer, DataField> fieldIdToField = this.laziedFieldIdToField;
348+
if (fieldIdToField == null) {
349+
fieldIdToField = new HashMap<>();
350+
for (DataField field : fields) {
351+
fieldIdToField.put(field.id(), field);
352+
}
353+
this.laziedFieldIdToField = fieldIdToField;
354+
}
355+
return fieldIdToField;
356+
}
357+
358+
private Map<Integer, Integer> fieldIdToIndex() {
359+
Map<Integer, Integer> fieldIdToIndex = this.laziedFieldIdToIndex;
360+
if (fieldIdToIndex == null) {
361+
fieldIdToIndex = new HashMap<>();
362+
for (int i = 0; i < fields.size(); i++) {
363+
fieldIdToIndex.put(fields.get(i).id(), i);
364+
}
365+
this.laziedFieldIdToIndex = fieldIdToIndex;
366+
}
367+
return fieldIdToIndex;
368+
}
369+
334370
public static RowType of() {
335371
return new RowType(true, Collections.emptyList());
336372
}

0 commit comments

Comments
 (0)