Skip to content

Commit 1ad6b22

Browse files
committed
Merge branch 'main' into centroid_versample
2 parents fd5ff38 + 3c264cf commit 1ad6b22

File tree

32 files changed

+985
-158
lines changed

32 files changed

+985
-158
lines changed

benchmarks/src/main/java/org/elasticsearch/benchmark/exponentialhistogram/ExponentialHistogramMergeBench.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,7 @@ private ExponentialHistogram asCompressedHistogram(ExponentialHistogram histogra
130130
CompressedExponentialHistogram.writeHistogramBytes(histoBytes, histogram.scale(), negativeBuckets, positiveBuckets);
131131
CompressedExponentialHistogram result = new CompressedExponentialHistogram();
132132
BytesRef data = histoBytes.bytes().toBytesRef();
133-
result.reset(histogram.zeroBucket().zeroThreshold(), totalCount, histogram.sum(), histogram.min(), data);
133+
result.reset(histogram.zeroBucket().zeroThreshold(), totalCount, histogram.sum(), histogram.min(), histogram.max(), data);
134134
return result;
135135
} catch (IOException e) {
136136
throw new RuntimeException(e);

branches.json

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,29 @@
11
{
2-
"notice": "This file is not maintained outside of the main branch and should only be used for tooling.",
3-
"branches": [
2+
"notice" : "This file is not maintained outside of the main branch and should only be used for tooling.",
3+
"branches" : [
44
{
5-
"branch": "main"
5+
"branch" : "main",
6+
"version" : "9.2.0"
67
},
78
{
8-
"branch": "9.1"
9+
"branch" : "9.1",
10+
"version" : "9.1.4"
911
},
1012
{
11-
"branch": "9.0"
13+
"branch" : "9.0",
14+
"version" : "9.0.7"
1215
},
1316
{
14-
"branch": "8.19"
17+
"branch" : "8.19",
18+
"version" : "8.19.4"
1519
},
1620
{
17-
"branch": "8.18"
21+
"branch" : "8.18",
22+
"version" : "8.18.7"
1823
},
1924
{
20-
"branch": "7.17"
25+
"branch" : "7.17",
26+
"version" : "7.17.30"
2127
}
2228
]
2329
}

docs/reference/elasticsearch/mapping-reference/dense-vector.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -274,7 +274,7 @@ The following mapping parameters are accepted:
274274
$$$dense-vector-element-type$$$
275275

276276
`element_type`
277-
: (Optional, string) The data type used to encode vectors. The supported data types are `float` (default), `byte`, and bit.
277+
: (Optional, string) The data type used to encode vectors. The supported data types are `float` (default), `byte`, and `bit`.
278278

279279
::::{dropdown} Valid values for element_type
280280
`float`

docs/reference/elasticsearch/mapping-reference/rank-vectors.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ The `rank_vectors` field type supports the following parameters:
9090
$$$rank-vectors-element-type$$$
9191

9292
`element_type`
93-
: (Optional, string) The data type used to encode vectors. The supported data types are `float` (default), `byte`, and bit.
93+
: (Optional, string) The data type used to encode vectors. The supported data types are `float` (default), `byte`, and `bit`.
9494

9595
::::{dropdown} Valid values for element_type
9696
`float`

libs/exponential-histogram/src/main/java/org/elasticsearch/exponentialhistogram/AbstractExponentialHistogram.java

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,4 +46,54 @@ public boolean equals(Object obj) {
4646
}
4747
return false;
4848
}
49+
50+
@Override
51+
public String toString() {
52+
StringBuilder sb = new StringBuilder(getClassNameWithoutPackage()).append("{");
53+
sb.append("scale=").append(scale());
54+
sb.append(", sum=").append(sum());
55+
sb.append(", valueCount=").append(valueCount());
56+
sb.append(", min=").append(min());
57+
sb.append(", max=").append(max());
58+
ZeroBucket zb = zeroBucket();
59+
if (zb.zeroThreshold() != 0) {
60+
sb.append(", zeroThreshold=").append(zb.zeroThreshold());
61+
}
62+
if (zb.count() != 0) {
63+
sb.append(", zeroCount=").append(zb.count());
64+
}
65+
BucketIterator neg = negativeBuckets().iterator();
66+
if (neg.hasNext()) {
67+
sb.append(", negative=[");
68+
appendsBucketsAsString(sb, neg);
69+
sb.append("]");
70+
}
71+
BucketIterator pos = positiveBuckets().iterator();
72+
if (pos.hasNext()) {
73+
sb.append(", positive=[");
74+
appendsBucketsAsString(sb, pos);
75+
sb.append("]");
76+
}
77+
sb.append("}");
78+
return sb.toString();
79+
}
80+
81+
private String getClassNameWithoutPackage() {
82+
String fqn = getClass().getName();
83+
int lastDot = fqn.lastIndexOf('.');
84+
return fqn.substring(lastDot + 1);
85+
}
86+
87+
private static void appendsBucketsAsString(StringBuilder out, BucketIterator it) {
88+
boolean first = true;
89+
while (it.hasNext()) {
90+
if (first) {
91+
first = false;
92+
} else {
93+
out.append(", ");
94+
}
95+
out.append(it.peekIndex()).append(": ").append(it.peekCount());
96+
it.advance();
97+
}
98+
}
4999
}

