Skip to content

Commit d8b9b02

Browse files
authored
Add reusable HistogramValue object (#49799)
Adds a reusable implementation of HistogramValue so we do not create an object per document.
1 parent 3008659 commit d8b9b02

File tree

1 file changed

+58
-49
lines changed

1 file changed

+58
-49
lines changed

x-pack/plugin/analytics/src/main/java/org/elasticsearch/xpack/analytics/mapper/HistogramFieldMapper.java

+58-49
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,11 @@
1818
import org.apache.lucene.search.DocValuesFieldExistsQuery;
1919
import org.apache.lucene.search.Query;
2020
import org.apache.lucene.search.SortField;
21+
import org.apache.lucene.store.ByteArrayDataInput;
22+
import org.apache.lucene.store.ByteBuffersDataOutput;
2123
import org.apache.lucene.util.BytesRef;
2224
import org.elasticsearch.common.Explicit;
2325
import org.elasticsearch.common.ParseField;
24-
import org.elasticsearch.common.io.stream.ByteBufferStreamInput;
25-
import org.elasticsearch.common.io.stream.BytesStreamOutput;
2626
import org.elasticsearch.common.settings.Settings;
2727
import org.elasticsearch.common.xcontent.XContentBuilder;
2828
import org.elasticsearch.common.xcontent.XContentParser;
@@ -49,7 +49,6 @@
4949
import org.elasticsearch.search.MultiValueMode;
5050

5151
import java.io.IOException;
52-
import java.nio.ByteBuffer;
5352
import java.util.Iterator;
5453
import java.util.List;
5554
import java.util.Map;
@@ -202,7 +201,9 @@ public AtomicHistogramFieldData load(LeafReaderContext context) {
202201
public HistogramValues getHistogramValues() throws IOException {
203202
try {
204203
final BinaryDocValues values = DocValues.getBinary(context.reader(), fieldName);
204+
final InternalHistogramValue value = new InternalHistogramValue();
205205
return new HistogramValues() {
206+
206207
@Override
207208
public boolean advanceExact(int doc) throws IOException {
208209
return values.advanceExact(doc);
@@ -211,7 +212,8 @@ public boolean advanceExact(int doc) throws IOException {
211212
@Override
212213
public HistogramValue histogram() throws IOException {
213214
try {
214-
return getHistogramValue(values.binaryValue());
215+
value.reset(values.binaryValue());
216+
return value;
215217
} catch (IOException e) {
216218
throw new IOException("Cannot load doc value", e);
217219
}
@@ -220,7 +222,6 @@ public HistogramValue histogram() throws IOException {
220222
} catch (IOException e) {
221223
throw new IOException("Cannot load doc values", e);
222224
}
223-
224225
}
225226

226227
@Override
@@ -259,44 +260,6 @@ public SortField sortField(Object missingValue, MultiValueMode sortMode,
259260
}
260261
};
261262
}
262-
263-
private HistogramValue getHistogramValue(final BytesRef bytesRef) throws IOException {
264-
final ByteBufferStreamInput streamInput = new ByteBufferStreamInput(
265-
ByteBuffer.wrap(bytesRef.bytes, bytesRef.offset, bytesRef.length));
266-
return new HistogramValue() {
267-
double value;
268-
int count;
269-
boolean isExhausted;
270-
271-
@Override
272-
public boolean next() throws IOException {
273-
if (streamInput.available() > 0) {
274-
count = streamInput.readVInt();
275-
value = streamInput.readDouble();
276-
return true;
277-
}
278-
isExhausted = true;
279-
return false;
280-
}
281-
282-
@Override
283-
public double value() {
284-
if (isExhausted) {
285-
throw new IllegalArgumentException("histogram already exhausted");
286-
}
287-
return value;
288-
}
289-
290-
@Override
291-
public int count() {
292-
if (isExhausted) {
293-
throw new IllegalArgumentException("histogram already exhausted");
294-
}
295-
return count;
296-
}
297-
};
298-
}
299-
300263
};
301264
}
302265

@@ -395,21 +358,20 @@ public void parse(ParseContext context) throws IOException {
395358
"[" + COUNTS_FIELD.getPreferredName() +"] but got [" + values.size() + " != " + counts.size() +"]");
396359
}
397360
if (fieldType().hasDocValues()) {
398-
BytesStreamOutput streamOutput = new BytesStreamOutput();
361+
ByteBuffersDataOutput dataOutput = new ByteBuffersDataOutput();
399362
for (int i = 0; i < values.size(); i++) {
400363
int count = counts.get(i);
401364
if (count < 0) {
402365
throw new MapperParsingException("error parsing field ["
403366
+ name() + "], ["+ COUNTS_FIELD + "] elements must be >= 0 but got " + counts.get(i));
404367
} else if (count > 0) {
405368
// we do not add elements with count == 0
406-
streamOutput.writeVInt(count);
407-
streamOutput.writeDouble(values.get(i));
369+
dataOutput.writeVInt(count);
370+
dataOutput.writeLong(Double.doubleToRawLongBits(values.get(i)));
408371
}
409372
}
410-
411-
Field field = new BinaryDocValuesField(simpleName(), streamOutput.bytes().toBytesRef());
412-
streamOutput.close();
373+
BytesRef docValue = new BytesRef(dataOutput.toArrayCopy(), 0, Math.toIntExact(dataOutput.size()));
374+
Field field = new BinaryDocValuesField(simpleName(), docValue);
413375
if (context.doc().getByKey(fieldType().name()) != null) {
414376
throw new IllegalArgumentException("Field [" + name() + "] of type [" + typeName() +
415377
"] doesn't not support indexing multiple values for the same field in the same document");
@@ -439,4 +401,51 @@ protected void doXContentBody(XContentBuilder builder, boolean includeDefaults,
439401
builder.field(Names.IGNORE_MALFORMED, ignoreMalformed.value());
440402
}
441403
}
404+
405+
/** re-usable {@link HistogramValue} implementation */
406+
private static class InternalHistogramValue extends HistogramValue {
407+
double value;
408+
int count;
409+
boolean isExhausted;
410+
ByteArrayDataInput dataInput;
411+
412+
InternalHistogramValue() {
413+
dataInput = new ByteArrayDataInput();
414+
}
415+
416+
/** reset the value for the histogram */
417+
void reset(BytesRef bytesRef) {
418+
dataInput.reset(bytesRef.bytes, bytesRef.offset, bytesRef.length);
419+
isExhausted = false;
420+
value = 0;
421+
count = 0;
422+
}
423+
424+
@Override
425+
public boolean next() {
426+
if (dataInput.eof() == false) {
427+
count = dataInput.readVInt();
428+
value = Double.longBitsToDouble(dataInput.readLong());
429+
return true;
430+
}
431+
isExhausted = true;
432+
return false;
433+
}
434+
435+
@Override
436+
public double value() {
437+
if (isExhausted) {
438+
throw new IllegalArgumentException("histogram already exhausted");
439+
}
440+
return value;
441+
}
442+
443+
@Override
444+
public int count() {
445+
if (isExhausted) {
446+
throw new IllegalArgumentException("histogram already exhausted");
447+
}
448+
return count;
449+
}
450+
}
442451
}

0 commit comments

Comments
 (0)