Skip to content

Commit 8ffb7fc

Browse files
committed
use Randomness.get()
1 parent 0386e63 commit 8ffb7fc

File tree

12 files changed

+117
-36
lines changed

12 files changed

+117
-36
lines changed
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
/*
2+
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
3+
* or more contributor license agreements. Licensed under the "Elastic License
4+
* 2.0", the "GNU Affero General Public License v3.0 only", and the "Server Side
5+
* Public License v 1"; you may not use this file except in compliance with, at
6+
* your election, the "Elastic License 2.0", the "GNU Affero General Public
7+
* License v3.0 only", or the "Server Side Public License, v 1".
8+
*/
9+
10+
package org.elasticsearch.test;
11+
12+
import com.carrotsearch.randomizedtesting.SeedDecorator;
13+
14+
import org.elasticsearch.common.Randomness;
15+
16+
import java.util.concurrent.atomic.AtomicLong;
17+
18+
/**
19+
* The {@link Randomness} class creates random generators with the same seed
20+
* in every thread.
21+
* <p>
22+
* This means that repeatedly calling:
23+
* <pre>
24+
* {@code
25+
* new Thread(() -> System.out.println(Randomness.get().nextInt())).start();
26+
* }
27+
* </pre>
28+
* will print the same number in every thread.
29+
* <p>
30+
* For some use cases, this is not desirable, e.g. when testing that the random
31+
* behavior obeys certain statistical properties.
32+
* <p>
33+
* To fix this, annotate a test class with:
34+
* <pre>
35+
* {@code
36+
* @SeedDecorators(MixWithIncrement.class)
37+
* }
38+
* </pre>
39+
* In this way, an additional seed is mixed into the seed of the random generators.
40+
* This additional seed can be updated be calling:
41+
* <pre>
42+
* {@code
43+
* MixWithIncrement.next()
44+
* }
45+
* </pre>
46+
* to make sure that new threads will get a different seed.
47+
*/
48+
public class MixWithIncrement implements SeedDecorator {
49+
50+
private static final AtomicLong mix = new AtomicLong(1);
51+
52+
@Override
53+
public void initialize(Class<?> aClass) {
54+
next();
55+
}
56+
57+
public long decorate(long seed) {
58+
return seed ^ mix.get();
59+
}
60+
61+
public static void next() {
62+
mix.updateAndGet(MixWithIncrement::fmix64);
63+
}
64+
65+
private static long fmix64(long k) {
66+
k ^= k >>> 33;
67+
k *= -49064778989728563L;
68+
k ^= k >>> 33;
69+
k *= -4265267296055464877L;
70+
k ^= k >>> 33;
71+
return k;
72+
}
73+
}

x-pack/plugin/esql/compute/src/main/generated-src/org/elasticsearch/compute/aggregation/SampleBooleanAggregator.java

Lines changed: 3 additions & 6 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

x-pack/plugin/esql/compute/src/main/generated-src/org/elasticsearch/compute/aggregation/SampleBytesRefAggregator.java

Lines changed: 3 additions & 6 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

x-pack/plugin/esql/compute/src/main/generated-src/org/elasticsearch/compute/aggregation/SampleDoubleAggregator.java

Lines changed: 3 additions & 6 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

x-pack/plugin/esql/compute/src/main/generated-src/org/elasticsearch/compute/aggregation/SampleIntAggregator.java

Lines changed: 3 additions & 6 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

x-pack/plugin/esql/compute/src/main/generated-src/org/elasticsearch/compute/aggregation/SampleLongAggregator.java

Lines changed: 3 additions & 6 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

x-pack/plugin/esql/compute/src/main/java/org/elasticsearch/compute/aggregation/X-SampleAggregator.java.st

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ import org.elasticsearch.compute.operator.topn.DefaultUnsortableTopNEncoder;
2626
import org.elasticsearch.core.Releasables;
2727
import org.elasticsearch.search.sort.SortOrder;
2828

29-
import java.util.SplittableRandom;
29+
import org.elasticsearch.common.Randomness;
3030
import java.util.random.RandomGenerator;
3131
// end generated imports
3232

@@ -125,20 +125,17 @@ class Sample$Type$Aggregator {
125125
}
126126