libs/exponential-histogram/src/main/java/org/elasticsearch/exponentialhistogram/EmptyExponentialHistogram.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,11 @@ public double min() {
8787
return Double.NaN;
8888
}
8989

90+
@Override
91+
public double max() {
92+
return Double.NaN;
93+
}
94+
9095
@Override
9196
public long ramBytesUsed() {
9297
return 0;

libs/exponential-histogram/src/main/java/org/elasticsearch/exponentialhistogram/ExponentialHistogram.java

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,6 @@
4747
*/
4848
public interface ExponentialHistogram extends Accountable {
4949

50-
// TODO(b/128622): support min/max storage and merging.
5150
// TODO(b/128622): Add special positive and negative infinity buckets
5251
// to allow representation of explicit bucket histograms with open boundaries.
5352

@@ -117,6 +116,13 @@ public interface ExponentialHistogram extends Accountable {
117116
*/
118117
double min();
119118

119+
/**
120+
* Returns maximum of all values represented by this histogram.
121+
*
122+
* @return the maximum, NaN for empty histograms
123+
*/
124+
double max();
125+
120126
/**
121127
* Represents a bucket range of an {@link ExponentialHistogram}, either the positive or the negative range.
122128
*/
@@ -154,6 +160,7 @@ static boolean equals(ExponentialHistogram a, ExponentialHistogram b) {
154160
return a.scale() == b.scale()
155161
&& a.sum() == b.sum()
156162
&& equalsIncludingNaN(a.min(), b.min())
163+
&& equalsIncludingNaN(a.max(), b.max())
157164
&& a.zeroBucket().equals(b.zeroBucket())
158165
&& bucketIteratorsEqual(a.negativeBuckets().iterator(), b.negativeBuckets().iterator())
159166
&& bucketIteratorsEqual(a.positiveBuckets().iterator(), b.positiveBuckets().iterator());
@@ -187,6 +194,7 @@ static int hashCode(ExponentialHistogram histogram) {
187194
hash = 31 * hash + Double.hashCode(histogram.sum());
188195
hash = 31 * hash + Long.hashCode(histogram.valueCount());
189196
hash = 31 * hash + Double.hashCode(histogram.min());
197+
hash = 31 * hash + Double.hashCode(histogram.max());
190198
hash = 31 * hash + histogram.zeroBucket().hashCode();
191199
// we intentionally don't include the hash of the buckets here, because that is likely expensive to compute
192200
// instead, we assume that the value count and sum are a good enough approximation in most cases to minimize collisions

libs/exponential-histogram/src/main/java/org/elasticsearch/exponentialhistogram/ExponentialHistogramGenerator.java

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,7 @@ private void mergeValuesToHistogram() {
126126
Aggregates aggregates = rawValuesAggregates();
127127
valueBuffer.setSum(aggregates.sum());
128128
valueBuffer.setMin(aggregates.min());
129+
valueBuffer.setMax(aggregates.max());
129130
int scale = valueBuffer.scale();
130131

131132
// Buckets must be provided with their indices in ascending order.
@@ -166,15 +167,17 @@ private void mergeValuesToHistogram() {
166167

167168
private Aggregates rawValuesAggregates() {
168169
if (valueCount == 0) {
169-
return new Aggregates(0, Double.NaN);
170+
return new Aggregates(0, Double.NaN, Double.NaN);
170171
}
171172
double sum = 0;
172173
double min = Double.MAX_VALUE;
174+
double max = -Double.MAX_VALUE;
173175
for (int i = 0; i < valueCount; i++) {
174176
sum += rawValueBuffer[i];
175177
min = Math.min(min, rawValueBuffer[i]);
178+
max = Math.max(max, rawValueBuffer[i]);
176179
}
177-
return new Aggregates(sum, min);
180+
return new Aggregates(sum, min, max);
178181
}
179182

180183
private static long estimateBaseSize(int numBuckets) {
@@ -198,5 +201,5 @@ public void close() {
198201
}
199202
}
200203

201-
private record Aggregates(double sum, double min) {}
204+
private record Aggregates(double sum, double min, double max) {}
202205
}

libs/exponential-histogram/src/main/java/org/elasticsearch/exponentialhistogram/ExponentialHistogramMerger.java

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
import org.elasticsearch.core.Releasable;
2828

2929
import java.util.OptionalLong;
30+
import java.util.function.DoubleBinaryOperator;
3031

3132
import static org.elasticsearch.exponentialhistogram.ExponentialScaleUtils.getMaximumScaleIncrease;
3233

@@ -151,7 +152,8 @@ public void add(ExponentialHistogram toAdd) {
151152
}
152153
buffer.setZeroBucket(zeroBucket);
153154
buffer.setSum(a.sum() + b.sum());
154-
buffer.setMin(nanAwareMin(a.min(), b.min()));
155+
buffer.setMin(nanAwareAggregate(a.min(), b.min(), Math::min));
156+
buffer.setMax(nanAwareAggregate(a.max(), b.max(), Math::max));
155157
// We attempt to bring everything to the scale of A.
156158
// This might involve increasing the scale for B, which would increase its indices.
157159
// We need to ensure that we do not exceed MAX_INDEX / MIN_INDEX in this case.
@@ -231,14 +233,14 @@ private static int putBuckets(
231233
return overflowCount;
232234
}
233235

234-
private static double nanAwareMin(double a, double b) {
236+
private static double nanAwareAggregate(double a, double b, DoubleBinaryOperator aggregator) {
235237
if (Double.isNaN(a)) {
236238
return b;
237239
}
238240
if (Double.isNaN(b)) {
239241
return a;
240242
}
241-
return Math.min(a, b);
243+
return aggregator.applyAsDouble(a, b);
242244
}
243245

244246
}

libs/exponential-histogram/src/main/java/org/elasticsearch/exponentialhistogram/ExponentialHistogramUtils.java

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ public static double estimateSum(BucketIterator negativeBuckets, BucketIterator
6767
* Estimates the minimum value of the histogram based on the populated buckets.
6868
* The returned value is guaranteed to be less than or equal to the exact minimum value of the histogram values.
6969
* If the histogram is empty, an empty Optional is returned.
70-
*
70+
* <p>
7171
* Note that this method can return +-Infinity if the histogram bucket boundaries are not representable in a double.
7272
*
7373
* @param zeroBucket the zero bucket of the histogram
@@ -102,4 +102,40 @@ public static OptionalDouble estimateMin(
102102
}
103103
return OptionalDouble.empty();
104104
}
105+
106+
/**
107+
* Estimates the maximum value of the histogram based on the populated buckets.
108+
* The returned value is guaranteed to be greater than or equal to the exact maximum value of the histogram values.
109+
* If the histogram is empty, an empty Optional is returned.
110+
* <p>
111+
* Note that this method can return +-Infinity if the histogram bucket boundaries are not representable in a double.
112+
*
113+
* @param zeroBucket the zero bucket of the histogram
114+
* @param negativeBuckets the negative buckets of the histogram
115+
* @param positiveBuckets the positive buckets of the histogram
116+
* @return the estimated minimum
117+
*/
118+
public static OptionalDouble estimateMax(
119+
ZeroBucket zeroBucket,
120+
ExponentialHistogram.Buckets negativeBuckets,
121+
ExponentialHistogram.Buckets positiveBuckets
122+
) {
123+
int scale = negativeBuckets.iterator().scale();
124+
assert scale == positiveBuckets.iterator().scale();
125+
126+
OptionalLong positiveMaxIndex = positiveBuckets.maxBucketIndex();
127+
if (positiveMaxIndex.isPresent()) {
128+
return OptionalDouble.of(ExponentialScaleUtils.getUpperBucketBoundary(positiveMaxIndex.getAsLong(), scale));
129+
}
130+
131+
if (zeroBucket.count() > 0) {
132+
return OptionalDouble.of(zeroBucket.zeroThreshold());
133+
}
134+
135+
BucketIterator negativeBucketsIt = negativeBuckets.iterator();
136+
if (negativeBucketsIt.hasNext()) {
137+
return OptionalDouble.of(-ExponentialScaleUtils.getLowerBucketBoundary(negativeBucketsIt.peekIndex(), scale));
138+
}
139+
return OptionalDouble.empty();
140+
}
105141
}

0 commit comments

Comments
 (0)