Skip to content

Commit c05fa5d

Browse files
committed
Only use NavigableSet for test uses
Introduce logarithmic random algorithm
1 parent 2e864aa commit c05fa5d

File tree

9 files changed

+77
-42
lines changed

9 files changed

+77
-42
lines changed

server/src/main/java/org/elasticsearch/TransportVersion.java

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,9 @@
1818
import java.io.IOException;
1919
import java.util.Collection;
2020
import java.util.Collections;
21+
import java.util.List;
2122
import java.util.Map;
22-
import java.util.NavigableSet;
2323
import java.util.ServiceLoader;
24-
import java.util.TreeSet;
2524
import java.util.function.Function;
2625
import java.util.stream.Collectors;
2726
import java.util.stream.Stream;
@@ -113,9 +112,9 @@ public static TransportVersion current() {
113112
}
114113

115114
/**
116-
* Sorted set of all defined transport versions
115+
* Sorted list of all defined transport versions
117116
*/
118-
public static NavigableSet<TransportVersion> getAllVersions() {
117+
public static List<TransportVersion> getAllVersions() {
119118
return VersionsHolder.ALL_VERSIONS;
120119
}
121120

@@ -161,7 +160,7 @@ public String toString() {
161160
}
162161

163162
private static class VersionsHolder {
164-
private static final NavigableSet<TransportVersion> ALL_VERSIONS;
163+
private static final List<TransportVersion> ALL_VERSIONS;
165164
private static final Map<Integer, TransportVersion> ALL_VERSIONS_MAP;
166165
private static final TransportVersion CURRENT;
167166

@@ -173,8 +172,7 @@ private static class VersionsHolder {
173172
if (extendedVersions.isEmpty()) {
174173
ALL_VERSIONS = TransportVersions.DEFINED_VERSIONS;
175174
} else {
176-
ALL_VERSIONS = Stream.concat(TransportVersions.DEFINED_VERSIONS.stream(), extendedVersions.stream())
177-
.collect(Collectors.toCollection(TreeSet::new));
175+
ALL_VERSIONS = Stream.concat(TransportVersions.DEFINED_VERSIONS.stream(), extendedVersions.stream()).sorted().toList();
178176
}
179177

180178
ALL_VERSIONS_MAP = ALL_VERSIONS.stream().collect(Collectors.toUnmodifiableMap(TransportVersion::id, Function.identity()));

server/src/main/java/org/elasticsearch/TransportVersions.java

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,11 @@
1313
import org.elasticsearch.core.UpdateForV9;
1414

1515
import java.lang.reflect.Field;
16+
import java.util.ArrayList;
1617
import java.util.Collections;
1718
import java.util.HashMap;
19+
import java.util.List;
1820
import java.util.Map;
19-
import java.util.NavigableSet;
2021
import java.util.Set;
2122
import java.util.TreeSet;
2223
import java.util.function.IntFunction;
@@ -241,7 +242,7 @@ static TransportVersion def(int id) {
241242
/**
242243
* Sorted list of all versions defined in this class
243244
*/
244-
static final NavigableSet<TransportVersion> DEFINED_VERSIONS = collectAllVersionIdsDefinedInClass(TransportVersions.class);
245+
static final List<TransportVersion> DEFINED_VERSIONS = collectAllVersionIdsDefinedInClass(TransportVersions.class);
245246

246247
// the highest transport version constant defined
247248
static final TransportVersion LATEST_DEFINED;
@@ -253,9 +254,9 @@ static TransportVersion def(int id) {
253254
IDS = null;
254255
}
255256

256-
public static NavigableSet<TransportVersion> collectAllVersionIdsDefinedInClass(Class<?> cls) {
257+
public static List<TransportVersion> collectAllVersionIdsDefinedInClass(Class<?> cls) {
257258
Map<Integer, String> versionIdFields = new HashMap<>();
258-
NavigableSet<TransportVersion> definedTransportVersions = new TreeSet<>();
259+
List<TransportVersion> definedTransportVersions = new ArrayList<>();
259260

260261
Set<String> ignore = Set.of("ZERO", "CURRENT", "MINIMUM_COMPATIBLE", "MINIMUM_CCS_VERSION");
261262

@@ -289,7 +290,8 @@ public static NavigableSet<TransportVersion> collectAllVersionIdsDefinedInClass(
289290
}
290291
}
291292

292-
return Collections.unmodifiableNavigableSet(definedTransportVersions);
293+
Collections.sort(definedTransportVersions);
294+
return List.copyOf(definedTransportVersions);
293295
}
294296

295297
static final IntFunction<String> VERSION_LOOKUP = ReleaseVersions.generateVersionsLookup(TransportVersions.class, LATEST_DEFINED.id());

server/src/main/java/org/elasticsearch/Version.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,15 +23,14 @@
2323
import java.io.IOException;
2424
import java.lang.reflect.Field;
2525
import java.lang.reflect.Modifier;
26+
import java.util.ArrayList;
2627
import java.util.Collections;
2728
import java.util.HashMap;
2829
import java.util.List;
2930
import java.util.Locale;
3031
import java.util.Map;
3132
import java.util.NavigableMap;
32-
import java.util.NavigableSet;
3333
import java.util.TreeMap;
34-
import java.util.TreeSet;
3534

3635
public class Version implements VersionId<Version>, ToXContentFragment {
3736
/*
@@ -495,9 +494,9 @@ public int hashCode() {
495494
* The argument would normally be Version.class but is exposed for
496495
* testing with other classes-containing-version-constants.
497496
*/
498-
public static NavigableSet<Version> getDeclaredVersions(final Class<?> versionClass) {
497+
public static List<Version> getDeclaredVersions(final Class<?> versionClass) {
499498
final Field[] fields = versionClass.getFields();
500-
final TreeSet<Version> versions = new TreeSet<>();
499+
final List<Version> versions = new ArrayList<>();
501500
for (final Field field : fields) {
502501
final int mod = field.getModifiers();
503502
if (false == Modifier.isStatic(mod) && Modifier.isFinal(mod) && Modifier.isPublic(mod)) {
@@ -518,6 +517,7 @@ public static NavigableSet<Version> getDeclaredVersions(final Class<?> versionCl
518517
throw new RuntimeException(e);
519518
}
520519
}
520+
Collections.sort(versions);
521521
return versions;
522522
}
523523
}

test/framework/src/main/java/org/elasticsearch/test/BWCVersions.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ public final class BWCVersions {
1818
private BWCVersions() {}
1919

2020
public static NavigableSet<TransportVersion> getAllBWCVersions() {
21-
return TransportVersion.getAllVersions().tailSet(TransportVersions.MINIMUM_COMPATIBLE, true);
21+
return TransportVersionUtils.allReleasedVersions().tailSet(TransportVersions.MINIMUM_COMPATIBLE, true);
2222
}
2323

2424
public static final NavigableSet<TransportVersion> DEFAULT_BWC_VERSIONS = getAllBWCVersions();

test/framework/src/main/java/org/elasticsearch/test/TransportVersionUtils.java

Lines changed: 19 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -13,15 +13,24 @@
1313
import org.elasticsearch.TransportVersions;
1414
import org.elasticsearch.core.Nullable;
1515

16+
import java.util.Collections;
1617
import java.util.NavigableSet;
1718
import java.util.Random;
1819
import java.util.Set;
20+
import java.util.TreeSet;
1921
import java.util.stream.Collectors;
2022

23+
import static org.apache.lucene.tests.util.LuceneTestCase.random;
24+
2125
public class TransportVersionUtils {
26+
27+
private static final NavigableSet<TransportVersion> RELEASED_VERSIONS = Collections.unmodifiableNavigableSet(
28+
new TreeSet<>(TransportVersion.getAllVersions())
29+
);
30+
2231
/** Returns all released versions */
2332
public static NavigableSet<TransportVersion> allReleasedVersions() {
24-
return TransportVersion.getAllVersions();
33+
return RELEASED_VERSIONS;
2534
}
2635

2736
/** Returns the oldest known {@link TransportVersion} */
@@ -31,7 +40,7 @@ public static TransportVersion getFirstVersion() {
3140

3241
/** Returns a random {@link TransportVersion} from all available versions. */
3342
public static TransportVersion randomVersion() {
34-
return ESTestCase.randomFrom(allReleasedVersions());
43+
return VersionUtils.randomFrom(random(), allReleasedVersions(), TransportVersion::fromId);
3544
}
3645

3746
/** Returns a random {@link TransportVersion} from all available versions without the ignore set */
@@ -41,7 +50,7 @@ public static TransportVersion randomVersion(Set<TransportVersion> ignore) {
4150

4251
/** Returns a random {@link TransportVersion} from all available versions. */
4352
public static TransportVersion randomVersion(Random random) {
44-
return ESTestCase.randomFrom(random, allReleasedVersions());
53+
return VersionUtils.randomFrom(random, allReleasedVersions(), TransportVersion::fromId);
4554
}
4655

4756
/** Returns a random {@link TransportVersion} between <code>minVersion</code> and <code>maxVersion</code> (inclusive). */
@@ -68,7 +77,7 @@ public static TransportVersion randomVersionBetween(
6877
versions = versions.headSet(maxVersion, true);
6978
}
7079

71-
return ESTestCase.randomFrom(random, versions);
80+
return VersionUtils.randomFrom(random, versions, TransportVersion::fromId);
7281
}
7382

7483
public static TransportVersion getPreviousVersion() {
@@ -78,28 +87,28 @@ public static TransportVersion getPreviousVersion() {
7887
}
7988

8089
public static TransportVersion getPreviousVersion(TransportVersion version) {
81-
var versions = allReleasedVersions().headSet(version, false);
82-
if (versions.isEmpty()) {
90+
TransportVersion lower = allReleasedVersions().lower(version);
91+
if (lower == null) {
8392
throw new IllegalArgumentException("couldn't find any released versions before [" + version + "]");
8493
}
85-
return versions.getLast();
94+
return lower;
8695
}
8796

8897
public static TransportVersion getNextVersion(TransportVersion version) {
8998
return getNextVersion(version, false);
9099
}
91100

92101
public static TransportVersion getNextVersion(TransportVersion version, boolean createIfNecessary) {
93-
var versions = allReleasedVersions().tailSet(version, false);
94-
if (versions.isEmpty()) {
102+
TransportVersion higher = allReleasedVersions().higher(version);
103+
if (higher == null) {
95104
if (createIfNecessary) {
96105
// create a new transport version one greater than specified
97106
return new TransportVersion(version.id() + 1);
98107
} else {
99108
throw new IllegalArgumentException("couldn't find any released versions after [" + version + "]");
100109
}
101110
}
102-
return versions.getFirst();
111+
return higher;
103112
}
104113

105114
/** Returns a random {@code TransportVersion} that is compatible with {@link TransportVersion#current()} */

test/framework/src/main/java/org/elasticsearch/test/VersionUtils.java

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,18 +9,26 @@
99

1010
package org.elasticsearch.test;
1111

12+
import com.carrotsearch.randomizedtesting.generators.RandomNumbers;
13+
1214
import org.elasticsearch.Build;
1315
import org.elasticsearch.Version;
16+
import org.elasticsearch.common.VersionId;
1417
import org.elasticsearch.core.Nullable;
1518

19+
import java.util.Collections;
1620
import java.util.List;
1721
import java.util.NavigableSet;
1822
import java.util.Random;
23+
import java.util.TreeSet;
24+
import java.util.function.IntFunction;
1925

2026
/** Utilities for selecting versions in tests */
2127
public class VersionUtils {
2228

23-
private static final NavigableSet<Version> ALL_VERSIONS = Version.getDeclaredVersions(Version.class);
29+
private static final NavigableSet<Version> ALL_VERSIONS = Collections.unmodifiableNavigableSet(
30+
new TreeSet<>(Version.getDeclaredVersions(Version.class))
31+
);
2432

2533
/**
2634
* Returns an immutable, sorted list containing all versions, both released and unreleased.
@@ -69,7 +77,7 @@ public static Version getFirstVersion() {
6977

7078
/** Returns a random {@link Version} from all available versions. */
7179
public static Version randomVersion(Random random) {
72-
return ESTestCase.randomFrom(random, ALL_VERSIONS);
80+
return randomFrom(random, ALL_VERSIONS, Version::fromId);
7381
}
7482

7583
/** Returns a random {@link Version} from all available versions, that is compatible with the given version. */
@@ -98,11 +106,24 @@ public static Version randomVersionBetween(Random random, @Nullable Version minV
98106
versions = versions.headSet(maxVersion, true);
99107
}
100108

101-
return ESTestCase.randomFrom(random, versions);
109+
return randomFrom(random, versions, Version::fromId);
102110
}
103111

104112
/** Returns the maximum {@link Version} that is compatible with the given version. */
105113
public static Version maxCompatibleVersion(Version version) {
106-
return ALL_VERSIONS.descendingSet().stream().filter(version::isCompatible).filter(version::onOrBefore).findFirst().orElseThrow();
114+
return ALL_VERSIONS.tailSet(version, true).descendingSet().stream().filter(version::isCompatible).findFirst().orElseThrow();
115+
}
116+
117+
public static <T extends VersionId<T>> T randomFrom(Random random, NavigableSet<T> set, IntFunction<T> ctor) {
118+
// get the first and last id, pick a random id in the middle, then find that id in the set in O(nlogn) time
119+
// this assumes the id numbers are reasonably evenly distributed in the set
120+
assert set.isEmpty() == false;
121+
int lowest = set.getFirst().id();
122+
int highest = set.getLast().id();
123+
124+
T randomId = ctor.apply(RandomNumbers.randomIntBetween(random, lowest, highest));
125+
// try to find the id below, then the id above. We're just looking for *some* item in the set that is close to randomId
126+
T found = set.floor(randomId);
127+
return found != null ? found : set.ceiling(randomId);
107128
}
108129
}

test/framework/src/main/java/org/elasticsearch/test/index/IndexVersionUtils.java

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,15 @@
1414
import org.elasticsearch.index.IndexVersions;
1515
import org.elasticsearch.index.KnownIndexVersions;
1616
import org.elasticsearch.test.ESTestCase;
17+
import org.elasticsearch.test.VersionUtils;
1718

1819
import java.util.NavigableSet;
1920
import java.util.Random;
2021
import java.util.Set;
2122
import java.util.stream.Collectors;
2223

24+
import static org.apache.lucene.tests.util.LuceneTestCase.random;
25+
2326
public class IndexVersionUtils {
2427

2528
private static final NavigableSet<IndexVersion> ALL_VERSIONS = KnownIndexVersions.ALL_VERSIONS;
@@ -42,12 +45,12 @@ public static IndexVersion getLowestWriteCompatibleVersion() {
4245

4346
/** Returns a random {@link IndexVersion} from all available versions. */
4447
public static IndexVersion randomVersion() {
45-
return ESTestCase.randomFrom(ALL_VERSIONS);
48+
return VersionUtils.randomFrom(random(), ALL_VERSIONS, IndexVersion::fromId);
4649
}
4750

4851
/** Returns a random {@link IndexVersion} from all versions that can be written to. */
4952
public static IndexVersion randomWriteVersion() {
50-
return ESTestCase.randomFrom(ALL_WRITE_VERSIONS);
53+
return VersionUtils.randomFrom(random(), ALL_WRITE_VERSIONS, IndexVersion::fromId);
5154
}
5255

5356
/** Returns a random {@link IndexVersion} from all available versions without the ignore set */
@@ -75,7 +78,7 @@ public static IndexVersion randomVersionBetween(Random random, @Nullable IndexVe
7578
versions = versions.headSet(maxVersion, true);
7679
}
7780

78-
return ESTestCase.randomFrom(random, versions);
81+
return VersionUtils.randomFrom(random, versions, IndexVersion::fromId);
7982
}
8083

8184
public static IndexVersion getPreviousVersion() {
@@ -85,23 +88,23 @@ public static IndexVersion getPreviousVersion() {
8588
}
8689

8790
public static IndexVersion getPreviousVersion(IndexVersion version) {
88-
var versions = allReleasedVersions().headSet(version, false);
89-
if (versions.isEmpty()) {
91+
IndexVersion lower = allReleasedVersions().lower(version);
92+
if (lower == null) {
9093
throw new IllegalArgumentException("couldn't find any released versions before [" + version + "]");
9194
}
92-
return versions.getLast();
95+
return lower;
9396
}
9497

9598
public static IndexVersion getPreviousMajorVersion(IndexVersion version) {
9699
return IndexVersion.getMinimumCompatibleIndexVersion(version.id());
97100
}
98101

99102
public static IndexVersion getNextVersion(IndexVersion version) {
100-
var versions = allReleasedVersions().tailSet(version, false);
101-
if (versions.isEmpty()) {
103+
IndexVersion higher = allReleasedVersions().higher(version);
104+
if (higher == null) {
102105
throw new IllegalArgumentException("couldn't find any released versions after [" + version + "]");
103106
}
104-
return versions.getFirst();
107+
return higher;
105108
}
106109

107110
/** Returns a random {@code IndexVersion} that is compatible with {@link IndexVersion#current()} */

x-pack/plugin/eql/src/test/java/org/elasticsearch/xpack/eql/AbstractBWCSerializationTestCase.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
import org.elasticsearch.TransportVersions;
1111
import org.elasticsearch.common.io.stream.Writeable;
1212
import org.elasticsearch.test.AbstractXContentSerializingTestCase;
13+
import org.elasticsearch.test.TransportVersionUtils;
1314
import org.elasticsearch.xcontent.ToXContent;
1415

1516
import java.io.IOException;
@@ -20,7 +21,7 @@
2021
public abstract class AbstractBWCSerializationTestCase<T extends Writeable & ToXContent> extends AbstractXContentSerializingTestCase<T> {
2122

2223
private static NavigableSet<TransportVersion> getAllBWCVersions() {
23-
return TransportVersion.getAllVersions().tailSet(TransportVersions.MINIMUM_COMPATIBLE, true);
24+
return TransportVersionUtils.allReleasedVersions().tailSet(TransportVersions.MINIMUM_COMPATIBLE, true);
2425
}
2526

2627
private static final NavigableSet<TransportVersion> DEFAULT_BWC_VERSIONS = getAllBWCVersions();

x-pack/plugin/eql/src/test/java/org/elasticsearch/xpack/eql/AbstractBWCWireSerializingTestCase.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
import org.elasticsearch.TransportVersions;
1111
import org.elasticsearch.common.io.stream.Writeable;
1212
import org.elasticsearch.test.AbstractWireSerializingTestCase;
13+
import org.elasticsearch.test.TransportVersionUtils;
1314

1415
import java.io.IOException;
1516
import java.util.NavigableSet;
@@ -19,7 +20,7 @@
1920
public abstract class AbstractBWCWireSerializingTestCase<T extends Writeable> extends AbstractWireSerializingTestCase<T> {
2021

2122
private static NavigableSet<TransportVersion> getAllBWCVersions() {
22-
return TransportVersion.getAllVersions().tailSet(TransportVersions.MINIMUM_COMPATIBLE, true);
23+
return TransportVersionUtils.allReleasedVersions().tailSet(TransportVersions.MINIMUM_COMPATIBLE, true);
2324
}
2425

2526
private static final NavigableSet<TransportVersion> DEFAULT_BWC_VERSIONS = getAllBWCVersions();

0 commit comments

Comments
 (0)