3434import java .util .ArrayList ;
3535import java .util .Arrays ;
3636import java .util .Collections ;
37+ import java .util .HashMap ;
3738import java .util .HashSet ;
3839import java .util .List ;
40+ import java .util .Map ;
3941import java .util .Objects ;
4042import java .util .Set ;
4143import 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