Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
/*
* SPDX-License-Identifier: Apache-2.0
*
* The OpenSearch Contributors require contributions made to
* this file be licensed under the Apache-2.0 license or a
* compatible open source license.
*/
package org.opensearch.index.fielddata;

import org.apache.lucene.index.LeafReaderContext;
import org.apache.lucene.search.SortField;
import org.opensearch.common.util.BigArrays;
import org.opensearch.search.DocValueFormat;
import org.opensearch.search.MultiValueMode;
import org.opensearch.search.aggregations.support.CoreValuesSourceType;
import org.opensearch.search.aggregations.support.ValuesSourceType;
import org.opensearch.search.sort.BucketedSort;
import org.opensearch.search.sort.SortOrder;

public class HistogramIndexFieldData implements IndexFieldData<HistogramLeafFieldData> {
private final String fieldName;

public HistogramIndexFieldData(String fieldName) {
this.fieldName = fieldName;
}

@Override
public String getFieldName() {
return fieldName;
}

@Override
public ValuesSourceType getValuesSourceType() {
return CoreValuesSourceType.HISTOGRAM;
}

@Override
public HistogramLeafFieldData load(LeafReaderContext context) {
return new HistogramLeafFieldData(context.reader(), fieldName);
}

@Override
public HistogramLeafFieldData loadDirect(LeafReaderContext context) throws Exception {
return load(context);
}

@Override
public SortField wideSortField(Object missingValue, MultiValueMode sortMode, XFieldComparatorSource.Nested nested, boolean reverse) {
return IndexFieldData.super.wideSortField(missingValue, sortMode, nested, reverse);
}

@Override
public BucketedSort newBucketedSort(BigArrays bigArrays, Object missingValue, MultiValueMode sortMode, XFieldComparatorSource.Nested nested, SortOrder sortOrder, DocValueFormat format, int bucketSize, BucketedSort.ExtraData extra) {
return null;
}

@Override
public SortField sortField(Object missingValue, MultiValueMode sortMode, XFieldComparatorSource.Nested nested, boolean reverse) {
throw new UnsupportedOperationException("Histogram fields do not support sorting");
}
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
/*
* SPDX-License-Identifier: Apache-2.0
*
* The OpenSearch Contributors require contributions made to
* this file be licensed under the Apache-2.0 license or a
* compatible open source license.
*/

package org.opensearch.index.fielddata;

import org.apache.lucene.index.BinaryDocValues;
import org.apache.lucene.index.DocValues;
import org.apache.lucene.index.LeafReader;
import org.apache.lucene.util.BytesRef;
import org.opensearch.indices.fielddata.Histogram;

import java.io.IOException;
import java.nio.ByteBuffer;

public class HistogramLeafFieldData implements LeafFieldData {
private final LeafReader reader;
private final String fieldName;

public HistogramLeafFieldData(LeafReader reader, String fieldName) {
this.reader = reader;
this.fieldName = fieldName;
}

public HistogramValues getHistogramValues() throws IOException {
final BinaryDocValues values = DocValues.getBinary(reader, fieldName);
return new HistogramValues() {
@Override
public boolean advanceExact(int doc) throws IOException {
return values.advanceExact(doc);
}

@Override
public Histogram histogram() throws IOException {
BytesRef bytesRef = values.binaryValue();
return decodeHistogram(bytesRef);
}
};
}

private Histogram decodeHistogram(BytesRef bytesRef) {
ByteBuffer buffer = ByteBuffer.wrap(bytesRef.bytes, bytesRef.offset, bytesRef.length);
int size = buffer.getInt();
double[] values = new double[size];
long[] counts = new long[size];

for (int i = 0; i < size; i++) {
values[i] = buffer.getDouble();
counts[i] = buffer.getLong();
}

return new Histogram(values, counts);
}

@Override
public void close() {}

@Override
public ScriptDocValues<?> getScriptValues() {
return null;
}

@Override
public SortedBinaryDocValues getBytesValues() {
return null;
}

@Override
public long ramBytesUsed() {
return 0;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@

package org.opensearch.index.fielddata;

import org.opensearch.indices.fielddata.Histogram;

import java.io.IOException;

/**
Expand All @@ -51,6 +53,6 @@ public abstract class HistogramValues {
* Get the {@link HistogramValue} associated with the current document.
* The returned {@link HistogramValue} might be reused across calls.
*/
Comment on lines 53 to 55
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Update javadoc to reflect the new return type.

The javadoc still references HistogramValue, but the method now returns Histogram. Update the comment to match the actual return type.

🔎 Proposed fix
     /**
-     * Get the {@link HistogramValue} associated with the current document.
-     * The returned {@link HistogramValue} might be reused across calls.
+     * Get the {@link Histogram} associated with the current document.
+     * The returned {@link Histogram} might be reused across calls.
      */
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
* Get the {@link HistogramValue} associated with the current document.
* The returned {@link HistogramValue} might be reused across calls.
*/
* Get the {@link Histogram} associated with the current document.
* The returned {@link Histogram} might be reused across calls.
*/
🤖 Prompt for AI Agents
In @server/src/main/java/org/opensearch/index/fielddata/HistogramValues.java
around lines 53-55, The Javadoc for the method in class HistogramValues still
refers to HistogramValue but the method now returns Histogram; update the
documentation to reference the correct return type (Histogram) and any related
wording (e.g., "Get the Histogram associated with the current document" and note
reuse of the returned Histogram) so the comment matches the actual return type
and behavior of the method.

public abstract HistogramValue histogram() throws IOException;
public abstract Histogram histogram() throws IOException;

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
/*
* SPDX-License-Identifier: Apache-2.0
*
* The OpenSearch Contributors require contributions made to
* this file be licensed under the Apache-2.0 license or a
* compatible open source license.
*/

package org.opensearch.index.fielddata;

import org.apache.lucene.index.LeafReaderContext;
import org.apache.lucene.index.SortedNumericDocValues;
import org.apache.lucene.util.BytesRef;
import org.opensearch.indices.fielddata.Histogram;
import org.opensearch.search.aggregations.support.ValuesSource;

import java.io.IOException;
import java.nio.ByteBuffer;

public class HistogramValuesSource extends ValuesSource.Numeric {
private final HistogramIndexFieldData indexFieldData;

public HistogramValuesSource(HistogramIndexFieldData indexFieldData) {
this.indexFieldData = indexFieldData;
}

public HistogramIndexFieldData getHistogramFieldData() {
return indexFieldData;
}

@Override
public boolean isFloatingPoint() {
return true;
}

@Override
public boolean isBigInteger() {
return false;
}

@Override
public SortedNumericDocValues longValues(LeafReaderContext context) throws IOException {
throw new UnsupportedOperationException("Histogram fields only support double values");
}

@Override
public SortedNumericDoubleValues doubleValues(LeafReaderContext context) throws IOException {
final HistogramLeafFieldData leafFieldData = indexFieldData.load(context);
final HistogramValues histogramValues = leafFieldData.getHistogramValues();

return new SortedNumericDoubleValues() {
private double[] currentValues;
private int currentValueIndex;

@Override
public boolean advanceExact(int doc) throws IOException {
if (histogramValues.advanceExact(doc)) {
Histogram histogram = histogramValues.histogram();
currentValues = histogram.getValues();
currentValueIndex = 0;
return currentValues.length > 0;
}
currentValues = null;
return false;
}

@Override
public double nextValue() throws IOException {
if (currentValues == null || currentValueIndex >= currentValues.length) {
throw new IllegalStateException("Cannot call nextValue() when there are no more values");
}
return currentValues[currentValueIndex++];
}

@Override
public int docValueCount() {
return currentValues == null ? 0 : currentValues.length;
}
};
}

/**
* Returns the counts values for the histogram buckets as doubles.
* These represent the frequency/count per bucket.
*/
public SortedNumericDoubleValues getCounts(LeafReaderContext context) throws IOException {
final HistogramLeafFieldData leafFieldData = indexFieldData.load(context);
final HistogramValues histogramValues = leafFieldData.getHistogramValues();

return new SortedNumericDoubleValues() {
private long[] currentCounts;
private int currentIndex;

@Override
public boolean advanceExact(int doc) throws IOException {
if (histogramValues.advanceExact(doc)) {
Histogram histogram = histogramValues.histogram();
currentCounts = histogram.getCounts();
currentIndex = 0;
return currentCounts.length > 0;
}
currentCounts = null;
return false;
}

@Override
public double nextValue() throws IOException {
if (currentCounts == null || currentIndex >= currentCounts.length) {
throw new IllegalStateException("Cannot call nextValue() when there are no more count values");
}
return (double) currentCounts[currentIndex++];
}

@Override
public int docValueCount() {
return currentCounts == null ? 0 : currentCounts.length;
}
};
}

private double decodeMin(BytesRef bytesRef) {
ByteBuffer buffer = ByteBuffer.wrap(bytesRef.bytes, bytesRef.offset, bytesRef.length);
int size = buffer.getInt();
if (size > 0) {
return buffer.getDouble();
}
return Double.NaN;
}

@Override
public SortedBinaryDocValues bytesValues(LeafReaderContext context) throws IOException {
return null;
}
}
Loading
Loading