127127
public static class GroupingState implements GroupingAggregatorState {
128-
private final CircuitBreaker breaker;
129128
private final BytesRefBucketedSort sort;
130129
private final BreakingBytesRefBuilder bytesRefBuilder;
131-
private final RandomGenerator random;
132130

133131
private GroupingState(BigArrays bigArrays, int limit) {
134-
this.breaker = bigArrays.breakerService().getBreaker(CircuitBreaker.REQUEST);
132+
CircuitBreaker breaker = bigArrays.breakerService().getBreaker(CircuitBreaker.REQUEST);
135133
this.sort = new BytesRefBucketedSort(breaker, "sample", bigArrays, SortOrder.ASC, limit);
136134
this.bytesRefBuilder = new BreakingBytesRefBuilder(breaker, "sample");
137-
this.random = new SplittableRandom();
138135
}
139136

140137
public void add(int groupId, $type$ value) {
141-
ENCODER.encodeLong(random.nextLong(), bytesRefBuilder);
138+
ENCODER.encodeLong(Randomness.get().nextLong(), bytesRefBuilder);
142139
ENCODER.encode$Type$(value, bytesRefBuilder);
143140
sort.collect(bytesRefBuilder.bytesRefView(), groupId);
144141
bytesRefBuilder.clear();

x-pack/plugin/esql/compute/src/test/java/org/elasticsearch/compute/aggregation/SampleBooleanAggregatorFunctionTests.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77

88
package org.elasticsearch.compute.aggregation;
99

10+
import com.carrotsearch.randomizedtesting.annotations.SeedDecorators;
11+
1012
import org.elasticsearch.compute.data.Block;
1113
import org.elasticsearch.compute.data.BlockFactory;
1214
import org.elasticsearch.compute.data.BooleanBlock;
@@ -15,6 +17,7 @@
1517
import org.elasticsearch.compute.operator.SequenceBooleanBlockSourceOperator;
1618
import org.elasticsearch.compute.operator.SourceOperator;
1719
import org.elasticsearch.compute.test.CannedSourceOperator;
20+
import org.elasticsearch.test.MixWithIncrement;
1821

1922
import java.util.List;
2023
import java.util.stream.Collectors;
@@ -25,6 +28,7 @@
2528
import static org.hamcrest.Matchers.greaterThan;
2629
import static org.hamcrest.Matchers.lessThan;
2730

31+
@SeedDecorators(MixWithIncrement.class)
2832
public class SampleBooleanAggregatorFunctionTests extends AggregatorFunctionTestCase {
2933
private static final int LIMIT = 50;
3034

@@ -77,6 +81,7 @@ public void testDistribution() {
7781
}
7882
}
7983
}
84+
MixWithIncrement.next();
8085
}
8186

8287
// On average, both boolean values should be sampled 25000x.

x-pack/plugin/esql/compute/src/test/java/org/elasticsearch/compute/aggregation/SampleBytesRefAggregatorFunctionTests.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77

88
package org.elasticsearch.compute.aggregation;
99

10+
import com.carrotsearch.randomizedtesting.annotations.SeedDecorators;
11+
1012
import org.apache.lucene.util.BytesRef;
1113
import org.elasticsearch.compute.data.Block;
1214
import org.elasticsearch.compute.data.BlockFactory;
@@ -16,6 +18,7 @@
1618
import org.elasticsearch.compute.operator.SequenceBytesRefBlockSourceOperator;
1719
import org.elasticsearch.compute.operator.SourceOperator;
1820
import org.elasticsearch.compute.test.CannedSourceOperator;
21+
import org.elasticsearch.test.MixWithIncrement;
1922

2023
import java.util.List;
2124
import java.util.Set;
@@ -28,6 +31,7 @@
2831
import static org.hamcrest.Matchers.hasItems;
2932
import static org.hamcrest.Matchers.lessThan;
3033

34+
@SeedDecorators(MixWithIncrement.class)
3135
public class SampleBytesRefAggregatorFunctionTests extends AggregatorFunctionTestCase {
3236
private static final int LIMIT = 50;
3337

@@ -83,6 +87,7 @@ public void testDistribution() {
8387
sampledCounts[Integer.parseInt(block.getBytesRef(i, scratch).utf8ToString())]++;
8488
}
8589
}
90+
MixWithIncrement.next();
8691
}
8792

8893
// On average, each string should be sampled 500x.

x-pack/plugin/esql/compute/src/test/java/org/elasticsearch/compute/aggregation/SampleDoubleAggregatorFunctionTests.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77

88
package org.elasticsearch.compute.aggregation;
99

10+
import com.carrotsearch.randomizedtesting.annotations.SeedDecorators;
11+
1012
import org.elasticsearch.compute.data.Block;
1113
import org.elasticsearch.compute.data.BlockFactory;
1214
import org.elasticsearch.compute.data.DoubleBlock;
@@ -15,6 +17,7 @@
1517
import org.elasticsearch.compute.operator.SequenceDoubleBlockSourceOperator;
1618
import org.elasticsearch.compute.operator.SourceOperator;
1719
import org.elasticsearch.compute.test.CannedSourceOperator;
20+
import org.elasticsearch.test.MixWithIncrement;
1821

1922
import java.util.List;
2023
import java.util.Set;
@@ -27,6 +30,7 @@
2730
import static org.hamcrest.Matchers.hasItems;
2831
import static org.hamcrest.Matchers.lessThan;
2932

33+
@SeedDecorators(MixWithIncrement.class)
3034
public class SampleDoubleAggregatorFunctionTests extends AggregatorFunctionTestCase {
3135
private static final int LIMIT = 50;
3236

@@ -78,6 +82,7 @@ public void testDistribution() {
7882
sampledCounts[(int) block.getDouble(i)]++;
7983
}
8084
}
85+
MixWithIncrement.next();
8186
}
8287

8388
// On average, each number should be sampled 500x.

0 commit comments

Comments
 (0)