Skip to content

Commit 1ec12b1

Browse files
authored
Return float[] instead of List<Double> in valueFetcher (#126702) (#126811)
We are currently having to hold in heap big list of Double objects which can take big amounts of heap. With this change we can reduce the heap usage by 7x.
1 parent 74bdf18 commit 1ec12b1

File tree

4 files changed

+35
-16
lines changed

4 files changed

+35
-16
lines changed

docs/changelog/126702.yaml

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
pr: 126702
2+
summary: "Return float[] instead of List<Double> in `valueFetcher`"
3+
area: Search
4+
type: enhancement
5+
issues: []

x-pack/plugin/rank-vectors/src/main/java/org/elasticsearch/xpack/rank/vectors/mapper/RankVectorsFieldMapper.java

+14-1
Original file line numberDiff line numberDiff line change
@@ -180,7 +180,20 @@ public ValueFetcher valueFetcher(SearchExecutionContext context, String format)
180180
return new ArraySourceValueFetcher(name(), context) {
181181
@Override
182182
protected Object parseSourceValue(Object value) {
183-
return value;
183+
List<?> outerList = (List<?>) value;
184+
List<Object> vectors = new ArrayList<>(outerList.size());
185+
for (Object o : outerList) {
186+
if (o instanceof List<?> innerList) {
187+
float[] vector = new float[innerList.size()];
188+
for (int i = 0; i < vector.length; i++) {
189+
vector[i] = ((Number) innerList.get(i)).floatValue();
190+
}
191+
vectors.add(vector);
192+
} else {
193+
vectors.add(o);
194+
}
195+
}
196+
return vectors;
184197
}
185198
};
186199
}

x-pack/plugin/rank-vectors/src/test/java/org/elasticsearch/xpack/rank/vectors/mapper/RankVectorsFieldMapperTests.java

+3-12
Original file line numberDiff line numberDiff line change
@@ -383,19 +383,10 @@ protected void assertFetch(MapperService mapperService, String field, Object val
383383
switch (denseVectorFieldType.getElementType()) {
384384
case BYTE -> assumeFalse("byte element type testing not currently added", false);
385385
case FLOAT -> {
386-
List<float[]> fetchedFloatsList = new ArrayList<>();
387-
for (var f : fromNative) {
388-
float[] fetchedFloats = new float[denseVectorFieldType.getVectorDimensions()];
389-
assert f instanceof List;
390-
List<?> vector = (List<?>) f;
391-
int i = 0;
392-
for (Object v : vector) {
393-
assert v instanceof Number;
394-
fetchedFloats[i++] = ((Number) v).floatValue();
395-
}
396-
fetchedFloatsList.add(fetchedFloats);
386+
float[][] fetchedFloats = new float[fromNative.size()][];
387+
for (int i = 0; i < fromNative.size(); i++) {
388+
fetchedFloats[i] = (float[]) fromNative.get(i);
397389
}
398-
float[][] fetchedFloats = fetchedFloatsList.toArray(new float[0][]);
399390
assertThat("fetching " + value, fetchedFloats, equalTo(value));
400391
}
401392
}

x-pack/plugin/rank-vectors/src/test/java/org/elasticsearch/xpack/rank/vectors/mapper/RankVectorsFieldTypeTests.java

+13-3
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,13 @@
1919

2020
import java.io.IOException;
2121
import java.util.Collections;
22+
import java.util.HexFormat;
2223
import java.util.List;
2324
import java.util.Set;
2425

2526
import static org.elasticsearch.index.mapper.vectors.DenseVectorFieldMapper.BBQ_MIN_DIMS;
27+
import static org.hamcrest.Matchers.equalTo;
28+
import static org.hamcrest.Matchers.iterableWithSize;
2629

2730
public class RankVectorsFieldTypeTests extends FieldTypeTestCase {
2831

@@ -86,9 +89,16 @@ public void testDocValueFormat() {
8689

8790
public void testFetchSourceValue() throws IOException {
8891
RankVectorsFieldType fft = createFloatFieldType();
89-
List<List<Double>> vector = List.of(List.of(0.0, 1.0, 2.0, 3.0, 4.0, 6.0));
90-
assertEquals(vector, fetchSourceValue(fft, vector));
92+
List<List<Double>> vectorFromXContent = List.of(List.of(0.0, 1.0, 2.0, 3.0, 4.0, 6.0));
93+
List<float[]> vector = List.of(new float[] { 0.0f, 1.0f, 2.0f, 3.0f, 4.0f, 6.0f });
94+
assertThat(fetchSourceValue(fft, vectorFromXContent), iterableWithSize(1));
95+
assertThat(fetchSourceValue(fft, vectorFromXContent).get(0), equalTo(vector.get(0)));
9196
RankVectorsFieldType bft = createByteFieldType();
92-
assertEquals(vector, fetchSourceValue(bft, vector));
97+
assertThat(fetchSourceValue(bft, vectorFromXContent), iterableWithSize(1));
98+
assertThat(fetchSourceValue(bft, vectorFromXContent).get(0), equalTo(vector.get(0)));
99+
String hexStr = HexFormat.of().formatHex(new byte[] { 0, 1, 2, 3, 4, 6 });
100+
List<String> hexVecs = List.of(hexStr);
101+
assertThat(fetchSourceValue(bft, hexVecs), iterableWithSize(1));
102+
assertThat(fetchSourceValue(bft, hexVecs).get(0), equalTo(hexStr));
93103
}
94104
}

0 commit comments

Comments
 (0)