Skip to content

Commit aa1c221

Browse files
committed
Merge remote-tracking branch 'elasticsearch/main' into fuse_out_of_snapshot
2 parents 026135b + 68ec7b1 commit aa1c221

File tree

72 files changed

+2622
-189
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

72 files changed

+2622
-189
lines changed

docs/changelog/134080.yaml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
pr: 134080
2+
summary: Added Google Model Garden Anthropic Completion and Chat Completion support to the Inference Plugin
3+
area: Machine Learning
4+
type: enhancement
5+
issues: []

docs/changelog/135051.yaml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,13 @@ summary: Ban Limit + `MvExpand` before remote Enrich
33
area: ES|QL
44
type: bug
55
issues: []
6+
highlight:
7+
title: Prevent LIMIT + MV_EXPAND before remote ENRICH
8+
body: |-
9+
Queries using LIMIT followed by MV_EXPAND before a remote ENRICH can produce incorrect results due to distributed execution semantics.
10+
These queries are now unsupported and produce an error. Example:
11+
[source,yaml]
12+
----------------------------
13+
FROM *:events | SORT @timestamp | LIMIT 2 | MV_EXPAND ip | ENRICH _remote:clientip_policy ON ip
14+
----------------------------
15+
To avoid this error, reorder your query, for example by moving ENRICH earlier in the pipeline.

docs/changelog/135204.yaml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
pr: 135204
2+
summary: Make `_tsid` available in metadata
3+
area: ES|QL
4+
type: enhancement
5+
issues:
6+
- 133205

docs/changelog/135337.yaml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
pr: 135337
2+
summary: Do not pass `ProjectMetadata` to lazy index permissions builder
3+
area: Security
4+
type: enhancement
5+
issues: []

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

