Skip to content

Commit 233ed1f

Browse files
committed
improve multi value field cache handling both in terms of memory usage and GC behavior
1 parent cb8ceb1 commit 233ed1f

File tree

7 files changed

+364
-260
lines changed

7 files changed

+364
-260
lines changed

modules/elasticsearch/src/main/java/org/elasticsearch/index/field/data/doubles/MultiValueDoubleFieldData.java

Lines changed: 43 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -61,36 +61,38 @@ public MultiValueDoubleFieldData(String fieldName, int[][] ordinals, double[] va
6161
}
6262

6363
@Override public boolean hasValue(int docId) {
64-
return ordinals[docId] != null;
64+
for (int[] ordinal : ordinals) {
65+
if (ordinal[docId] != 0) {
66+
return true;
67+
}
68+
}
69+
return false;
6570
}
6671

6772
@Override public void forEachValueInDoc(int docId, StringValueInDocProc proc) {
68-
int[] docOrders = ordinals[docId];
69-
if (docOrders == null) {
70-
return;
71-
}
72-
for (int docOrder : docOrders) {
73-
proc.onValue(docId, Double.toString(values[docOrder]));
73+
for (int[] ordinal : ordinals) {
74+
int loc = ordinal[docId];
75+
if (loc != 0) {
76+
proc.onValue(docId, Double.toString(values[loc]));
77+
}
7478
}
7579
}
7680

7781
@Override public void forEachValueInDoc(int docId, DoubleValueInDocProc proc) {
78-
int[] docOrders = ordinals[docId];
79-
if (docOrders == null) {
80-
return;
81-
}
82-
for (int docOrder : docOrders) {
83-
proc.onValue(docId, values[docOrder]);
82+
for (int[] ordinal : ordinals) {
83+
int loc = ordinal[docId];
84+
if (loc != 0) {
85+
proc.onValue(docId, values[loc]);
86+
}
8487
}
8588
}
8689

8790
@Override public void forEachValueInDoc(int docId, ValueInDocProc proc) {
88-
int[] docOrders = ordinals[docId];
89-
if (docOrders == null) {
90-
return;
91-
}
92-
for (int docOrder : docOrders) {
93-
proc.onValue(docId, values[docOrder]);
91+
for (int[] ordinal : ordinals) {
92+
int loc = ordinal[docId];
93+
if (loc != 0) {
94+
proc.onValue(docId, values[loc]);
95+
}
9496
}
9597
}
9698

@@ -99,26 +101,37 @@ public MultiValueDoubleFieldData(String fieldName, int[][] ordinals, double[] va
99101
}
100102

101103
@Override public double value(int docId) {
102-
int[] docOrders = ordinals[docId];
103-
if (docOrders == null) {
104-
return 0;
104+
for (int[] ordinal : ordinals) {
105+
int loc = ordinal[docId];
106+
if (loc != 0) {
107+
return values[loc];
108+
}
105109
}
106-
return values[docOrders[0]];
110+
return 0;
107111
}
108112

109113
@Override public double[] values(int docId) {
110-
int[] docOrders = ordinals[docId];
111-
if (docOrders == null) {
114+
int length = 0;
115+
for (int[] ordinal : ordinals) {
116+
if (ordinal[docId] != 0) {
117+
length++;
118+
}
119+
}
120+
if (length == 0) {
112121
return EMPTY_DOUBLE_ARRAY;
113122
}
114123
double[] doubles;
115-
if (docOrders.length < VALUE_CACHE_SIZE) {
116-
doubles = valuesCache.get().get()[docOrders.length];
124+
if (length < VALUE_CACHE_SIZE) {
125+
doubles = valuesCache.get().get()[length];
117126
} else {
118-
doubles = new double[docOrders.length];
127+
doubles = new double[length];
119128
}
120-
for (int i = 0; i < docOrders.length; i++) {
121-
doubles[i] = values[docOrders[i]];
129+
int i = 0;
130+
for (int[] ordinal : ordinals) {
131+
int loc = ordinal[docId];
132+
if (loc != 0) {
133+
doubles[i++] = values[loc];
134+
}
122135
}
123136
return doubles;
124137
}

modules/elasticsearch/src/main/java/org/elasticsearch/index/field/data/floats/MultiValueFloatFieldData.java

Lines changed: 59 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -72,77 +72,99 @@ public MultiValueFloatFieldData(String fieldName, int[][] ordinals, float[] valu
7272
}
7373

7474
@Override public boolean hasValue(int docId) {
75-
return ordinals[docId] != null;
75+
for (int[] ordinal : ordinals) {
76+
if (ordinal[docId] != 0) {
77+
return true;
78+
}
79+
}
80+
return false;
7681
}
7782

7883
@Override public void forEachValueInDoc(int docId, StringValueInDocProc proc) {
79-
int[] docOrders = ordinals[docId];
80-
if (docOrders == null) {
81-
return;
82-
}
83-
for (int docOrder : docOrders) {
84-
proc.onValue(docId, Float.toString(values[docOrder]));
84+
for (int[] ordinal : ordinals) {
85+
int loc = ordinal[docId];
86+
if (loc != 0) {
87+
proc.onValue(docId, Float.toString(values[loc]));
88+
}
8589
}
8690
}
8791

8892
@Override public void forEachValueInDoc(int docId, DoubleValueInDocProc proc) {
89-
int[] docOrders = ordinals[docId];
90-
if (docOrders == null) {
91-
return;
92-
}
93-
for (int docOrder : docOrders) {
94-
proc.onValue(docId, values[docOrder]);
93+
for (int[] ordinal : ordinals) {
94+
int loc = ordinal[docId];
95+
if (loc != 0) {
96+
proc.onValue(docId, values[loc]);
97+
}
9598
}
9699
}
97100

98101
@Override public void forEachValueInDoc(int docId, ValueInDocProc proc) {
99-
int[] docOrders = ordinals[docId];
100-
if (docOrders == null) {
101-
return;
102-
}
103-
for (int docOrder : docOrders) {
104-
proc.onValue(docId, values[docOrder]);
102+
for (int[] ordinal : ordinals) {
103+
int loc = ordinal[docId];
104+
if (loc != 0) {
105+
proc.onValue(docId, values[loc]);
106+
}
105107
}
106108
}
107109

108110
@Override public double[] doubleValues(int docId) {
109-
int[] docOrders = ordinals[docId];
110-
if (docOrders == null) {
111+
int length = 0;
112+
for (int[] ordinal : ordinals) {
113+
if (ordinal[docId] != 0) {
114+
length++;
115+
}
116+
}
117+
if (length == 0) {
111118
return DoubleFieldData.EMPTY_DOUBLE_ARRAY;
112119
}
113120
double[] doubles;
114-
if (docOrders.length < VALUE_CACHE_SIZE) {
115-
doubles = doublesValuesCache.get().get()[docOrders.length];
121+
if (length < VALUE_CACHE_SIZE) {
122+
doubles = doublesValuesCache.get().get()[length];
116123
} else {
117-
doubles = new double[docOrders.length];
124+
doubles = new double[length];
118125
}
119-
for (int i = 0; i < docOrders.length; i++) {
120-
doubles[i] = values[docOrders[i]];
126+
int i = 0;
127+
for (int[] ordinal : ordinals) {
128+
int loc = ordinal[docId];
129+
if (loc != 0) {
130+
doubles[i++] = values[loc];
131+
}
121132
}
122133
return doubles;
123134
}
124135

125136
@Override public float value(int docId) {
126-
int[] docOrders = ordinals[docId];
127-
if (docOrders == null) {
128-
return 0;
137+
for (int[] ordinal : ordinals) {
138+
int loc = ordinal[docId];
139+
if (loc != 0) {
140+
return values[loc];
141+
}
129142
}
130-
return values[docOrders[0]];
143+
return 0;
131144
}
132145

133146
@Override public float[] values(int docId) {
134-
int[] docOrders = ordinals[docId];
135-
if (docOrders == null) {
147+
int length = 0;
148+
for (int[] ordinal : ordinals) {
149+
if (ordinal[docId] != 0) {
150+
length++;
151+
}
152+
}
153+
if (length == 0) {
136154
return EMPTY_FLOAT_ARRAY;
137155
}
138156
float[] floats;
139-
if (docOrders.length < VALUE_CACHE_SIZE) {
140-
floats = valuesCache.get().get()[docOrders.length];
157+
if (length < VALUE_CACHE_SIZE) {
158+
floats = valuesCache.get().get()[length];
141159
} else {
142-
floats = new float[docOrders.length];
160+
floats = new float[length];
143161
}
144-
for (int i = 0; i < docOrders.length; i++) {
145-
floats[i] = values[docOrders[i]];
162+
int i = 0;
163+
for (int[] ordinal : ordinals) {
164+
int loc = ordinal[docId];
165+
if (loc != 0) {
166+
floats[i++] = values[loc];
167+
}
146168
}
147169
return floats;
148170
}

modules/elasticsearch/src/main/java/org/elasticsearch/index/field/data/ints/MultiValueIntFieldData.java

Lines changed: 59 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -72,77 +72,99 @@ public MultiValueIntFieldData(String fieldName, int[][] ordinals, int[] values)
7272
}
7373

7474
@Override public boolean hasValue(int docId) {
75-
return ordinals[docId] != null;
75+
for (int[] ordinal : ordinals) {
76+
if (ordinal[docId] != 0) {
77+
return true;
78+
}
79+
}
80+
return false;
7681
}
7782

7883
@Override public void forEachValueInDoc(int docId, StringValueInDocProc proc) {
79-
int[] docOrders = ordinals[docId];
80-
if (docOrders == null) {
81-
return;
82-
}
83-
for (int docOrder : docOrders) {
84-
proc.onValue(docId, Integer.toString(values[docOrder]));
84+
for (int[] ordinal : ordinals) {
85+
int loc = ordinal[docId];
86+
if (loc != 0) {
87+
proc.onValue(docId, Integer.toString(values[loc]));
88+
}
8589
}
8690
}
8791

8892
@Override public void forEachValueInDoc(int docId, DoubleValueInDocProc proc) {
89-
int[] docOrders = ordinals[docId];
90-
if (docOrders == null) {
91-
return;
92-
}
93-
for (int docOrder : docOrders) {
94-
proc.onValue(docId, values[docOrder]);
93+
for (int[] ordinal : ordinals) {
94+
int loc = ordinal[docId];
95+
if (loc != 0) {
96+
proc.onValue(docId, values[loc]);
97+
}
9598
}
9699
}
97100

98101
@Override public void forEachValueInDoc(int docId, ValueInDocProc proc) {
99-
int[] docOrders = ordinals[docId];
100-
if (docOrders == null) {
101-
return;
102-
}
103-
for (int docOrder : docOrders) {
104-
proc.onValue(docId, values[docOrder]);
102+
for (int[] ordinal : ordinals) {
103+
int loc = ordinal[docId];
104+
if (loc != 0) {
105+
proc.onValue(docId, values[loc]);
106+
}
105107
}
106108
}
107109

108110
@Override public double[] doubleValues(int docId) {
109-
int[] docOrders = ordinals[docId];
110-
if (docOrders == null) {
111+
int length = 0;
112+
for (int[] ordinal : ordinals) {
113+
if (ordinal[docId] != 0) {
114+
length++;
115+
}
116+
}
117+
if (length == 0) {
111118
return DoubleFieldData.EMPTY_DOUBLE_ARRAY;
112119
}
113120
double[] doubles;
114-
if (docOrders.length < VALUE_CACHE_SIZE) {
115-
doubles = doublesValuesCache.get().get()[docOrders.length];
121+
if (length < VALUE_CACHE_SIZE) {
122+
doubles = doublesValuesCache.get().get()[length];
116123
} else {
117-
doubles = new double[docOrders.length];
124+
doubles = new double[length];
118125
}
119-
for (int i = 0; i < docOrders.length; i++) {
120-
doubles[i] = values[docOrders[i]];
126+
int i = 0;
127+
for (int[] ordinal : ordinals) {
128+
int loc = ordinal[docId];
129+
if (loc != 0) {
130+
doubles[i++] = values[loc];
131+
}
121132
}
122133
return doubles;
123134
}
124135

125136
@Override public int value(int docId) {
126-
int[] docOrders = ordinals[docId];
127-
if (docOrders == null) {
128-
return 0;
137+
for (int[] ordinal : ordinals) {
138+
int loc = ordinal[docId];
139+
if (loc != 0) {
140+
return values[loc];
141+
}
129142
}
130-
return values[docOrders[0]];
143+
return 0;
131144
}
132145

133146
@Override public int[] values(int docId) {
134-
int[] docOrders = ordinals[docId];
135-
if (docOrders == null) {
147+
int length = 0;
148+
for (int[] ordinal : ordinals) {
149+
if (ordinal[docId] != 0) {
150+
length++;
151+
}
152+
}
153+
if (length == 0) {
136154
return EMPTY_INT_ARRAY;
137155
}
138156
int[] ints;
139-
if (docOrders.length < VALUE_CACHE_SIZE) {
140-
ints = valuesCache.get().get()[docOrders.length];
157+
if (length < VALUE_CACHE_SIZE) {
158+
ints = valuesCache.get().get()[length];
141159
} else {
142-
ints = new int[docOrders.length];
160+
ints = new int[length];
143161
}
144-
for (int i = 0; i < docOrders.length; i++) {
145-
ints[i] = values[docOrders[i]];
162+
int i = 0;
163+
for (int[] ordinal : ordinals) {
164+
int loc = ordinal[docId];
165+
if (loc != 0) {
166+
ints[i++] = values[loc];
167+
}
146168
}
147169
return ints;
148170
}

0 commit comments

Comments
 (0)