Lines changed: 25 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -56,12 +56,21 @@ public class ExponentialHistogramMerger implements Accountable, Releasable {
5656
/**
5757
* Creates a new instance with the specified bucket limit.
5858
*
59-
* @param bucketLimit the maximum number of buckets the result histogram is allowed to have
59+
* @param bucketLimit the maximum number of buckets the result histogram is allowed to have, must be at least 4
6060
* @param circuitBreaker the circuit breaker to use to limit memory allocations
6161
*/
6262
public static ExponentialHistogramMerger create(int bucketLimit, ExponentialHistogramCircuitBreaker circuitBreaker) {
6363
circuitBreaker.adjustBreaker(BASE_SIZE);
64-
return new ExponentialHistogramMerger(bucketLimit, circuitBreaker);
64+
boolean success = false;
65+
try {
66+
ExponentialHistogramMerger result = new ExponentialHistogramMerger(bucketLimit, circuitBreaker);
67+
success = true;
68+
return result;
69+
} finally {
70+
if (success == false) {
71+
circuitBreaker.adjustBreaker(-BASE_SIZE);
72+
}
73+
}
6574
}
6675

6776
private ExponentialHistogramMerger(int bucketLimit, ExponentialHistogramCircuitBreaker circuitBreaker) {
@@ -70,6 +79,10 @@ private ExponentialHistogramMerger(int bucketLimit, ExponentialHistogramCircuitB
7079

7180
// Only intended for testing, using this in production means an unnecessary reduction of precision
7281
private ExponentialHistogramMerger(int bucketLimit, int maxScale, ExponentialHistogramCircuitBreaker circuitBreaker) {
82+
// We need at least four buckets to represent any possible distribution
83+
if (bucketLimit < 4) {
84+
throw new IllegalArgumentException("The bucket limit must be at least 4");
85+
}
7386
this.bucketLimit = bucketLimit;
7487
this.maxScale = maxScale;
7588
this.circuitBreaker = circuitBreaker;
@@ -124,11 +137,16 @@ public ReleasableExponentialHistogram getAndClear() {
124137
return retVal;
125138
}
126139

127-
// TODO(b/128622): this algorithm is very efficient if b has roughly as many buckets as a
128-
// However, if b is much smaller we still have to iterate over all buckets of a which is very wasteful.
129-
// This can be optimized by buffering multiple histograms to accumulate first,
130-
// then in O(log(n)) turn them into a single, merged histogram.
131-
// (n is the number of buffered buckets)
140+
// This algorithm is very efficient if B has roughly as many buckets as A.
141+
// However, if B is much smaller we still have to iterate over all buckets of A.
142+
// This can be optimized by buffering the buckets of small histograms and only merging them when we have enough buckets.
143+
// The buffered histogram buckets would first be merged with each other, and then be merged with accumulator.
144+
//
145+
// However, benchmarks of a PoC implementation have shown that this only brings significant improvements
146+
// if the accumulator size is 500+ and the merged histograms are smaller than 50 buckets
147+
// and otherwise slows down the merging.
148+
// It would be possible to only enable the buffering for small histograms,
149+
// but the optimization seems not worth the added complexity at this point.
132150

133151
/**
134152
* Merges the given histogram into the current result.

libs/exponential-histogram/src/test/java/org/elasticsearch/exponentialhistogram/ExponentialHistogramGeneratorTests.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ public class ExponentialHistogramGeneratorTests extends ExponentialHistogramTest
3333

3434
public void testVeryLargeValue() {
3535
double value = Double.MAX_VALUE / 10;
36-
ExponentialHistogram histo = createAutoReleasedHistogram(1, value);
36+
ExponentialHistogram histo = createAutoReleasedHistogram(4, value);
3737
long index = histo.positiveBuckets().iterator().peekIndex();
3838
int scale = histo.scale();
3939

libs/exponential-histogram/src/test/java/org/elasticsearch/exponentialhistogram/ExponentialHistogramMergerTests.java

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
import static org.elasticsearch.exponentialhistogram.ExponentialHistogram.MIN_INDEX;
3737
import static org.elasticsearch.exponentialhistogram.ExponentialScaleUtils.adjustScale;
3838
import static org.hamcrest.Matchers.closeTo;
39+
import static org.hamcrest.Matchers.containsString;
3940
import static org.hamcrest.Matchers.equalTo;
4041
import static org.hamcrest.Matchers.greaterThan;
4142

@@ -112,7 +113,7 @@ public void testAggregatesCorrectness() {
112113
try (
113114
// Merge some empty histograms too to test that code path
114115
ReleasableExponentialHistogram merged = ExponentialHistogram.merge(
115-
2,
116+
4,
116117
breaker(),
117118
ExponentialHistogram.empty(),
118119
createAutoReleasedHistogram(10, firstValues),
@@ -153,6 +154,15 @@ public void testUpscalingDoesNotExceedIndexLimits() {
153154
}
154155
}
155156

157+
public void testMinimumBucketCountBounded() {
158+
try {
159+
ExponentialHistogram.merge(3, breaker(), ExponentialHistogram.empty(), ExponentialHistogram.empty());
160+
fail("Expected exception");
161+
} catch (IllegalArgumentException e) {
162+
assertThat(e.getMessage(), containsString("limit must be at least 4"));
163+
}
164+
}
165+
156166
/**
157167
* Verify that the resulting histogram is independent of the order of elements and therefore merges performed.
158168
*/

libs/exponential-histogram/src/test/java/org/elasticsearch/exponentialhistogram/ExponentialHistogramUtilsTests.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ public class ExponentialHistogramUtilsTests extends ExponentialHistogramTestCase
3131
public void testRandomDataSumEstimation() {
3232
for (int i = 0; i < 100; i++) {
3333
int valueCount = randomIntBetween(100, 10_000);
34-
int bucketCount = randomIntBetween(2, 500);
34+
int bucketCount = randomIntBetween(4, 500);
3535

3636
double correctSum = 0;
3737
double sign = randomBoolean() ? 1 : -1;

libs/exponential-histogram/src/test/java/org/elasticsearch/exponentialhistogram/QuantileAccuracyTests.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -159,7 +159,7 @@ public void testEmptyHistogram() {
159159
}
160160

161161
public void testSingleValueHistogram() {
162-
ExponentialHistogram histo = createAutoReleasedHistogram(1, 42.0);
162+
ExponentialHistogram histo = createAutoReleasedHistogram(4, 42.0);
163163
for (double q : QUANTILES_TO_TEST) {
164164
assertThat(ExponentialHistogramQuantile.getQuantile(histo, q), closeTo(42, 0.0000001));
165165
}

libs/x-content/impl/src/main/java/org/elasticsearch/xcontent/provider/json/ESUTF8StreamJsonParser.java

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,12 @@
2525
import java.util.ArrayList;
2626
import java.util.List;
2727

28+
/**
29+
* Provides the method getValueAsText that is a best-effort optimization for UTF8 fields. If the
30+
* {@link UTF8StreamJsonParser} has already parsed the text, then the caller should fall back to getText.
31+
* This is sufficient because when we call getText, jackson stores the parsed UTF-16 value for future calls.
32+
* Once we've already got the parsed UTF-16 value, the optimization isn't necessary.
33+
*/
2834
public class ESUTF8StreamJsonParser extends UTF8StreamJsonParser implements OptimizedTextCapable {
2935
protected int stringEnd = -1;
3036
protected int stringLength;
@@ -53,6 +59,7 @@ public ESUTF8StreamJsonParser(
5359
*/
5460
@Override
5561
public Text getValueAsText() throws IOException {
62+
// _tokenIncomplete is true when UTF8StreamJsonParser has already processed this value.
5663
if (_currToken == JsonToken.VALUE_STRING && _tokenIncomplete) {
5764
if (lastOptimisedValue != null) {
5865
return new Text(new XContentString.UTF8Bytes(lastOptimisedValue), stringLength);
@@ -148,33 +155,33 @@ protected Text _finishAndReturnText() throws IOException {
148155

149156
@Override
150157
public JsonToken nextToken() throws IOException {
151-
maybeResetCurrentTokenState();
152-
stringEnd = -1;
158+
resetCurrentTokenState();
153159
return super.nextToken();
154160
}
155161

156162
@Override
157163
public boolean nextFieldName(SerializableString str) throws IOException {
158-
maybeResetCurrentTokenState();
159-
stringEnd = -1;
164+
resetCurrentTokenState();
160165
return super.nextFieldName(str);
161166
}
162167

163168
@Override
164169
public String nextFieldName() throws IOException {
165-
maybeResetCurrentTokenState();
166-
stringEnd = -1;
170+
resetCurrentTokenState();
167171
return super.nextFieldName();
168172
}
169173

170174
/**
171-
* Resets the current token state before moving to the next.
175+
* Resets the current token state before moving to the next. It resets the _inputPtr and the
176+
* _tokenIncomplete only if {@link UTF8StreamJsonParser#getText()} or {@link UTF8StreamJsonParser#getValueAsString()}
177+
* hasn't run yet.
172178
*/
173-
private void maybeResetCurrentTokenState() {
179+
private void resetCurrentTokenState() {
174180
if (_currToken == JsonToken.VALUE_STRING && _tokenIncomplete && stringEnd > 0) {
175181
_inputPtr = stringEnd;
176182
_tokenIncomplete = false;
177-
lastOptimisedValue = null;
178183
}
184+
lastOptimisedValue = null;
185+
stringEnd = -1;
179186
}
180187
}

0 commit comments

Comments
 (0)