You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucene.apache.org by br...@apache.org on 2024/05/27 08:51:28 UTC
(lucene) 01/02: Replace List by IntArrayList and List by LongArrayList. (#13406)
This is an automated email from the ASF dual-hosted git repository.
broustant pushed a commit to branch branch_9x
in repository https://gitbox.apache.org/repos/asf/lucene.git
commit a8def94339110d7f18e0abc026e211e4eebcd46f
Author: Bruno Roustant <33...@users.noreply.github.com>
AuthorDate: Sat May 25 19:53:42 2024 +0200
Replace List<Integer> by IntArrayList and List<Long> by LongArrayList. (#13406)
---
lucene/CHANGES.txt | 2 +
.../lucene/analysis/core/FlattenGraphFilter.java | 16 +-
.../lucene/analysis/hunspell/Dictionary.java | 20 +-
.../lucene/analysis/hunspell/WordStorage.java | 3 +-
.../path/ReversePathHierarchyTokenizer.java | 7 +-
.../apache/lucene/analysis/synonym/SynonymMap.java | 4 +-
.../lucene/analysis/ko/dict/UserDictionary.java | 15 +-
.../lucene/analysis/cn/smart/hhmm/BiSegGraph.java | 8 +-
.../lucene/benchmark/byTask/utils/Config.java | 7 +-
.../lucene/analysis/AutomatonToTokenStream.java | 12 +-
.../Lucene99ScalarQuantizedVectorsWriter.java | 5 +-
.../org/apache/lucene/index/SegmentDocValues.java | 24 +-
.../lucene/index/SegmentDocValuesProducer.java | 5 +-
.../org/apache/lucene/index/SegmentReader.java | 4 +-
.../org/apache/lucene/search/MultiPhraseQuery.java | 16 +-
.../java/org/apache/lucene/search/PhraseQuery.java | 13 +-
.../lucene/util/automaton/CompiledAutomaton.java | 7 +-
.../apache/lucene/util/automaton/UTF32ToUTF8.java | 7 +-
.../java/org/apache/lucene/util/bkd/BKDWriter.java | 3 +-
.../src/java/org/apache/lucene/util/fst/Util.java | 8 +-
.../util/graph/GraphTokenStreamFiniteStrings.java | 9 +-
.../org/apache/lucene/util/hnsw/HnswGraph.java | 9 +-
.../apache/lucene/util/hnsw/OnHeapHnswGraph.java | 9 +-
.../org/apache/lucene/util/hppc/IntArrayList.java | 454 ++++++++++++++++++++
.../org/apache/lucene/util/hppc/LongArrayList.java | 454 ++++++++++++++++++++
.../apache/lucene/util/hppc/TestIntArrayList.java | 466 +++++++++++++++++++++
.../apache/lucene/util/hppc/TestLongArrayList.java | 466 +++++++++++++++++++++
.../facet/range/OverlappingLongRangeCounter.java | 14 +-
.../directory/DirectoryTaxonomyReader.java | 8 +-
.../DiversifyingNearestChildrenKnnCollector.java | 2 +-
.../search/join/PointInSetIncludingScoreQuery.java | 18 +-
.../document/FloatPointNearestNeighbor.java | 5 +-
.../search/LatLonPointPrototypeQueries.java | 3 +-
.../lucene/sandbox/search/NearestNeighbor.java | 3 +-
.../lucene/sandbox/search/QueryProfilerTree.java | 22 +-
lucene/spatial3d/build.gradle | 3 +
lucene/spatial3d/src/java/module-info.java | 2 +
.../lucene/spatial3d/geom/GeoStandardPath.java | 7 +-
.../lucene/spatial3d/geom/StandardObjects.java | 2 +-
39 files changed, 1996 insertions(+), 146 deletions(-)
diff --git a/lucene/CHANGES.txt b/lucene/CHANGES.txt
index 5ceabcd7c59..77def8c32cc 100644
--- a/lucene/CHANGES.txt
+++ b/lucene/CHANGES.txt
@@ -128,6 +128,8 @@ Optimizations
* GITHUB#13400: Replace Set<Integer> by IntHashSet and Set<Long> by LongHashSet. (Bruno Roustant)
+* GITHUB#13406: Replace List<Integer> by IntArrayList and List<Long> by LongArrayList. (Bruno Roustant)
+
Bug Fixes
---------------------
diff --git a/lucene/analysis/common/src/java/org/apache/lucene/analysis/core/FlattenGraphFilter.java b/lucene/analysis/common/src/java/org/apache/lucene/analysis/core/FlattenGraphFilter.java
index 9f3a93e00e2..b72a3aa9a8a 100644
--- a/lucene/analysis/common/src/java/org/apache/lucene/analysis/core/FlattenGraphFilter.java
+++ b/lucene/analysis/common/src/java/org/apache/lucene/analysis/core/FlattenGraphFilter.java
@@ -19,7 +19,6 @@ package org.apache.lucene.analysis.core;
import java.io.IOException;
import java.util.ArrayList;
-import java.util.Collections;
import java.util.List;
import org.apache.lucene.analysis.TokenFilter;
import org.apache.lucene.analysis.TokenStream;
@@ -29,6 +28,8 @@ import org.apache.lucene.analysis.tokenattributes.PositionIncrementAttribute;
import org.apache.lucene.analysis.tokenattributes.PositionLengthAttribute;
import org.apache.lucene.util.AttributeSource;
import org.apache.lucene.util.RollingBuffer;
+import org.apache.lucene.util.hppc.IntArrayList;
+import org.apache.lucene.util.hppc.IntCursor;
/**
* Converts an incoming graph token stream, such as one from {@link SynonymGraphFilter}, into a flat
@@ -90,7 +91,7 @@ public final class FlattenGraphFilter extends TokenFilter {
* "frontier" of nodes we've seen but can't yet output because they are not frozen.
*/
private static final class OutputNode implements RollingBuffer.Resettable {
- private final List<Integer> inputNodes = new ArrayList<>();
+ private final IntArrayList inputNodes = new IntArrayList();
/** Node ID for this output, or -1 if we haven't been assigned yet. */
int node = -1;
@@ -175,8 +176,8 @@ public final class FlattenGraphFilter extends TokenFilter {
}
int maxToNode = -1;
- for (int inputNodeID : output.inputNodes) {
- InputNode inputNode = inputNodes.get(inputNodeID);
+ for (IntCursor inputNodeID : output.inputNodes) {
+ InputNode inputNode = inputNodes.get(inputNodeID.value);
assert inputNode.outputNode == outputFrom;
maxToNode = Math.max(maxToNode, inputNode.maxToNode);
}
@@ -280,7 +281,7 @@ public final class FlattenGraphFilter extends TokenFilter {
Related tests testShingledGap, testShingledGapWithHoles
*/
outputFrom++;
- int freeBefore = Collections.min(output.inputNodes);
+ int freeBefore = output.inputNodes.stream().min().orElseThrow();
// This will catch a node being freed early if it is input to the next output.
// Could a freed early node be input to a later output?
assert outputNodes.get(outputFrom).inputNodes.stream().filter(n -> freeBefore > n).count() == 0
@@ -349,7 +350,7 @@ public final class FlattenGraphFilter extends TokenFilter {
* The last node in the alt path didn't arrive to remove this reference.
*/
assert inputNodes.get(inputFrom).tokens.isEmpty() : "about to remove non empty edge";
- outSrc.inputNodes.remove(Integer.valueOf(inputFrom));
+ outSrc.inputNodes.removeElement(inputFrom);
src.outputNode = -1;
int prevEndOffset = outSrc.endOffset;
@@ -381,8 +382,7 @@ public final class FlattenGraphFilter extends TokenFilter {
if (outputEndNode > dest.outputNode) {
if (dest.outputNode != -1) {
- boolean removed =
- outputNodes.get(dest.outputNode).inputNodes.remove(Integer.valueOf(inputTo));
+ boolean removed = outputNodes.get(dest.outputNode).inputNodes.removeElement(inputTo);
assert removed;
}
// System.out.println(" increase output node: " + dest.outputNode + " vs " +
diff --git a/lucene/analysis/common/src/java/org/apache/lucene/analysis/hunspell/Dictionary.java b/lucene/analysis/common/src/java/org/apache/lucene/analysis/hunspell/Dictionary.java
index 3be870efd36..74594ebdbcb 100644
--- a/lucene/analysis/common/src/java/org/apache/lucene/analysis/hunspell/Dictionary.java
+++ b/lucene/analysis/common/src/java/org/apache/lucene/analysis/hunspell/Dictionary.java
@@ -60,6 +60,8 @@ import org.apache.lucene.util.fst.FST;
import org.apache.lucene.util.fst.FSTCompiler;
import org.apache.lucene.util.fst.IntSequenceOutputs;
import org.apache.lucene.util.fst.Util;
+import org.apache.lucene.util.hppc.IntArrayList;
+import org.apache.lucene.util.hppc.IntCursor;
/** In-memory structure for the dictionary (.dic) and affix (.aff) data of a hunspell dictionary. */
public class Dictionary {
@@ -330,8 +332,8 @@ public class Dictionary {
*/
private void readAffixFile(InputStream affixStream, CharsetDecoder decoder, FlagEnumerator flags)
throws IOException, ParseException {
- TreeMap<String, List<Integer>> prefixes = new TreeMap<>();
- TreeMap<String, List<Integer>> suffixes = new TreeMap<>();
+ TreeMap<String, IntArrayList> prefixes = new TreeMap<>();
+ TreeMap<String, IntArrayList> suffixes = new TreeMap<>();
Set<Character> prefixContFlags = new HashSet<>();
Set<Character> suffixContFlags = new HashSet<>();
Map<String, Integer> seenPatterns = new HashMap<>();
@@ -643,17 +645,17 @@ public class Dictionary {
return new Breaks(starting, ending, middle);
}
- private FST<IntsRef> affixFST(TreeMap<String, List<Integer>> affixes) throws IOException {
+ private FST<IntsRef> affixFST(TreeMap<String, IntArrayList> affixes) throws IOException {
IntSequenceOutputs outputs = IntSequenceOutputs.getSingleton();
FSTCompiler<IntsRef> fstCompiler =
new FSTCompiler.Builder<>(FST.INPUT_TYPE.BYTE4, outputs).build();
IntsRefBuilder scratch = new IntsRefBuilder();
- for (Map.Entry<String, List<Integer>> entry : affixes.entrySet()) {
+ for (Map.Entry<String, IntArrayList> entry : affixes.entrySet()) {
Util.toUTF32(entry.getKey(), scratch);
- List<Integer> entries = entry.getValue();
+ IntArrayList entries = entry.getValue();
IntsRef output = new IntsRef(entries.size());
- for (Integer c : entries) {
- output.ints[output.length++] = c;
+ for (IntCursor c : entries) {
+ output.ints[output.length++] = c.value;
}
fstCompiler.add(scratch.get(), output);
}
@@ -670,7 +672,7 @@ public class Dictionary {
* @throws IOException Can be thrown while reading the rule
*/
private void parseAffix(
- TreeMap<String, List<Integer>> affixes,
+ TreeMap<String, IntArrayList> affixes,
Set<Character> secondStageFlags,
String header,
LineNumberReader reader,
@@ -792,7 +794,7 @@ public class Dictionary {
affixArg = new StringBuilder(affixArg).reverse().toString();
}
- affixes.computeIfAbsent(affixArg, __ -> new ArrayList<>()).add(currentAffix);
+ affixes.computeIfAbsent(affixArg, __ -> new IntArrayList()).add(currentAffix);
currentAffix++;
}
}
diff --git a/lucene/analysis/common/src/java/org/apache/lucene/analysis/hunspell/WordStorage.java b/lucene/analysis/common/src/java/org/apache/lucene/analysis/hunspell/WordStorage.java
index b05ec27a8b4..5bf9585f719 100644
--- a/lucene/analysis/common/src/java/org/apache/lucene/analysis/hunspell/WordStorage.java
+++ b/lucene/analysis/common/src/java/org/apache/lucene/analysis/hunspell/WordStorage.java
@@ -29,6 +29,7 @@ import org.apache.lucene.util.CharsRef;
import org.apache.lucene.util.IntsRef;
import org.apache.lucene.util.IntsRefBuilder;
import org.apache.lucene.util.fst.IntSequenceOutputs;
+import org.apache.lucene.util.hppc.IntArrayList;
/**
* A data structure for memory-efficient word storage and fast lookup/enumeration. Each dictionary
@@ -262,7 +263,7 @@ class WordStorage {
private final IntsRefBuilder currentOrds = new IntsRefBuilder();
private final List<char[]> group = new ArrayList<>();
- private final List<Integer> morphDataIDs = new ArrayList<>();
+ private final IntArrayList morphDataIDs = new IntArrayList();
private String currentEntry = null;
private final int wordCount;
private final double hashFactor;
diff --git a/lucene/analysis/common/src/java/org/apache/lucene/analysis/path/ReversePathHierarchyTokenizer.java b/lucene/analysis/common/src/java/org/apache/lucene/analysis/path/ReversePathHierarchyTokenizer.java
index 7b1f60f51c4..a5a144a561f 100644
--- a/lucene/analysis/common/src/java/org/apache/lucene/analysis/path/ReversePathHierarchyTokenizer.java
+++ b/lucene/analysis/common/src/java/org/apache/lucene/analysis/path/ReversePathHierarchyTokenizer.java
@@ -17,14 +17,13 @@
package org.apache.lucene.analysis.path;
import java.io.IOException;
-import java.util.ArrayList;
-import java.util.List;
import org.apache.lucene.analysis.Tokenizer;
import org.apache.lucene.analysis.tokenattributes.CharTermAttribute;
import org.apache.lucene.analysis.tokenattributes.OffsetAttribute;
import org.apache.lucene.analysis.tokenattributes.PositionIncrementAttribute;
import org.apache.lucene.util.AttributeFactory;
import org.apache.lucene.util.IgnoreRandomChains;
+import org.apache.lucene.util.hppc.IntArrayList;
/**
* Tokenizer for domain-like hierarchies.
@@ -99,7 +98,7 @@ public class ReversePathHierarchyTokenizer extends Tokenizer {
this.skip = skip;
resultToken = new StringBuilder(bufferSize);
resultTokenBuffer = new char[bufferSize];
- delimiterPositions = new ArrayList<>(bufferSize / 10);
+ delimiterPositions = new IntArrayList(bufferSize / 10);
}
private static final int DEFAULT_BUFFER_SIZE = 1024;
@@ -119,7 +118,7 @@ public class ReversePathHierarchyTokenizer extends Tokenizer {
private int skipped = 0;
private StringBuilder resultToken;
- private List<Integer> delimiterPositions;
+ private IntArrayList delimiterPositions;
private int delimitersCount = -1;
private char[] resultTokenBuffer;
diff --git a/lucene/analysis/common/src/java/org/apache/lucene/analysis/synonym/SynonymMap.java b/lucene/analysis/common/src/java/org/apache/lucene/analysis/synonym/SynonymMap.java
index 29ab08e895b..7c23cfd2378 100644
--- a/lucene/analysis/common/src/java/org/apache/lucene/analysis/synonym/SynonymMap.java
+++ b/lucene/analysis/common/src/java/org/apache/lucene/analysis/synonym/SynonymMap.java
@@ -19,7 +19,6 @@ package org.apache.lucene.analysis.synonym;
import java.io.IOException;
import java.io.Reader;
import java.text.ParseException;
-import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Set;
@@ -38,6 +37,7 @@ import org.apache.lucene.util.fst.ByteSequenceOutputs;
import org.apache.lucene.util.fst.FST;
import org.apache.lucene.util.fst.FSTCompiler;
import org.apache.lucene.util.fst.Util;
+import org.apache.lucene.util.hppc.IntArrayList;
import org.apache.lucene.util.hppc.IntHashSet;
/**
@@ -91,7 +91,7 @@ public class SynonymMap {
private static class MapEntry {
boolean includeOrig;
// we could sort for better sharing ultimately, but it could confuse people
- ArrayList<Integer> ords = new ArrayList<>();
+ IntArrayList ords = new IntArrayList();
}
/**
diff --git a/lucene/analysis/nori/src/java/org/apache/lucene/analysis/ko/dict/UserDictionary.java b/lucene/analysis/nori/src/java/org/apache/lucene/analysis/ko/dict/UserDictionary.java
index 64a06cd1abe..5614451df64 100644
--- a/lucene/analysis/nori/src/java/org/apache/lucene/analysis/ko/dict/UserDictionary.java
+++ b/lucene/analysis/nori/src/java/org/apache/lucene/analysis/ko/dict/UserDictionary.java
@@ -88,8 +88,9 @@ public final class UserDictionary implements Dictionary {
String lastToken = null;
List<int[]> segmentations = new ArrayList<>(entries.size());
- List<Short> rightIds = new ArrayList<>(entries.size());
+ short[] rightIds = new short[entries.size()];
long ord = 0;
+ int entryIndex = 0;
for (String entry : entries) {
String[] splits = entry.split("\\s+");
String token = splits[0];
@@ -99,12 +100,12 @@ public final class UserDictionary implements Dictionary {
char lastChar = entry.charAt(entry.length() - 1);
if (charDef.isHangul(lastChar)) {
if (charDef.hasCoda(lastChar)) {
- rightIds.add(RIGHT_ID_T);
+ rightIds[entryIndex++] = RIGHT_ID_T;
} else {
- rightIds.add(RIGHT_ID_F);
+ rightIds[entryIndex++] = RIGHT_ID_F;
}
} else {
- rightIds.add(RIGHT_ID);
+ rightIds[entryIndex++] = RIGHT_ID;
}
if (splits.length == 1) {
@@ -140,10 +141,8 @@ public final class UserDictionary implements Dictionary {
this.fst =
new TokenInfoFST(FST.fromFSTReader(fstCompiler.compile(), fstCompiler.getFSTReader()));
this.segmentations = segmentations.toArray(new int[segmentations.size()][]);
- this.rightIds = new short[rightIds.size()];
- for (int i = 0; i < rightIds.size(); i++) {
- this.rightIds[i] = rightIds.get(i);
- }
+ assert entryIndex == rightIds.length;
+ this.rightIds = rightIds;
}
public TokenInfoFST getFST() {
diff --git a/lucene/analysis/smartcn/src/java/org/apache/lucene/analysis/cn/smart/hhmm/BiSegGraph.java b/lucene/analysis/smartcn/src/java/org/apache/lucene/analysis/cn/smart/hhmm/BiSegGraph.java
index a57f6cfc20d..92cff58002a 100644
--- a/lucene/analysis/smartcn/src/java/org/apache/lucene/analysis/cn/smart/hhmm/BiSegGraph.java
+++ b/lucene/analysis/smartcn/src/java/org/apache/lucene/analysis/cn/smart/hhmm/BiSegGraph.java
@@ -19,6 +19,7 @@ package org.apache.lucene.analysis.cn.smart.hhmm;
import java.util.ArrayList;
import java.util.List;
import org.apache.lucene.analysis.cn.smart.Utility;
+import org.apache.lucene.util.hppc.IntArrayList;
import org.apache.lucene.util.hppc.IntObjectHashMap;
import org.apache.lucene.util.hppc.ObjectCursor;
@@ -197,19 +198,18 @@ class BiSegGraph {
int preNode, lastNode;
lastNode = path.size() - 1;
current = lastNode;
- List<Integer> rpath = new ArrayList<>();
+ IntArrayList rpath = new IntArrayList();
List<SegToken> resultPath = new ArrayList<>();
rpath.add(current);
while (current != 0) {
PathNode currentPathNode = path.get(current);
preNode = currentPathNode.preNode;
- rpath.add(Integer.valueOf(preNode));
+ rpath.add(preNode);
current = preNode;
}
for (int j = rpath.size() - 1; j >= 0; j--) {
- Integer idInteger = rpath.get(j);
- int id = idInteger.intValue();
+ int id = rpath.get(j);
SegToken t = segTokenList.get(id);
resultPath.add(t);
}
diff --git a/lucene/benchmark/src/java/org/apache/lucene/benchmark/byTask/utils/Config.java b/lucene/benchmark/src/java/org/apache/lucene/benchmark/byTask/utils/Config.java
index 8fed1010c9f..36de0c5ffca 100644
--- a/lucene/benchmark/src/java/org/apache/lucene/benchmark/byTask/utils/Config.java
+++ b/lucene/benchmark/src/java/org/apache/lucene/benchmark/byTask/utils/Config.java
@@ -27,6 +27,7 @@ import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.StringTokenizer;
+import org.apache.lucene.util.hppc.IntArrayList;
/**
* Perf run configuration properties.
@@ -338,15 +339,15 @@ public class Config {
return new int[] {Integer.parseInt(s)};
}
- ArrayList<Integer> a = new ArrayList<>();
+ IntArrayList a = new IntArrayList();
StringTokenizer st = new StringTokenizer(s, ":");
while (st.hasMoreTokens()) {
String t = st.nextToken();
- a.add(Integer.valueOf(t));
+ a.add(Integer.parseInt(t));
}
int[] res = new int[a.size()];
for (int i = 0; i < a.size(); i++) {
- res[i] = a.get(i).intValue();
+ res[i] = a.get(i);
}
return res;
}
diff --git a/lucene/core/src/java/org/apache/lucene/analysis/AutomatonToTokenStream.java b/lucene/core/src/java/org/apache/lucene/analysis/AutomatonToTokenStream.java
index 0d73a07e4eb..fa0db8de798 100644
--- a/lucene/core/src/java/org/apache/lucene/analysis/AutomatonToTokenStream.java
+++ b/lucene/core/src/java/org/apache/lucene/analysis/AutomatonToTokenStream.java
@@ -28,6 +28,8 @@ import org.apache.lucene.analysis.tokenattributes.PositionLengthAttribute;
import org.apache.lucene.util.automaton.Automaton;
import org.apache.lucene.util.automaton.Operations;
import org.apache.lucene.util.automaton.Transition;
+import org.apache.lucene.util.hppc.IntArrayList;
+import org.apache.lucene.util.hppc.IntCursor;
import org.apache.lucene.util.hppc.IntIntHashMap;
/** Converts an Automaton into a TokenStream. */
@@ -49,7 +51,7 @@ public class AutomatonToTokenStream {
throw new IllegalArgumentException("Automaton must be finite");
}
- List<List<Integer>> positionNodes = new ArrayList<>();
+ List<IntArrayList> positionNodes = new ArrayList<>();
Transition[][] transitions = automaton.getSortedTransitions();
@@ -77,7 +79,7 @@ public class AutomatonToTokenStream {
}
}
if (positionNodes.size() == currState.pos) {
- List<Integer> posIncs = new ArrayList<>();
+ IntArrayList posIncs = new IntArrayList();
posIncs.add(currState.id);
positionNodes.add(posIncs);
} else {
@@ -93,10 +95,10 @@ public class AutomatonToTokenStream {
}
List<List<EdgeToken>> edgesByLayer = new ArrayList<>();
- for (List<Integer> layer : positionNodes) {
+ for (IntArrayList layer : positionNodes) {
List<EdgeToken> edges = new ArrayList<>();
- for (int state : layer) {
- for (Transition t : transitions[state]) {
+ for (IntCursor state : layer) {
+ for (Transition t : transitions[state.value]) {
// each edge in the token stream can only be on value, though a transition takes a range.
for (int val = t.min; val <= t.max; val++) {
int destLayer = idToPos.get(t.dest);
diff --git a/lucene/core/src/java/org/apache/lucene/codecs/lucene99/Lucene99ScalarQuantizedVectorsWriter.java b/lucene/core/src/java/org/apache/lucene/codecs/lucene99/Lucene99ScalarQuantizedVectorsWriter.java
index 0e2256a6a4a..b584ffff606 100644
--- a/lucene/core/src/java/org/apache/lucene/codecs/lucene99/Lucene99ScalarQuantizedVectorsWriter.java
+++ b/lucene/core/src/java/org/apache/lucene/codecs/lucene99/Lucene99ScalarQuantizedVectorsWriter.java
@@ -59,6 +59,7 @@ import org.apache.lucene.util.VectorUtil;
import org.apache.lucene.util.hnsw.CloseableRandomVectorScorerSupplier;
import org.apache.lucene.util.hnsw.RandomVectorScorer;
import org.apache.lucene.util.hnsw.RandomVectorScorerSupplier;
+import org.apache.lucene.util.hppc.IntArrayList;
import org.apache.lucene.util.quantization.QuantizedByteVectorValues;
import org.apache.lucene.util.quantization.QuantizedVectorsReader;
import org.apache.lucene.util.quantization.ScalarQuantizer;
@@ -540,7 +541,7 @@ public final class Lucene99ScalarQuantizedVectorsWriter extends FlatVectorsWrite
}
static ScalarQuantizer mergeQuantiles(
- List<ScalarQuantizer> quantizationStates, List<Integer> segmentSizes, byte bits) {
+ List<ScalarQuantizer> quantizationStates, IntArrayList segmentSizes, byte bits) {
assert quantizationStates.size() == segmentSizes.size();
if (quantizationStates.isEmpty()) {
return null;
@@ -633,7 +634,7 @@ public final class Lucene99ScalarQuantizedVectorsWriter extends FlatVectorsWrite
throws IOException {
assert fieldInfo.getVectorEncoding().equals(VectorEncoding.FLOAT32);
List<ScalarQuantizer> quantizationStates = new ArrayList<>(mergeState.liveDocs.length);
- List<Integer> segmentSizes = new ArrayList<>(mergeState.liveDocs.length);
+ IntArrayList segmentSizes = new IntArrayList(mergeState.liveDocs.length);
for (int i = 0; i < mergeState.liveDocs.length; i++) {
FloatVectorValues fvv;
if (mergeState.knnVectorsReaders[i] != null
diff --git a/lucene/core/src/java/org/apache/lucene/index/SegmentDocValues.java b/lucene/core/src/java/org/apache/lucene/index/SegmentDocValues.java
index 451123913f5..bf4a9358439 100644
--- a/lucene/core/src/java/org/apache/lucene/index/SegmentDocValues.java
+++ b/lucene/core/src/java/org/apache/lucene/index/SegmentDocValues.java
@@ -17,13 +17,13 @@
package org.apache.lucene.index;
import java.io.IOException;
-import java.util.List;
import org.apache.lucene.codecs.DocValuesFormat;
import org.apache.lucene.codecs.DocValuesProducer;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.IOContext;
-import org.apache.lucene.util.IOUtils;
import org.apache.lucene.util.RefCount;
+import org.apache.lucene.util.hppc.LongArrayList;
+import org.apache.lucene.util.hppc.LongCursor;
import org.apache.lucene.util.hppc.LongObjectHashMap;
/**
@@ -36,12 +36,12 @@ final class SegmentDocValues {
new LongObjectHashMap<>();
private RefCount<DocValuesProducer> newDocValuesProducer(
- SegmentCommitInfo si, Directory dir, final Long gen, FieldInfos infos) throws IOException {
+ SegmentCommitInfo si, Directory dir, final long gen, FieldInfos infos) throws IOException {
Directory dvDir = dir;
String segmentSuffix = "";
- if (gen.longValue() != -1) {
+ if (gen != -1) {
dvDir = si.info.dir; // gen'd files are written outside CFS, so use SegInfo directory
- segmentSuffix = Long.toString(gen.longValue(), Character.MAX_RADIX);
+ segmentSuffix = Long.toString(gen, Character.MAX_RADIX);
}
// set SegmentReadState to list only the fields that are relevant to that gen
@@ -75,13 +75,11 @@ final class SegmentDocValues {
}
/** Decrement the reference count of the given {@link DocValuesProducer} generations. */
- synchronized void decRef(List<Long> dvProducersGens) throws IOException {
- IOUtils.applyToAll(
- dvProducersGens,
- gen -> {
- RefCount<DocValuesProducer> dvp = genDVProducers.get(gen);
- assert dvp != null : "gen=" + gen;
- dvp.decRef();
- });
+ synchronized void decRef(LongArrayList dvProducersGens) throws IOException {
+ for (LongCursor gen : dvProducersGens) {
+ RefCount<DocValuesProducer> dvp = genDVProducers.get(gen.value);
+ assert dvp != null : "gen=" + gen;
+ dvp.decRef();
+ }
}
}
diff --git a/lucene/core/src/java/org/apache/lucene/index/SegmentDocValuesProducer.java b/lucene/core/src/java/org/apache/lucene/index/SegmentDocValuesProducer.java
index 1a1fa6f963b..f0979ddd3e7 100644
--- a/lucene/core/src/java/org/apache/lucene/index/SegmentDocValuesProducer.java
+++ b/lucene/core/src/java/org/apache/lucene/index/SegmentDocValuesProducer.java
@@ -17,15 +17,14 @@
package org.apache.lucene.index;
import java.io.IOException;
-import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.IdentityHashMap;
-import java.util.List;
import java.util.Map;
import java.util.Set;
import org.apache.lucene.codecs.DocValuesProducer;
import org.apache.lucene.store.Directory;
+import org.apache.lucene.util.hppc.LongArrayList;
/** Encapsulates multiple producers when there are docvalues updates as one producer */
// TODO: try to clean up close? no-op?
@@ -36,7 +35,7 @@ class SegmentDocValuesProducer extends DocValuesProducer {
final Map<String, DocValuesProducer> dvProducersByField = new HashMap<>();
final Set<DocValuesProducer> dvProducers =
Collections.newSetFromMap(new IdentityHashMap<DocValuesProducer, Boolean>());
- final List<Long> dvGens = new ArrayList<>();
+ final LongArrayList dvGens = new LongArrayList();
/**
* Creates a new producer that handles updated docvalues fields
diff --git a/lucene/core/src/java/org/apache/lucene/index/SegmentReader.java b/lucene/core/src/java/org/apache/lucene/index/SegmentReader.java
index b6bd266da5e..0bc5feeb6ba 100644
--- a/lucene/core/src/java/org/apache/lucene/index/SegmentReader.java
+++ b/lucene/core/src/java/org/apache/lucene/index/SegmentReader.java
@@ -17,7 +17,6 @@
package org.apache.lucene.index;
import java.io.IOException;
-import java.util.Collections;
import java.util.Objects;
import java.util.Set;
import java.util.concurrent.CopyOnWriteArraySet;
@@ -36,6 +35,7 @@ import org.apache.lucene.store.Directory;
import org.apache.lucene.store.IOContext;
import org.apache.lucene.util.Bits;
import org.apache.lucene.util.IOUtils;
+import org.apache.lucene.util.hppc.LongArrayList;
/**
* IndexReader implementation over a single segment.
@@ -226,7 +226,7 @@ public final class SegmentReader extends CodecReader {
if (docValuesProducer instanceof SegmentDocValuesProducer) {
segDocValues.decRef(((SegmentDocValuesProducer) docValuesProducer).dvGens);
} else if (docValuesProducer != null) {
- segDocValues.decRef(Collections.singletonList(-1L));
+ segDocValues.decRef(LongArrayList.from(-1L));
}
}
}
diff --git a/lucene/core/src/java/org/apache/lucene/search/MultiPhraseQuery.java b/lucene/core/src/java/org/apache/lucene/search/MultiPhraseQuery.java
index 4607487b370..8ad2f5afb18 100644
--- a/lucene/core/src/java/org/apache/lucene/search/MultiPhraseQuery.java
+++ b/lucene/core/src/java/org/apache/lucene/search/MultiPhraseQuery.java
@@ -38,6 +38,7 @@ import org.apache.lucene.search.similarities.Similarity.SimScorer;
import org.apache.lucene.util.ArrayUtil;
import org.apache.lucene.util.BytesRef;
import org.apache.lucene.util.PriorityQueue;
+import org.apache.lucene.util.hppc.IntArrayList;
/**
* A generalized version of {@link PhraseQuery}, with the possibility of adding more than one term
@@ -53,14 +54,14 @@ public class MultiPhraseQuery extends Query {
public static class Builder {
private String field; // becomes non-null on first add() then is unmodified
private final ArrayList<Term[]> termArrays;
- private final ArrayList<Integer> positions;
+ private final IntArrayList positions;
private int slop;
/** Default constructor. */
public Builder() {
this.field = null;
this.termArrays = new ArrayList<>();
- this.positions = new ArrayList<>();
+ this.positions = new IntArrayList();
this.slop = 0;
}
@@ -74,7 +75,7 @@ public class MultiPhraseQuery extends Query {
int length = multiPhraseQuery.termArrays.length;
this.termArrays = new ArrayList<>(length);
- this.positions = new ArrayList<>(length);
+ this.positions = new IntArrayList(length);
for (int i = 0; i < length; ++i) {
this.termArrays.add(multiPhraseQuery.termArrays[i]);
@@ -138,15 +139,8 @@ public class MultiPhraseQuery extends Query {
/** Builds a {@link MultiPhraseQuery}. */
public MultiPhraseQuery build() {
- int[] positionsArray = new int[this.positions.size()];
-
- for (int i = 0; i < this.positions.size(); ++i) {
- positionsArray[i] = this.positions.get(i);
- }
-
Term[][] termArraysArray = termArrays.toArray(new Term[termArrays.size()][]);
-
- return new MultiPhraseQuery(field, termArraysArray, positionsArray, slop);
+ return new MultiPhraseQuery(field, termArraysArray, positions.toArray(), slop);
}
}
diff --git a/lucene/core/src/java/org/apache/lucene/search/PhraseQuery.java b/lucene/core/src/java/org/apache/lucene/search/PhraseQuery.java
index ea9df193413..5c771aba2cf 100644
--- a/lucene/core/src/java/org/apache/lucene/search/PhraseQuery.java
+++ b/lucene/core/src/java/org/apache/lucene/search/PhraseQuery.java
@@ -37,6 +37,7 @@ import org.apache.lucene.search.similarities.Similarity;
import org.apache.lucene.search.similarities.Similarity.SimScorer;
import org.apache.lucene.util.ArrayUtil;
import org.apache.lucene.util.BytesRef;
+import org.apache.lucene.util.hppc.IntArrayList;
/**
* A Query that matches documents containing a particular sequence of terms. A PhraseQuery is built
@@ -73,13 +74,13 @@ public class PhraseQuery extends Query {
private int slop;
private final List<Term> terms;
- private final List<Integer> positions;
+ private final IntArrayList positions;
/** Sole constructor. */
public Builder() {
slop = 0;
terms = new ArrayList<>();
- positions = new ArrayList<>();
+ positions = new IntArrayList();
}
/**
@@ -133,12 +134,8 @@ public class PhraseQuery extends Query {
/** Build a phrase query based on the terms that have been added. */
public PhraseQuery build() {
- Term[] terms = this.terms.toArray(new Term[this.terms.size()]);
- int[] positions = new int[this.positions.size()];
- for (int i = 0; i < positions.length; ++i) {
- positions[i] = this.positions.get(i);
- }
- return new PhraseQuery(slop, terms, positions);
+ Term[] terms = this.terms.toArray(new Term[0]);
+ return new PhraseQuery(slop, terms, positions.toArray());
}
}
diff --git a/lucene/core/src/java/org/apache/lucene/util/automaton/CompiledAutomaton.java b/lucene/core/src/java/org/apache/lucene/util/automaton/CompiledAutomaton.java
index f2ec26d807a..83d937809b1 100644
--- a/lucene/core/src/java/org/apache/lucene/util/automaton/CompiledAutomaton.java
+++ b/lucene/core/src/java/org/apache/lucene/util/automaton/CompiledAutomaton.java
@@ -17,8 +17,6 @@
package org.apache.lucene.util.automaton;
import java.io.IOException;
-import java.util.ArrayList;
-import java.util.List;
import org.apache.lucene.index.SingleTermsEnum;
import org.apache.lucene.index.Term;
import org.apache.lucene.index.Terms;
@@ -32,6 +30,7 @@ import org.apache.lucene.util.IntsRef;
import org.apache.lucene.util.RamUsageEstimator;
import org.apache.lucene.util.StringHelper;
import org.apache.lucene.util.UnicodeUtil;
+import org.apache.lucene.util.hppc.IntArrayList;
/**
* Immutable class holding compiled details for a given Automaton. The Automaton is deterministic,
@@ -394,7 +393,7 @@ public class CompiledAutomaton implements Accountable {
}
}
- final List<Integer> stack = new ArrayList<>();
+ final IntArrayList stack = new IntArrayList();
int idx = 0;
while (true) {
@@ -442,7 +441,7 @@ public class CompiledAutomaton implements Accountable {
// if (DEBUG) System.out.println(" pop ord=" + idx + " return null");
return null;
} else {
- state = stack.remove(stack.size() - 1);
+ state = stack.removeLast();
idx--;
// if (DEBUG) System.out.println(" pop ord=" + (idx+1) + " label=" + (char) label +
// " first trans.min=" + (char) transitions[0].min);
diff --git a/lucene/core/src/java/org/apache/lucene/util/automaton/UTF32ToUTF8.java b/lucene/core/src/java/org/apache/lucene/util/automaton/UTF32ToUTF8.java
index 700847a0a1d..a1734cbad3c 100644
--- a/lucene/core/src/java/org/apache/lucene/util/automaton/UTF32ToUTF8.java
+++ b/lucene/core/src/java/org/apache/lucene/util/automaton/UTF32ToUTF8.java
@@ -16,9 +16,8 @@
*/
package org.apache.lucene.util.automaton;
-import java.util.ArrayList;
import java.util.Arrays;
-import java.util.List;
+import org.apache.lucene.util.hppc.IntArrayList;
// TODO
// - do we really need the .bits...? if not we can make util in UnicodeUtil to convert 1 char
@@ -297,7 +296,7 @@ public final class UTF32ToUTF8 {
int[] map = new int[utf32.getNumStates()];
Arrays.fill(map, -1);
- List<Integer> pending = new ArrayList<>();
+ IntArrayList pending = new IntArrayList();
int utf32State = 0;
pending.add(utf32State);
utf8 = new Automaton.Builder();
@@ -311,7 +310,7 @@ public final class UTF32ToUTF8 {
Transition scratch = new Transition();
while (pending.size() != 0) {
- utf32State = pending.remove(pending.size() - 1);
+ utf32State = pending.removeLast();
utf8State = map[utf32State];
assert utf8State != -1;
diff --git a/lucene/core/src/java/org/apache/lucene/util/bkd/BKDWriter.java b/lucene/core/src/java/org/apache/lucene/util/bkd/BKDWriter.java
index 6463a254c02..a65ba9164b8 100644
--- a/lucene/core/src/java/org/apache/lucene/util/bkd/BKDWriter.java
+++ b/lucene/core/src/java/org/apache/lucene/util/bkd/BKDWriter.java
@@ -45,6 +45,7 @@ import org.apache.lucene.util.IOUtils;
import org.apache.lucene.util.NumericUtils;
import org.apache.lucene.util.PriorityQueue;
import org.apache.lucene.util.bkd.BKDUtil.ByteArrayPredicate;
+import org.apache.lucene.util.hppc.LongArrayList;
// TODO
// - allow variable length byte[] (across docs and dims), but this is quite a bit more hairy
@@ -651,7 +652,7 @@ public class BKDWriter implements Closeable {
final IndexOutput metaOut, indexOut, dataOut;
final long dataStartFP;
- final List<Long> leafBlockFPs = new ArrayList<>();
+ final LongArrayList leafBlockFPs = new LongArrayList();
final List<byte[]> leafBlockStartValues = new ArrayList<>();
final byte[] leafValues = new byte[config.maxPointsInLeafNode * config.packedBytesLength];
final int[] leafDocs = new int[config.maxPointsInLeafNode];
diff --git a/lucene/core/src/java/org/apache/lucene/util/fst/Util.java b/lucene/core/src/java/org/apache/lucene/util/fst/Util.java
index 5800b22028d..4ee07a2feda 100644
--- a/lucene/core/src/java/org/apache/lucene/util/fst/Util.java
+++ b/lucene/core/src/java/org/apache/lucene/util/fst/Util.java
@@ -32,6 +32,8 @@ import org.apache.lucene.util.IntsRef;
import org.apache.lucene.util.IntsRefBuilder;
import org.apache.lucene.util.fst.FST.Arc;
import org.apache.lucene.util.fst.FST.BytesReader;
+import org.apache.lucene.util.hppc.IntArrayList;
+import org.apache.lucene.util.hppc.IntCursor;
/**
* Static helper methods.
@@ -524,7 +526,7 @@ public final class Util {
// System.out.println("toDot: startArc: " + startArc);
// A list of states on the same level (for ranking).
- final List<Integer> sameLevelStates = new ArrayList<>();
+ final IntArrayList sameLevelStates = new IntArrayList();
// A bitset of already seen states (target offset).
final BitSet seen = new BitSet();
@@ -692,8 +694,8 @@ public final class Util {
// Emit state ranking information.
if (sameRank && sameLevelStates.size() > 1) {
out.write(" {rank=same; ");
- for (int state : sameLevelStates) {
- out.write(state + "; ");
+ for (IntCursor state : sameLevelStates) {
+ out.write(state.value + "; ");
}
out.write(" }\n");
}
diff --git a/lucene/core/src/java/org/apache/lucene/util/graph/GraphTokenStreamFiniteStrings.java b/lucene/core/src/java/org/apache/lucene/util/graph/GraphTokenStreamFiniteStrings.java
index 321c6ff133a..f8ad4806da1 100644
--- a/lucene/core/src/java/org/apache/lucene/util/graph/GraphTokenStreamFiniteStrings.java
+++ b/lucene/core/src/java/org/apache/lucene/util/graph/GraphTokenStreamFiniteStrings.java
@@ -23,7 +23,6 @@ import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.BitSet;
-import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import org.apache.lucene.analysis.TokenStream;
@@ -38,6 +37,7 @@ import org.apache.lucene.util.automaton.Automaton;
import org.apache.lucene.util.automaton.FiniteStringsIterator;
import org.apache.lucene.util.automaton.Operations;
import org.apache.lucene.util.automaton.Transition;
+import org.apache.lucene.util.hppc.IntArrayList;
/**
* Consumes a TokenStream and creates an {@link Automaton} where the transition labels are terms
@@ -182,10 +182,9 @@ public final class GraphTokenStreamFiniteStrings {
int[] low = new int[det.getNumStates()];
int[] parent = new int[det.getNumStates()];
Arrays.fill(parent, -1);
- List<Integer> points = new ArrayList<>();
+ IntArrayList points = new IntArrayList();
articulationPointsRecurse(undirect.finish(), 0, 0, depth, low, parent, visited, points);
- Collections.reverse(points);
- return points.stream().mapToInt(p -> p).toArray();
+ return points.reverse().toArray();
}
/** Build an automaton from the provided {@link TokenStream}. */
@@ -261,7 +260,7 @@ public final class GraphTokenStreamFiniteStrings {
int[] low,
int[] parent,
BitSet visited,
- List<Integer> points) {
+ IntArrayList points) {
visited.set(state);
depth[state] = d;
low[state] = d;
diff --git a/lucene/core/src/java/org/apache/lucene/util/hnsw/HnswGraph.java b/lucene/core/src/java/org/apache/lucene/util/hnsw/HnswGraph.java
index ff6695f2c7b..5907a262fe0 100644
--- a/lucene/core/src/java/org/apache/lucene/util/hnsw/HnswGraph.java
+++ b/lucene/core/src/java/org/apache/lucene/util/hnsw/HnswGraph.java
@@ -21,11 +21,12 @@ import static org.apache.lucene.search.DocIdSetIterator.NO_MORE_DOCS;
import java.io.IOException;
import java.util.Arrays;
-import java.util.Collection;
import java.util.Iterator;
import java.util.NoSuchElementException;
import java.util.PrimitiveIterator;
import org.apache.lucene.index.FloatVectorValues;
+import org.apache.lucene.util.hppc.IntArrayList;
+import org.apache.lucene.util.hppc.IntCursor;
/**
* Hierarchical Navigable Small World graph. Provides efficient approximate nearest neighbor search
@@ -220,10 +221,10 @@ public abstract class HnswGraph {
/** Nodes iterator based on set representation of nodes. */
public static class CollectionNodesIterator extends NodesIterator {
- Iterator<Integer> nodes;
+ Iterator<IntCursor> nodes;
/** Constructor for iterator based on collection representing nodes */
- public CollectionNodesIterator(Collection<Integer> nodes) {
+ public CollectionNodesIterator(IntArrayList nodes) {
super(nodes.size());
this.nodes = nodes.iterator();
}
@@ -247,7 +248,7 @@ public abstract class HnswGraph {
if (hasNext() == false) {
throw new NoSuchElementException();
}
- return nodes.next();
+ return nodes.next().value;
}
@Override
diff --git a/lucene/core/src/java/org/apache/lucene/util/hnsw/OnHeapHnswGraph.java b/lucene/core/src/java/org/apache/lucene/util/hnsw/OnHeapHnswGraph.java
index 08c67a2af6d..6368a120fcc 100644
--- a/lucene/core/src/java/org/apache/lucene/util/hnsw/OnHeapHnswGraph.java
+++ b/lucene/core/src/java/org/apache/lucene/util/hnsw/OnHeapHnswGraph.java
@@ -19,13 +19,12 @@ package org.apache.lucene.util.hnsw;
import static org.apache.lucene.search.DocIdSetIterator.NO_MORE_DOCS;
-import java.util.ArrayList;
-import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicReference;
import org.apache.lucene.util.Accountable;
import org.apache.lucene.util.ArrayUtil;
import org.apache.lucene.util.RamUsageEstimator;
+import org.apache.lucene.util.hppc.IntArrayList;
/**
* An {@link HnswGraph} where all nodes and connections are held in memory. This class is used to
@@ -44,7 +43,7 @@ public final class OnHeapHnswGraph extends HnswGraph implements Accountable {
// essentially another 2d map which the first dimension is level and second dimension is node id,
// this is only
// generated on demand when there's someone calling getNodeOnLevel on a non-zero level
- private List<Integer>[] levelToNodes;
+ private IntArrayList[] levelToNodes;
private int
lastFreezeSize; // remember the size we are at last time to freeze the graph and generate
// levelToNodes
@@ -252,9 +251,9 @@ public final class OnHeapHnswGraph extends HnswGraph implements Accountable {
return;
}
int maxLevels = numLevels();
- levelToNodes = new List[maxLevels];
+ levelToNodes = new IntArrayList[maxLevels];
for (int i = 1; i < maxLevels; i++) {
- levelToNodes[i] = new ArrayList<>();
+ levelToNodes[i] = new IntArrayList();
}
int nonNullNode = 0;
for (int node = 0; node < graph.length; node++) {
diff --git a/lucene/core/src/java/org/apache/lucene/util/hppc/IntArrayList.java b/lucene/core/src/java/org/apache/lucene/util/hppc/IntArrayList.java
new file mode 100644
index 00000000000..bc80e36463b
--- /dev/null
+++ b/lucene/core/src/java/org/apache/lucene/util/hppc/IntArrayList.java
@@ -0,0 +1,454 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.lucene.util.hppc;
+
+import static org.apache.lucene.util.hppc.HashContainers.DEFAULT_EXPECTED_ELEMENTS;
+
+import java.util.Arrays;
+import java.util.Iterator;
+import java.util.stream.IntStream;
+import org.apache.lucene.util.Accountable;
+import org.apache.lucene.util.ArrayUtil;
+import org.apache.lucene.util.RamUsageEstimator;
+
+/**
+ * An array-backed list of {@code int}.
+ *
+ * <p>Mostly forked and trimmed from com.carrotsearch.hppc.IntArrayList
+ *
+ * <p>github: https://github.com/carrotsearch/hppc release 0.9.0
+ */
+public class IntArrayList implements Iterable<IntCursor>, Cloneable, Accountable {
+ private static final long BASE_RAM_BYTES_USED =
+ RamUsageEstimator.shallowSizeOfInstance(IntArrayList.class);
+
+ /** An immutable empty buffer (array). */
+ public static final int[] EMPTY_ARRAY = new int[0];
+
+ ;
+
+ /**
+ * Internal array for storing the list. The array may be larger than the current size ({@link
+ * #size()}).
+ */
+ public int[] buffer = EMPTY_ARRAY;
+
+ /** Current number of elements stored in {@link #buffer}. */
+ public int elementsCount;
+
+ /** New instance with sane defaults. */
+ public IntArrayList() {
+ this(DEFAULT_EXPECTED_ELEMENTS);
+ }
+
+ /**
+ * New instance with sane defaults.
+ *
+ * @param expectedElements The expected number of elements guaranteed not to cause buffer
+ * expansion (inclusive).
+ */
+ public IntArrayList(int expectedElements) {
+ buffer = new int[expectedElements];
+ }
+
+ /** Creates a new list from the elements of another list in its iteration order. */
+ public IntArrayList(IntArrayList list) {
+ this(list.size());
+ addAll(list);
+ }
+
+ public void add(int e1) {
+ ensureBufferSpace(1);
+ buffer[elementsCount++] = e1;
+ }
+
+ /** Add all elements from a range of given array to the list. */
+ public void add(int[] elements, int start, int length) {
+ assert length >= 0 : "Length must be >= 0";
+
+ ensureBufferSpace(length);
+ System.arraycopy(elements, start, buffer, elementsCount, length);
+ elementsCount += length;
+ }
+
+ /**
+ * Vararg-signature method for adding elements at the end of the list.
+ *
+ * <p><b>This method is handy, but costly if used in tight loops (anonymous array passing)</b>
+ */
+ /* */
+ public final void add(int... elements) {
+ add(elements, 0, elements.length);
+ }
+
+ /** Adds all elements from another list. */
+ public int addAll(IntArrayList list) {
+ final int size = list.size();
+ ensureBufferSpace(size);
+
+ for (IntCursor cursor : list) {
+ add(cursor.value);
+ }
+
+ return size;
+ }
+
+ /** Adds all elements from another iterable. */
+ public int addAll(Iterable<? extends IntCursor> iterable) {
+ int size = 0;
+ for (IntCursor cursor : iterable) {
+ add(cursor.value);
+ size++;
+ }
+ return size;
+ }
+
+ public void insert(int index, int e1) {
+ assert (index >= 0 && index <= size())
+ : "Index " + index + " out of bounds [" + 0 + ", " + size() + "].";
+
+ ensureBufferSpace(1);
+ System.arraycopy(buffer, index, buffer, index + 1, elementsCount - index);
+ buffer[index] = e1;
+ elementsCount++;
+ }
+
+ public int get(int index) {
+ assert (index >= 0 && index < size())
+ : "Index " + index + " out of bounds [" + 0 + ", " + size() + ").";
+
+ return buffer[index];
+ }
+
+ public int set(int index, int e1) {
+ assert (index >= 0 && index < size())
+ : "Index " + index + " out of bounds [" + 0 + ", " + size() + ").";
+
+ final int v = buffer[index];
+ buffer[index] = e1;
+ return v;
+ }
+
+ /** Removes the element at the specified position in this container and returns it. */
+ public int removeAt(int index) {
+ assert (index >= 0 && index < size())
+ : "Index " + index + " out of bounds [" + 0 + ", " + size() + ").";
+
+ final int v = buffer[index];
+ System.arraycopy(buffer, index + 1, buffer, index, --elementsCount - index);
+ return v;
+ }
+
+ /** Removes and returns the last element of this list. */
+ public int removeLast() {
+ assert !isEmpty() : "List is empty";
+
+ return buffer[--elementsCount];
+ }
+
+ /**
+ * Removes from this list all the elements with indexes between <code>fromIndex</code>, inclusive,
+ * and <code>toIndex</code>, exclusive.
+ */
+ public void removeRange(int fromIndex, int toIndex) {
+ assert (fromIndex >= 0 && fromIndex <= size())
+ : "Index " + fromIndex + " out of bounds [" + 0 + ", " + size() + ").";
+ assert (toIndex >= 0 && toIndex <= size())
+ : "Index " + toIndex + " out of bounds [" + 0 + ", " + size() + "].";
+ assert fromIndex <= toIndex : "fromIndex must be <= toIndex: " + fromIndex + ", " + toIndex;
+
+ System.arraycopy(buffer, toIndex, buffer, fromIndex, elementsCount - toIndex);
+ final int count = toIndex - fromIndex;
+ elementsCount -= count;
+ }
+
+ /**
+ * Removes the first element that equals <code>e</code>, returning whether an element has been
+ * removed.
+ */
+ public boolean removeElement(int e) {
+ return removeFirst(e) != -1;
+ }
+
+ /**
+ * Removes the first element that equals <code>e1</code>, returning its deleted position or <code>
+ * -1</code> if the element was not found.
+ */
+ public int removeFirst(int e1) {
+ final int index = indexOf(e1);
+ if (index >= 0) removeAt(index);
+ return index;
+ }
+
+ /**
+ * Removes the last element that equals <code>e1</code>, returning its deleted position or <code>
+ * -1</code> if the element was not found.
+ */
+ public int removeLast(int e1) {
+ final int index = lastIndexOf(e1);
+ if (index >= 0) removeAt(index);
+ return index;
+ }
+
+ /**
+ * Removes all occurrences of <code>e</code> from this collection.
+ *
+ * @param e Element to be removed from this collection, if present.
+ * @return The number of removed elements as a result of this call.
+ */
+ public int removeAll(int e) {
+ int to = 0;
+ for (int from = 0; from < elementsCount; from++) {
+ if (((e) == (buffer[from]))) {
+ continue;
+ }
+ if (to != from) {
+ buffer[to] = buffer[from];
+ }
+ to++;
+ }
+ final int deleted = elementsCount - to;
+ this.elementsCount = to;
+ return deleted;
+ }
+
+ public boolean contains(int e1) {
+ return indexOf(e1) >= 0;
+ }
+
+ public int indexOf(int e1) {
+ for (int i = 0; i < elementsCount; i++) {
+ if (((e1) == (buffer[i]))) {
+ return i;
+ }
+ }
+
+ return -1;
+ }
+
+ public int lastIndexOf(int e1) {
+ for (int i = elementsCount - 1; i >= 0; i--) {
+ if (((e1) == (buffer[i]))) {
+ return i;
+ }
+ }
+
+ return -1;
+ }
+
+ public boolean isEmpty() {
+ return elementsCount == 0;
+ }
+
+ /**
+ * Ensure this container can hold at least the given number of elements without resizing its
+ * buffers.
+ *
+ * @param expectedElements The total number of elements, inclusive.
+ */
+ public void ensureCapacity(int expectedElements) {
+ final int bufferLen = (buffer == null ? 0 : buffer.length);
+ if (expectedElements > bufferLen) {
+ ensureBufferSpace(expectedElements - size());
+ }
+ }
+
+ /**
+ * Ensures the internal buffer has enough free slots to store <code>expectedAdditions</code>.
+ * Increases internal buffer size if needed.
+ */
+ protected void ensureBufferSpace(int expectedAdditions) {
+ final int bufferLen = (buffer == null ? 0 : buffer.length);
+ if (elementsCount + expectedAdditions > bufferLen) {
+ this.buffer = ArrayUtil.grow(buffer, elementsCount + expectedAdditions);
+ }
+ }
+
+ /**
+ * Truncate or expand the list to the new size. If the list is truncated, the buffer will not be
+ * reallocated (use {@link #trimToSize()} if you need a truncated buffer), but the truncated
+ * values will be reset to the default value (zero). If the list is expanded, the elements beyond
+ * the current size are initialized with JVM-defaults (zero or <code>null</code> values).
+ */
+ public void resize(int newSize) {
+ if (newSize <= buffer.length) {
+ if (newSize < elementsCount) {
+ Arrays.fill(buffer, newSize, elementsCount, 0);
+ } else {
+ Arrays.fill(buffer, elementsCount, newSize, 0);
+ }
+ } else {
+ ensureCapacity(newSize);
+ }
+ this.elementsCount = newSize;
+ }
+
+ public int size() {
+ return elementsCount;
+ }
+
+ /** Trim the internal buffer to the current size. */
+ public void trimToSize() {
+ if (size() != this.buffer.length) {
+ this.buffer = toArray();
+ }
+ }
+
+ /**
+ * Sets the number of stored elements to zero. Releases and initializes the internal storage array
+ * to default values. To clear the list without cleaning the buffer, simply set the {@link
+ * #elementsCount} field to zero.
+ */
+ public void clear() {
+ Arrays.fill(buffer, 0, elementsCount, 0);
+ this.elementsCount = 0;
+ }
+
+ /** Sets the number of stored elements to zero and releases the internal storage array. */
+ public void release() {
+ this.buffer = EMPTY_ARRAY;
+ this.elementsCount = 0;
+ }
+
+ /** The returned array is sized to match exactly the number of elements of the stack. */
+ public int[] toArray() {
+
+ return ArrayUtil.copyOfSubArray(buffer, 0, elementsCount);
+ }
+
+ /**
+ * Clone this object. The returned clone will reuse the same hash function and array resizing
+ * strategy.
+ */
+ @Override
+ public IntArrayList clone() {
+ try {
+ final IntArrayList cloned = (IntArrayList) super.clone();
+ cloned.buffer = buffer.clone();
+ return cloned;
+ } catch (CloneNotSupportedException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ @Override
+ public int hashCode() {
+ int h = 1, max = elementsCount;
+ for (int i = 0; i < max; i++) {
+ h = 31 * h + BitMixer.mix(this.buffer[i]);
+ }
+ return h;
+ }
+
+ /**
+ * Returns <code>true</code> only if the other object is an instance of the same class and with
+ * the same elements.
+ */
+ @Override
+ public boolean equals(Object obj) {
+ return (this == obj)
+ || (obj != null && getClass() == obj.getClass() && equalElements(getClass().cast(obj)));
+ }
+
+ /** Compare index-aligned elements against another {@link IntArrayList}. */
+ protected boolean equalElements(IntArrayList other) {
+ int max = size();
+ if (other.size() != max) {
+ return false;
+ }
+
+ for (int i = 0; i < max; i++) {
+ if (!((get(i)) == (other.get(i)))) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ /** Convert the contents of this list to a human-friendly string. */
+ @Override
+ public String toString() {
+ return Arrays.toString(this.toArray());
+ }
+
+ @Override
+ public long ramBytesUsed() {
+ return BASE_RAM_BYTES_USED + RamUsageEstimator.sizeOf(buffer);
+ }
+
+ /** Returns a stream of all the elements contained in this list. */
+ public IntStream stream() {
+ return Arrays.stream(buffer, 0, size());
+ }
+
+ /** Sorts the elements in this list and returns this list. */
+ public IntArrayList sort() {
+ Arrays.sort(buffer, 0, elementsCount);
+ return this;
+ }
+
+ /** Reverses the elements in this list and returns this list. */
+ public IntArrayList reverse() {
+ for (int i = 0, mid = elementsCount >> 1, j = elementsCount - 1; i < mid; i++, j--) {
+ int tmp = buffer[i];
+ buffer[i] = buffer[j];
+ buffer[j] = tmp;
+ }
+ return this;
+ }
+
+ /** An iterator implementation for {@link IntArrayList#iterator}. */
+ static final class ValueIterator extends AbstractIterator<IntCursor> {
+ private final IntCursor cursor;
+
+ private final int[] buffer;
+ private final int size;
+
+ public ValueIterator(int[] buffer, int size) {
+ this.cursor = new IntCursor();
+ this.cursor.index = -1;
+ this.size = size;
+ this.buffer = buffer;
+ }
+
+ @Override
+ protected IntCursor fetch() {
+ if (cursor.index + 1 == size) return done();
+
+ cursor.value = buffer[++cursor.index];
+ return cursor;
+ }
+ }
+
+ @Override
+ public Iterator<IntCursor> iterator() {
+ return new ValueIterator(buffer, size());
+ }
+
+ /**
+ * Create a list from a variable number of arguments or an array of <code>int</code>. The elements
+ * are copied from the argument to the internal buffer.
+ */
+ /* */
+ public static IntArrayList from(int... elements) {
+ final IntArrayList list = new IntArrayList(elements.length);
+ list.add(elements);
+ return list;
+ }
+}
diff --git a/lucene/core/src/java/org/apache/lucene/util/hppc/LongArrayList.java b/lucene/core/src/java/org/apache/lucene/util/hppc/LongArrayList.java
new file mode 100644
index 00000000000..a3503944bdd
--- /dev/null
+++ b/lucene/core/src/java/org/apache/lucene/util/hppc/LongArrayList.java
@@ -0,0 +1,454 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.lucene.util.hppc;
+
+import static org.apache.lucene.util.hppc.HashContainers.DEFAULT_EXPECTED_ELEMENTS;
+
+import java.util.Arrays;
+import java.util.Iterator;
+import java.util.stream.LongStream;
+import org.apache.lucene.util.Accountable;
+import org.apache.lucene.util.ArrayUtil;
+import org.apache.lucene.util.RamUsageEstimator;
+
+/**
+ * An array-backed list of {@code long}.
+ *
+ * <p>Mostly forked and trimmed from com.carrotsearch.hppc.LongArrayList
+ *
+ * <p>github: https://github.com/carrotsearch/hppc release 0.9.0
+ */
+public class LongArrayList implements Iterable<LongCursor>, Cloneable, Accountable {
+ private static final long BASE_RAM_BYTES_USED =
+ RamUsageEstimator.shallowSizeOfInstance(LongArrayList.class);
+
+ /** An immutable empty buffer (array). */
+ public static final long[] EMPTY_ARRAY = new long[0];
+
+ ;
+
+ /**
+ * Internal array for storing the list. The array may be larger than the current size ({@link
+ * #size()}).
+ */
+ public long[] buffer = EMPTY_ARRAY;
+
+ /** Current number of elements stored in {@link #buffer}. */
+ public int elementsCount;
+
+ /** New instance with sane defaults. */
+ public LongArrayList() {
+ this(DEFAULT_EXPECTED_ELEMENTS);
+ }
+
+ /**
+ * New instance with sane defaults.
+ *
+ * @param expectedElements The expected number of elements guaranteed not to cause buffer
+ * expansion (inclusive).
+ */
+ public LongArrayList(int expectedElements) {
+ buffer = new long[expectedElements];
+ }
+
+ /** Creates a new list from the elements of another list in its iteration order. */
+ public LongArrayList(LongArrayList list) {
+ this(list.size());
+ addAll(list);
+ }
+
+ public void add(long e1) {
+ ensureBufferSpace(1);
+ buffer[elementsCount++] = e1;
+ }
+
+ /** Add all elements from a range of given array to the list. */
+ public void add(long[] elements, int start, int length) {
+ assert length >= 0 : "Length must be >= 0";
+
+ ensureBufferSpace(length);
+ System.arraycopy(elements, start, buffer, elementsCount, length);
+ elementsCount += length;
+ }
+
+ /**
+ * Vararg-signature method for adding elements at the end of the list.
+ *
+ * <p><b>This method is handy, but costly if used in tight loops (anonymous array passing)</b>
+ */
+ /* */
+ public final void add(long... elements) {
+ add(elements, 0, elements.length);
+ }
+
+ /** Adds all elements from another list. */
+ public int addAll(LongArrayList list) {
+ final int size = list.size();
+ ensureBufferSpace(size);
+
+ for (LongCursor cursor : list) {
+ add(cursor.value);
+ }
+
+ return size;
+ }
+
+ /** Adds all elements from another iterable. */
+ public int addAll(Iterable<? extends LongCursor> iterable) {
+ int size = 0;
+ for (LongCursor cursor : iterable) {
+ add(cursor.value);
+ size++;
+ }
+ return size;
+ }
+
+ public void insert(int index, long e1) {
+ assert (index >= 0 && index <= size())
+ : "Index " + index + " out of bounds [" + 0 + ", " + size() + "].";
+
+ ensureBufferSpace(1);
+ System.arraycopy(buffer, index, buffer, index + 1, elementsCount - index);
+ buffer[index] = e1;
+ elementsCount++;
+ }
+
+ public long get(int index) {
+ assert (index >= 0 && index < size())
+ : "Index " + index + " out of bounds [" + 0 + ", " + size() + ").";
+
+ return buffer[index];
+ }
+
+ public long set(int index, long e1) {
+ assert (index >= 0 && index < size())
+ : "Index " + index + " out of bounds [" + 0 + ", " + size() + ").";
+
+ final long v = buffer[index];
+ buffer[index] = e1;
+ return v;
+ }
+
+ /** Removes the element at the specified position in this container and returns it. */
+ public long removeAt(int index) {
+ assert (index >= 0 && index < size())
+ : "Index " + index + " out of bounds [" + 0 + ", " + size() + ").";
+
+ final long v = buffer[index];
+ System.arraycopy(buffer, index + 1, buffer, index, --elementsCount - index);
+ return v;
+ }
+
+ /** Removes and returns the last element of this list. */
+ public long removeLast() {
+ assert !isEmpty() : "List is empty";
+
+ return buffer[--elementsCount];
+ }
+
+ /**
+ * Removes from this list all the elements with indexes between <code>fromIndex</code>, inclusive,
+ * and <code>toIndex</code>, exclusive.
+ */
+ public void removeRange(int fromIndex, int toIndex) {
+ assert (fromIndex >= 0 && fromIndex <= size())
+ : "Index " + fromIndex + " out of bounds [" + 0 + ", " + size() + ").";
+ assert (toIndex >= 0 && toIndex <= size())
+ : "Index " + toIndex + " out of bounds [" + 0 + ", " + size() + "].";
+ assert fromIndex <= toIndex : "fromIndex must be <= toIndex: " + fromIndex + ", " + toIndex;
+
+ System.arraycopy(buffer, toIndex, buffer, fromIndex, elementsCount - toIndex);
+ final int count = toIndex - fromIndex;
+ elementsCount -= count;
+ }
+
+ /**
+ * Removes the first element that equals <code>e</code>, returning whether an element has been
+ * removed.
+ */
+ public boolean removeElement(long e) {
+ return removeFirst(e) != -1;
+ }
+
+ /**
+ * Removes the first element that equals <code>e1</code>, returning its deleted position or <code>
+ * -1</code> if the element was not found.
+ */
+ public int removeFirst(long e1) {
+ final int index = indexOf(e1);
+ if (index >= 0) removeAt(index);
+ return index;
+ }
+
+ /**
+ * Removes the last element that equals <code>e1</code>, returning its deleted position or <code>
+ * -1</code> if the element was not found.
+ */
+ public int removeLast(long e1) {
+ final int index = lastIndexOf(e1);
+ if (index >= 0) removeAt(index);
+ return index;
+ }
+
+ /**
+ * Removes all occurrences of <code>e</code> from this collection.
+ *
+ * @param e Element to be removed from this collection, if present.
+ * @return The number of removed elements as a result of this call.
+ */
+ public int removeAll(long e) {
+ int to = 0;
+ for (int from = 0; from < elementsCount; from++) {
+ if (((e) == (buffer[from]))) {
+ continue;
+ }
+ if (to != from) {
+ buffer[to] = buffer[from];
+ }
+ to++;
+ }
+ final int deleted = elementsCount - to;
+ this.elementsCount = to;
+ return deleted;
+ }
+
+ public boolean contains(long e1) {
+ return indexOf(e1) >= 0;
+ }
+
+ public int indexOf(long e1) {
+ for (int i = 0; i < elementsCount; i++) {
+ if (((e1) == (buffer[i]))) {
+ return i;
+ }
+ }
+
+ return -1;
+ }
+
+ public int lastIndexOf(long e1) {
+ for (int i = elementsCount - 1; i >= 0; i--) {
+ if (((e1) == (buffer[i]))) {
+ return i;
+ }
+ }
+
+ return -1;
+ }
+
+ public boolean isEmpty() {
+ return elementsCount == 0;
+ }
+
+ /**
+ * Ensure this container can hold at least the given number of elements without resizing its
+ * buffers.
+ *
+ * @param expectedElements The total number of elements, inclusive.
+ */
+ public void ensureCapacity(int expectedElements) {
+ final int bufferLen = (buffer == null ? 0 : buffer.length);
+ if (expectedElements > bufferLen) {
+ ensureBufferSpace(expectedElements - size());
+ }
+ }
+
+ /**
+ * Ensures the internal buffer has enough free slots to store <code>expectedAdditions</code>.
+ * Increases internal buffer size if needed.
+ */
+ protected void ensureBufferSpace(int expectedAdditions) {
+ final int bufferLen = (buffer == null ? 0 : buffer.length);
+ if (elementsCount + expectedAdditions > bufferLen) {
+ this.buffer = ArrayUtil.grow(buffer, elementsCount + expectedAdditions);
+ }
+ }
+
+ /**
+ * Truncate or expand the list to the new size. If the list is truncated, the buffer will not be
+ * reallocated (use {@link #trimToSize()} if you need a truncated buffer), but the truncated
+ * values will be reset to the default value (zero). If the list is expanded, the elements beyond
+ * the current size are initialized with JVM-defaults (zero or <code>null</code> values).
+ */
+ public void resize(int newSize) {
+ if (newSize <= buffer.length) {
+ if (newSize < elementsCount) {
+ Arrays.fill(buffer, newSize, elementsCount, 0L);
+ } else {
+ Arrays.fill(buffer, elementsCount, newSize, 0L);
+ }
+ } else {
+ ensureCapacity(newSize);
+ }
+ this.elementsCount = newSize;
+ }
+
+ public int size() {
+ return elementsCount;
+ }
+
+ /** Trim the internal buffer to the current size. */
+ public void trimToSize() {
+ if (size() != this.buffer.length) {
+ this.buffer = toArray();
+ }
+ }
+
+ /**
+ * Sets the number of stored elements to zero. Releases and initializes the internal storage array
+ * to default values. To clear the list without cleaning the buffer, simply set the {@link
+ * #elementsCount} field to zero.
+ */
+ public void clear() {
+ Arrays.fill(buffer, 0, elementsCount, 0);
+ this.elementsCount = 0;
+ }
+
+ /** Sets the number of stored elements to zero and releases the internal storage array. */
+ public void release() {
+ this.buffer = EMPTY_ARRAY;
+ this.elementsCount = 0;
+ }
+
+ /** The returned array is sized to match exactly the number of elements of the stack. */
+ public long[] toArray() {
+
+ return ArrayUtil.copyOfSubArray(buffer, 0, elementsCount);
+ }
+
+ /**
+ * Clone this object. The returned clone will reuse the same hash function and array resizing
+ * strategy.
+ */
+ @Override
+ public LongArrayList clone() {
+ try {
+ final LongArrayList cloned = (LongArrayList) super.clone();
+ cloned.buffer = buffer.clone();
+ return cloned;
+ } catch (CloneNotSupportedException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ @Override
+ public int hashCode() {
+ int h = 1, max = elementsCount;
+ for (int i = 0; i < max; i++) {
+ h = 31 * h + BitMixer.mix(this.buffer[i]);
+ }
+ return h;
+ }
+
+ /**
+ * Returns <code>true</code> only if the other object is an instance of the same class and with
+ * the same elements.
+ */
+ @Override
+ public boolean equals(Object obj) {
+ return (this == obj)
+ || (obj != null && getClass() == obj.getClass() && equalElements(getClass().cast(obj)));
+ }
+
+ /** Compare index-aligned elements against another {@link LongArrayList}. */
+ protected boolean equalElements(LongArrayList other) {
+ int max = size();
+ if (other.size() != max) {
+ return false;
+ }
+
+ for (int i = 0; i < max; i++) {
+ if (!((get(i)) == (other.get(i)))) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ /** Convert the contents of this list to a human-friendly string. */
+ @Override
+ public String toString() {
+ return Arrays.toString(this.toArray());
+ }
+
+ @Override
+ public long ramBytesUsed() {
+ return BASE_RAM_BYTES_USED + RamUsageEstimator.sizeOf(buffer);
+ }
+
+ /** Returns a stream of all the elements contained in this list. */
+ public LongStream stream() {
+ return Arrays.stream(buffer, 0, size());
+ }
+
+ /** Sorts the elements in this list and returns this list. */
+ public LongArrayList sort() {
+ Arrays.sort(buffer, 0, elementsCount);
+ return this;
+ }
+
+ /** Reverses the elements in this list and returns this list. */
+ public LongArrayList reverse() {
+ for (int i = 0, mid = elementsCount >> 1, j = elementsCount - 1; i < mid; i++, j--) {
+ long tmp = buffer[i];
+ buffer[i] = buffer[j];
+ buffer[j] = tmp;
+ }
+ return this;
+ }
+
+ /** An iterator implementation for {@link LongArrayList#iterator}. */
+ static final class ValueIterator extends AbstractIterator<LongCursor> {
+ private final LongCursor cursor;
+
+ private final long[] buffer;
+ private final int size;
+
+ public ValueIterator(long[] buffer, int size) {
+ this.cursor = new LongCursor();
+ this.cursor.index = -1;
+ this.size = size;
+ this.buffer = buffer;
+ }
+
+ @Override
+ protected LongCursor fetch() {
+ if (cursor.index + 1 == size) return done();
+
+ cursor.value = buffer[++cursor.index];
+ return cursor;
+ }
+ }
+
+ @Override
+ public Iterator<LongCursor> iterator() {
+ return new ValueIterator(buffer, size());
+ }
+
+ /**
+ * Create a list from a variable number of arguments or an array of <code>int</code>. The elements
+ * are copied from the argument to the internal buffer.
+ */
+ /* */
+ public static LongArrayList from(long... elements) {
+ final LongArrayList list = new LongArrayList(elements.length);
+ list.add(elements);
+ return list;
+ }
+}
diff --git a/lucene/core/src/test/org/apache/lucene/util/hppc/TestIntArrayList.java b/lucene/core/src/test/org/apache/lucene/util/hppc/TestIntArrayList.java
new file mode 100644
index 00000000000..dd1371aea77
--- /dev/null
+++ b/lucene/core/src/test/org/apache/lucene/util/hppc/TestIntArrayList.java
@@ -0,0 +1,466 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.lucene.util.hppc;
+
+import java.util.Arrays;
+import java.util.Iterator;
+import java.util.NoSuchElementException;
+import org.apache.lucene.tests.util.LuceneTestCase;
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * Tests for {@link IntArrayList}.
+ *
+ * <p>Mostly forked and trimmed from com.carrotsearch.hppc.IntArrayListTest
+ *
+ * <p>github: https://github.com/carrotsearch/hppc release: 0.9.0
+ */
+public class TestIntArrayList extends LuceneTestCase {
+ private final int key0 = cast(0);
+ private final int key1 = cast(1);
+ private final int key2 = cast(2);
+ private final int key3 = cast(3);
+ private final int key4 = cast(4);
+ private final int key5 = cast(5);
+ private final int key6 = cast(6);
+ private final int key7 = cast(7);
+
+ /** Convert to target type from an integer used to test stuff. */
+ private int cast(int v) {
+ return v;
+ }
+
+ /** Per-test fresh initialized instance. */
+ private IntArrayList list;
+
+ @Before
+ public void initialize() {
+ list = new IntArrayList();
+ }
+
+ @Test
+ public void testInitiallyEmpty() {
+ assertEquals(0, list.size());
+ }
+
+ @Test
+ public void testAdd() {
+ list.add(key1, key2);
+ assertListEquals(list.toArray(), 1, 2);
+ }
+
+ @Test
+ public void testAddTwoArgs() {
+ list.add(key1, key2);
+ list.add(key3, key4);
+ assertListEquals(list.toArray(), 1, 2, 3, 4);
+ }
+
+ @Test
+ public void testAddArray() {
+ list.add(asArray(0, 1, 2, 3), 1, 2);
+ assertListEquals(list.toArray(), 1, 2);
+ }
+
+ @Test
+ public void testAddVarArg() {
+ list.add(asArray(0, 1, 2, 3));
+ list.add(key4, key5, key6, key7);
+ assertListEquals(list.toArray(), 0, 1, 2, 3, 4, 5, 6, 7);
+ }
+
+ @Test
+ public void testAddAll() {
+ IntArrayList list2 = new IntArrayList();
+ list2.add(asArray(0, 1, 2));
+
+ list.addAll(list2);
+ list.addAll(list2);
+
+ assertListEquals(list.toArray(), 0, 1, 2, 0, 1, 2);
+ }
+
+ @Test
+ public void testInsert() {
+ list.insert(0, key1);
+ list.insert(0, key2);
+ list.insert(2, key3);
+ list.insert(1, key4);
+
+ assertListEquals(list.toArray(), 2, 4, 1, 3);
+ }
+
+ @Test
+ public void testSet() {
+ list.add(asArray(0, 1, 2));
+
+ assertEquals(0, list.set(0, key3));
+ assertEquals(1, list.set(1, key4));
+ assertEquals(2, list.set(2, key5));
+
+ assertListEquals(list.toArray(), 3, 4, 5);
+ }
+
+ @Test
+ public void testRemoveAt() {
+ list.add(asArray(0, 1, 2, 3, 4));
+
+ list.removeAt(0);
+ list.removeAt(2);
+ list.removeAt(1);
+
+ assertListEquals(list.toArray(), 1, 4);
+ }
+
+ @Test
+ public void testRemoveLast() {
+ list.add(asArray(0, 1, 2, 3, 4));
+
+ assertEquals(4, list.removeLast());
+ assertEquals(4, list.size());
+ assertListEquals(list.toArray(), 0, 1, 2, 3);
+ assertEquals(3, list.removeLast());
+ assertEquals(3, list.size());
+ assertListEquals(list.toArray(), 0, 1, 2);
+ assertEquals(2, list.removeLast());
+ assertEquals(1, list.removeLast());
+ assertEquals(0, list.removeLast());
+ assertTrue(list.isEmpty());
+ }
+
+ @Test
+ public void testRemoveElement() {
+ list.add(asArray(0, 1, 2, 3, 3, 4));
+
+ assertTrue(list.removeElement(3));
+ assertTrue(list.removeElement(2));
+ assertFalse(list.removeElement(5));
+
+ assertListEquals(list.toArray(), 0, 1, 3, 4);
+ }
+
+ @Test
+ public void testRemoveRange() {
+ list.add(asArray(0, 1, 2, 3, 4));
+
+ list.removeRange(0, 2);
+ assertListEquals(list.toArray(), 2, 3, 4);
+
+ list.removeRange(2, 3);
+ assertListEquals(list.toArray(), 2, 3);
+
+ list.removeRange(1, 1);
+ assertListEquals(list.toArray(), 2, 3);
+
+ list.removeRange(0, 1);
+ assertListEquals(list.toArray(), 3);
+ }
+
+ @Test
+ public void testRemoveFirstLast() {
+ list.add(asArray(0, 1, 2, 1, 0));
+
+ assertEquals(-1, list.removeFirst(key5));
+ assertEquals(-1, list.removeLast(key5));
+ assertListEquals(list.toArray(), 0, 1, 2, 1, 0);
+
+ assertEquals(1, list.removeFirst(key1));
+ assertListEquals(list.toArray(), 0, 2, 1, 0);
+ assertEquals(3, list.removeLast(key0));
+ assertListEquals(list.toArray(), 0, 2, 1);
+ assertEquals(0, list.removeLast(key0));
+ assertListEquals(list.toArray(), 2, 1);
+ assertEquals(-1, list.removeLast(key0));
+ }
+
+ @Test
+ public void testRemoveAll() {
+ list.add(asArray(0, 1, 0, 1, 0));
+
+ assertEquals(0, list.removeAll(key2));
+ assertEquals(3, list.removeAll(key0));
+ assertListEquals(list.toArray(), 1, 1);
+
+ assertEquals(2, list.removeAll(key1));
+ assertTrue(list.isEmpty());
+ }
+
+ @Test
+ public void testIndexOf() {
+ list.add(asArray(0, 1, 2, 1, 0));
+
+ assertEquals(0, list.indexOf(key0));
+ assertEquals(-1, list.indexOf(key3));
+ assertEquals(2, list.indexOf(key2));
+ }
+
+ @Test
+ public void testLastIndexOf() {
+ list.add(asArray(0, 1, 2, 1, 0));
+
+ assertEquals(4, list.lastIndexOf(key0));
+ assertEquals(-1, list.lastIndexOf(key3));
+ assertEquals(2, list.lastIndexOf(key2));
+ }
+
+ @Test
+ public void testEnsureCapacity() {
+ IntArrayList list = new IntArrayList(0);
+ assertEquals(list.size(), list.buffer.length);
+ int[] buffer1 = list.buffer;
+ list.ensureCapacity(100);
+ assertNotSame(buffer1, list.buffer);
+ }
+
+ @Test
+ public void testResizeAndCleanBuffer() {
+ list.ensureCapacity(20);
+ Arrays.fill(list.buffer, key1);
+
+ list.resize(10);
+ assertEquals(10, list.size());
+ for (int i = 0; i < list.size(); i++) {
+ assertEquals(0, list.get(i));
+ }
+
+ Arrays.fill(list.buffer, 0);
+ for (int i = 5; i < list.size(); i++) {
+ list.set(i, key1);
+ }
+ list.resize(5);
+ assertEquals(5, list.size());
+ for (int i = list.size(); i < list.buffer.length; i++) {
+ assertEquals(0, list.buffer[i]);
+ }
+ }
+
+ @Test
+ public void testTrimToSize() {
+ list.add(asArray(1, 2));
+ list.trimToSize();
+ assertEquals(2, list.buffer.length);
+ }
+
+ @Test
+ public void testRelease() {
+ list.add(asArray(1, 2));
+ list.release();
+ assertEquals(0, list.size());
+ list.add(asArray(1, 2));
+ assertEquals(2, list.size());
+ }
+
+ @Test
+ public void testIterable() {
+ list.add(asArray(0, 1, 2, 3));
+ int count = 0;
+ for (IntCursor cursor : list) {
+ count++;
+ assertEquals(list.get(cursor.index), cursor.value);
+ assertEquals(list.buffer[cursor.index], cursor.value);
+ }
+ assertEquals(count, list.size());
+
+ count = 0;
+ list.resize(0);
+ for (@SuppressWarnings("unused") IntCursor cursor : list) {
+ count++;
+ }
+ assertEquals(0, count);
+ }
+
+ @Test
+ public void testIterator() {
+ list.add(asArray(0, 1, 2, 3));
+ Iterator<IntCursor> iterator = list.iterator();
+ int count = 0;
+ while (iterator.hasNext()) {
+ iterator.hasNext();
+ iterator.hasNext();
+ iterator.hasNext();
+ iterator.next();
+ count++;
+ }
+ assertEquals(count, list.size());
+
+ list.resize(0);
+ assertFalse(list.iterator().hasNext());
+ }
+
+ @Test
+ public void testClear() {
+ list.add(asArray(1, 2, 3));
+ list.clear();
+ assertTrue(list.isEmpty());
+ assertEquals(-1, list.indexOf(cast(1)));
+ }
+
+ @Test
+ public void testFrom() {
+ list = IntArrayList.from(key1, key2, key3);
+ assertEquals(3, list.size());
+ assertListEquals(list.toArray(), 1, 2, 3);
+ assertEquals(list.size(), list.buffer.length);
+ }
+
+ @Test
+ public void testCopyList() {
+ list.add(asArray(1, 2, 3));
+ IntArrayList copy = new IntArrayList(list);
+ assertEquals(3, copy.size());
+ assertListEquals(copy.toArray(), 1, 2, 3);
+ assertEquals(copy.size(), copy.buffer.length);
+ }
+
+ @Test
+ public void testHashCodeEquals() {
+ IntArrayList l0 = IntArrayList.from();
+ assertEquals(1, l0.hashCode());
+ assertEquals(l0, IntArrayList.from());
+
+ IntArrayList l1 = IntArrayList.from(key1, key2, key3);
+ IntArrayList l2 = IntArrayList.from(key1, key2);
+ l2.add(key3);
+
+ assertEquals(l1.hashCode(), l2.hashCode());
+ assertEquals(l1, l2);
+ }
+
+ @Test
+ public void testEqualElements() {
+ IntArrayList l1 = IntArrayList.from(key1, key2, key3);
+ IntArrayList l2 = IntArrayList.from(key1, key2);
+ l2.add(key3);
+
+ assertEquals(l1.hashCode(), l2.hashCode());
+ assertTrue(l2.equalElements(l1));
+ }
+
+ @Test
+ public void testToArray() {
+ IntArrayList l1 = IntArrayList.from(key1, key2, key3);
+ l1.ensureCapacity(100);
+ int[] result = l1.toArray();
+ assertArrayEquals(new int[] {key1, key2, key3}, result);
+ }
+
+ @Test
+ public void testClone() {
+ list.add(key1, key2, key3);
+
+ IntArrayList cloned = list.clone();
+ cloned.removeAt(cloned.indexOf(key1));
+
+ assertSortedListEquals(list.toArray(), key1, key2, key3);
+ assertSortedListEquals(cloned.toArray(), key2, key3);
+ }
+
+ @Test
+ public void testToString() {
+ assertEquals(
+ "[" + key1 + ", " + key2 + ", " + key3 + "]",
+ IntArrayList.from(key1, key2, key3).toString());
+ }
+
+ @Test
+ public void testEqualsSameClass() {
+ IntArrayList l1 = IntArrayList.from(key1, key2, key3);
+ IntArrayList l2 = IntArrayList.from(key1, key2, key3);
+ IntArrayList l3 = IntArrayList.from(key1, key3, key2);
+
+ assertEquals(l1, l2);
+ assertEquals(l1.hashCode(), l2.hashCode());
+ assertNotEquals(l1, l3);
+ }
+
+ @Test
+ public void testEqualsSubClass() {
+ class Sub extends IntArrayList {}
+ ;
+
+ IntArrayList l1 = IntArrayList.from(key1, key2, key3);
+ IntArrayList l2 = new Sub();
+ IntArrayList l3 = new Sub();
+ l2.addAll(l1);
+ l3.addAll(l1);
+
+ assertEquals(l2, l3);
+ assertNotEquals(l1, l3);
+ }
+
+ @Test
+ public void testStream() {
+ assertEquals(key1, IntArrayList.from(key1, key2, key3).stream().min().orElseThrow());
+ assertEquals(key3, IntArrayList.from(key2, key1, key3).stream().max().orElseThrow());
+ assertEquals(0, IntArrayList.from(key1, key2, -key3).stream().sum());
+ expectThrows(
+ NoSuchElementException.class,
+ () -> {
+ IntArrayList.from().stream().min().orElseThrow();
+ });
+ }
+
+ @Test
+ public void testSort() {
+ list.add(key1, key3, key2);
+
+ IntArrayList list2 = new IntArrayList();
+ list2.ensureCapacity(100);
+ list2.addAll(list);
+ assertSame(list2, list2.sort());
+ assertEquals(IntArrayList.from(list.stream().sorted().toArray()), list2);
+ }
+
+ @Test
+ public void testReverse() {
+ for (int i = 0; i < 10; i++) {
+ int[] elements = new int[i];
+ for (int j = 0; j < i; j++) {
+ elements[j] = cast(j);
+ }
+ IntArrayList list = new IntArrayList();
+ list.ensureCapacity(30);
+ list.add(elements);
+ assertSame(list, list.reverse());
+ assertEquals(elements.length, list.size());
+ int reverseIndex = elements.length - 1;
+ for (IntCursor cursor : list) {
+ assertEquals(elements[reverseIndex--], cursor.value);
+ }
+ }
+ }
+
+ /** Check if the array's content is identical to a given sequence of elements. */
+ private static void assertListEquals(int[] array, int... elements) {
+ assertEquals(elements.length, array.length);
+ assertArrayEquals(elements, array);
+ }
+
+ private static int[] asArray(int... elements) {
+ return elements;
+ }
+
+ /** Check if the array's content is identical to a given sequence of elements. */
+ private static void assertSortedListEquals(int[] array, int... elements) {
+ assertEquals(elements.length, array.length);
+ Arrays.sort(array);
+ Arrays.sort(elements);
+ assertArrayEquals(elements, array);
+ }
+}
diff --git a/lucene/core/src/test/org/apache/lucene/util/hppc/TestLongArrayList.java b/lucene/core/src/test/org/apache/lucene/util/hppc/TestLongArrayList.java
new file mode 100644
index 00000000000..0f53a9f3749
--- /dev/null
+++ b/lucene/core/src/test/org/apache/lucene/util/hppc/TestLongArrayList.java
@@ -0,0 +1,466 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.lucene.util.hppc;
+
+import java.util.Arrays;
+import java.util.Iterator;
+import java.util.NoSuchElementException;
+import org.apache.lucene.tests.util.LuceneTestCase;
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * Tests for {@link LongArrayList}.
+ *
+ * <p>Mostly forked and trimmed from com.carrotsearch.hppc.LongArrayListTest
+ *
+ * <p>github: https://github.com/carrotsearch/hppc release: 0.9.0
+ */
+public class TestLongArrayList extends LuceneTestCase {
+ private final long key0 = cast(0);
+ private final long key1 = cast(1);
+ private final long key2 = cast(2);
+ private final long key3 = cast(3);
+ private final long key4 = cast(4);
+ private final long key5 = cast(5);
+ private final long key6 = cast(6);
+ private final long key7 = cast(7);
+
+ /** Convert to target type from an integer used to test stuff. */
+ private long cast(int v) {
+ return v;
+ }
+
+ /** Per-test fresh initialized instance. */
+ private LongArrayList list;
+
+ @Before
+ public void initialize() {
+ list = new LongArrayList();
+ }
+
+ @Test
+ public void testInitiallyEmpty() {
+ assertEquals(0, list.size());
+ }
+
+ @Test
+ public void testAdd() {
+ list.add(key1, key2);
+ assertListEquals(list.toArray(), 1, 2);
+ }
+
+ @Test
+ public void testAddTwoArgs() {
+ list.add(key1, key2);
+ list.add(key3, key4);
+ assertListEquals(list.toArray(), 1, 2, 3, 4);
+ }
+
+ @Test
+ public void testAddArray() {
+ list.add(asArray(0, 1, 2, 3), 1, 2);
+ assertListEquals(list.toArray(), 1, 2);
+ }
+
+ @Test
+ public void testAddVarArg() {
+ list.add(asArray(0, 1, 2, 3));
+ list.add(key4, key5, key6, key7);
+ assertListEquals(list.toArray(), 0, 1, 2, 3, 4, 5, 6, 7);
+ }
+
+ @Test
+ public void testAddAll() {
+ LongArrayList list2 = new LongArrayList();
+ list2.add(asArray(0, 1, 2));
+
+ list.addAll(list2);
+ list.addAll(list2);
+
+ assertListEquals(list.toArray(), 0, 1, 2, 0, 1, 2);
+ }
+
+ @Test
+ public void testInsert() {
+ list.insert(0, key1);
+ list.insert(0, key2);
+ list.insert(2, key3);
+ list.insert(1, key4);
+
+ assertListEquals(list.toArray(), 2, 4, 1, 3);
+ }
+
+ @Test
+ public void testSet() {
+ list.add(asArray(0, 1, 2));
+
+ assertEquals(0, list.set(0, key3));
+ assertEquals(1, list.set(1, key4));
+ assertEquals(2, list.set(2, key5));
+
+ assertListEquals(list.toArray(), 3, 4, 5);
+ }
+
+ @Test
+ public void testRemoveAt() {
+ list.add(asArray(0, 1, 2, 3, 4));
+
+ list.removeAt(0);
+ list.removeAt(2);
+ list.removeAt(1);
+
+ assertListEquals(list.toArray(), 1, 4);
+ }
+
+ @Test
+ public void testRemoveLast() {
+ list.add(asArray(0, 1, 2, 3, 4));
+
+ assertEquals(4, list.removeLast());
+ assertEquals(4, list.size());
+ assertListEquals(list.toArray(), 0, 1, 2, 3);
+ assertEquals(3, list.removeLast());
+ assertEquals(3, list.size());
+ assertListEquals(list.toArray(), 0, 1, 2);
+ assertEquals(2, list.removeLast());
+ assertEquals(1, list.removeLast());
+ assertEquals(0, list.removeLast());
+ assertTrue(list.isEmpty());
+ }
+
+ @Test
+ public void testRemoveElement() {
+ list.add(asArray(0, 1, 2, 3, 3, 4));
+
+ assertTrue(list.removeElement(3));
+ assertTrue(list.removeElement(2));
+ assertFalse(list.removeElement(5));
+
+ assertListEquals(list.toArray(), 0, 1, 3, 4);
+ }
+
+ @Test
+ public void testRemoveRange() {
+ list.add(asArray(0, 1, 2, 3, 4));
+
+ list.removeRange(0, 2);
+ assertListEquals(list.toArray(), 2, 3, 4);
+
+ list.removeRange(2, 3);
+ assertListEquals(list.toArray(), 2, 3);
+
+ list.removeRange(1, 1);
+ assertListEquals(list.toArray(), 2, 3);
+
+ list.removeRange(0, 1);
+ assertListEquals(list.toArray(), 3);
+ }
+
+ @Test
+ public void testRemoveFirstLast() {
+ list.add(asArray(0, 1, 2, 1, 0));
+
+ assertEquals(-1, list.removeFirst(key5));
+ assertEquals(-1, list.removeLast(key5));
+ assertListEquals(list.toArray(), 0, 1, 2, 1, 0);
+
+ assertEquals(1, list.removeFirst(key1));
+ assertListEquals(list.toArray(), 0, 2, 1, 0);
+ assertEquals(3, list.removeLast(key0));
+ assertListEquals(list.toArray(), 0, 2, 1);
+ assertEquals(0, list.removeLast(key0));
+ assertListEquals(list.toArray(), 2, 1);
+ assertEquals(-1, list.removeLast(key0));
+ }
+
+ @Test
+ public void testRemoveAll() {
+ list.add(asArray(0, 1, 0, 1, 0));
+
+ assertEquals(0, list.removeAll(key2));
+ assertEquals(3, list.removeAll(key0));
+ assertListEquals(list.toArray(), 1, 1);
+
+ assertEquals(2, list.removeAll(key1));
+ assertTrue(list.isEmpty());
+ }
+
+ @Test
+ public void testIndexOf() {
+ list.add(asArray(0, 1, 2, 1, 0));
+
+ assertEquals(0, list.indexOf(key0));
+ assertEquals(-1, list.indexOf(key3));
+ assertEquals(2, list.indexOf(key2));
+ }
+
+ @Test
+ public void testLastIndexOf() {
+ list.add(asArray(0, 1, 2, 1, 0));
+
+ assertEquals(4, list.lastIndexOf(key0));
+ assertEquals(-1, list.lastIndexOf(key3));
+ assertEquals(2, list.lastIndexOf(key2));
+ }
+
+ @Test
+ public void testEnsureCapacity() {
+ LongArrayList list = new LongArrayList(0);
+ assertEquals(list.size(), list.buffer.length);
+ long[] buffer1 = list.buffer;
+ list.ensureCapacity(100);
+ assertNotSame(buffer1, list.buffer);
+ }
+
+ @Test
+ public void testResizeAndCleanBuffer() {
+ list.ensureCapacity(20);
+ Arrays.fill(list.buffer, key1);
+
+ list.resize(10);
+ assertEquals(10, list.size());
+ for (int i = 0; i < list.size(); i++) {
+ assertEquals(0, list.get(i));
+ }
+
+ Arrays.fill(list.buffer, 0);
+ for (int i = 5; i < list.size(); i++) {
+ list.set(i, key1);
+ }
+ list.resize(5);
+ assertEquals(5, list.size());
+ for (int i = list.size(); i < list.buffer.length; i++) {
+ assertEquals(0, list.buffer[i]);
+ }
+ }
+
+ @Test
+ public void testTrimToSize() {
+ list.add(asArray(1, 2));
+ list.trimToSize();
+ assertEquals(2, list.buffer.length);
+ }
+
+ @Test
+ public void testRelease() {
+ list.add(asArray(1, 2));
+ list.release();
+ assertEquals(0, list.size());
+ list.add(asArray(1, 2));
+ assertEquals(2, list.size());
+ }
+
+ @Test
+ public void testIterable() {
+ list.add(asArray(0, 1, 2, 3));
+ int count = 0;
+ for (LongCursor cursor : list) {
+ count++;
+ assertEquals(list.get(cursor.index), cursor.value);
+ assertEquals(list.buffer[cursor.index], cursor.value);
+ }
+ assertEquals(count, list.size());
+
+ count = 0;
+ list.resize(0);
+ for (@SuppressWarnings("unused") LongCursor cursor : list) {
+ count++;
+ }
+ assertEquals(0, count);
+ }
+
+ @Test
+ public void testIterator() {
+ list.add(asArray(0, 1, 2, 3));
+ Iterator<LongCursor> iterator = list.iterator();
+ int count = 0;
+ while (iterator.hasNext()) {
+ iterator.hasNext();
+ iterator.hasNext();
+ iterator.hasNext();
+ iterator.next();
+ count++;
+ }
+ assertEquals(count, list.size());
+
+ list.resize(0);
+ assertFalse(list.iterator().hasNext());
+ }
+
+ @Test
+ public void testClear() {
+ list.add(asArray(1, 2, 3));
+ list.clear();
+ assertTrue(list.isEmpty());
+ assertEquals(-1, list.indexOf(cast(1)));
+ }
+
+ @Test
+ public void testFrom() {
+ list = LongArrayList.from(key1, key2, key3);
+ assertEquals(3, list.size());
+ assertListEquals(list.toArray(), 1, 2, 3);
+ assertEquals(list.size(), list.buffer.length);
+ }
+
+ @Test
+ public void testCopyList() {
+ list.add(asArray(1, 2, 3));
+ LongArrayList copy = new LongArrayList(list);
+ assertEquals(3, copy.size());
+ assertListEquals(copy.toArray(), 1, 2, 3);
+ assertEquals(copy.size(), copy.buffer.length);
+ }
+
+ @Test
+ public void testHashCodeEquals() {
+ LongArrayList l0 = LongArrayList.from();
+ assertEquals(1, l0.hashCode());
+ assertEquals(l0, LongArrayList.from());
+
+ LongArrayList l1 = LongArrayList.from(key1, key2, key3);
+ LongArrayList l2 = LongArrayList.from(key1, key2);
+ l2.add(key3);
+
+ assertEquals(l1.hashCode(), l2.hashCode());
+ assertEquals(l1, l2);
+ }
+
+ @Test
+ public void testEqualElements() {
+ LongArrayList l1 = LongArrayList.from(key1, key2, key3);
+ LongArrayList l2 = LongArrayList.from(key1, key2);
+ l2.add(key3);
+
+ assertEquals(l1.hashCode(), l2.hashCode());
+ assertTrue(l2.equalElements(l1));
+ }
+
+ @Test
+ public void testToArray() {
+ LongArrayList l1 = LongArrayList.from(key1, key2, key3);
+ l1.ensureCapacity(100);
+ long[] result = l1.toArray();
+ assertArrayEquals(new long[] {key1, key2, key3}, result);
+ }
+
+ @Test
+ public void testClone() {
+ list.add(key1, key2, key3);
+
+ LongArrayList cloned = list.clone();
+ cloned.removeAt(cloned.indexOf(key1));
+
+ assertSortedListEquals(list.toArray(), key1, key2, key3);
+ assertSortedListEquals(cloned.toArray(), key2, key3);
+ }
+
+ @Test
+ public void testToString() {
+ assertEquals(
+ "[" + key1 + ", " + key2 + ", " + key3 + "]",
+ LongArrayList.from(key1, key2, key3).toString());
+ }
+
+ @Test
+ public void testEqualsSameClass() {
+ LongArrayList l1 = LongArrayList.from(key1, key2, key3);
+ LongArrayList l2 = LongArrayList.from(key1, key2, key3);
+ LongArrayList l3 = LongArrayList.from(key1, key3, key2);
+
+ assertEquals(l1, l2);
+ assertEquals(l1.hashCode(), l2.hashCode());
+ assertNotEquals(l1, l3);
+ }
+
+ @Test
+ public void testEqualsSubClass() {
+ class Sub extends LongArrayList {}
+ ;
+
+ LongArrayList l1 = LongArrayList.from(key1, key2, key3);
+ LongArrayList l2 = new Sub();
+ LongArrayList l3 = new Sub();
+ l2.addAll(l1);
+ l3.addAll(l1);
+
+ assertEquals(l2, l3);
+ assertNotEquals(l1, l3);
+ }
+
+ @Test
+ public void testStream() {
+ assertEquals(key1, LongArrayList.from(key1, key2, key3).stream().min().orElseThrow());
+ assertEquals(key3, LongArrayList.from(key2, key1, key3).stream().max().orElseThrow());
+ assertEquals(0, LongArrayList.from(key1, key2, -key3).stream().sum());
+ expectThrows(
+ NoSuchElementException.class,
+ () -> {
+ LongArrayList.from().stream().min().orElseThrow();
+ });
+ }
+
+ @Test
+ public void testSort() {
+ list.add(key1, key3, key2);
+
+ LongArrayList list2 = new LongArrayList();
+ list2.ensureCapacity(100);
+ list2.addAll(list);
+ assertSame(list2, list2.sort());
+ assertEquals(LongArrayList.from(list.stream().sorted().toArray()), list2);
+ }
+
+ @Test
+ public void testReverse() {
+ for (int i = 0; i < 10; i++) {
+ long[] elements = new long[i];
+ for (int j = 0; j < i; j++) {
+ elements[j] = cast(j);
+ }
+ LongArrayList list = new LongArrayList();
+ list.ensureCapacity(30);
+ list.add(elements);
+ assertSame(list, list.reverse());
+ assertEquals(elements.length, list.size());
+ int reverseIndex = elements.length - 1;
+ for (LongCursor cursor : list) {
+ assertEquals(elements[reverseIndex--], cursor.value);
+ }
+ }
+ }
+
+ /** Check if the array's content is identical to a given sequence of elements. */
+ private static void assertListEquals(long[] array, long... elements) {
+ assertEquals(elements.length, array.length);
+ assertArrayEquals(elements, array);
+ }
+
+ private static long[] asArray(long... elements) {
+ return elements;
+ }
+
+ /** Check if the array's content is identical to a given sequence of elements. */
+ private static void assertSortedListEquals(long[] array, long... elements) {
+ assertEquals(elements.length, array.length);
+ Arrays.sort(array);
+ Arrays.sort(elements);
+ assertArrayEquals(elements, array);
+ }
+}
diff --git a/lucene/facet/src/java/org/apache/lucene/facet/range/OverlappingLongRangeCounter.java b/lucene/facet/src/java/org/apache/lucene/facet/range/OverlappingLongRangeCounter.java
index a46adac7b86..9c09f29841f 100644
--- a/lucene/facet/src/java/org/apache/lucene/facet/range/OverlappingLongRangeCounter.java
+++ b/lucene/facet/src/java/org/apache/lucene/facet/range/OverlappingLongRangeCounter.java
@@ -16,8 +16,10 @@
*/
package org.apache.lucene.facet.range;
+import com.carrotsearch.hppc.IntArrayList;
import com.carrotsearch.hppc.LongArrayList;
import com.carrotsearch.hppc.LongIntHashMap;
+import com.carrotsearch.hppc.cursors.IntCursor;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
@@ -198,8 +200,8 @@ class OverlappingLongRangeCounter extends LongRangeCounter {
}
}
if (node.outputs != null) {
- for (int rangeIndex : node.outputs) {
- increment(rangeIndex, count);
+ for (IntCursor rangeIndex : node.outputs) {
+ increment(rangeIndex.value, count);
}
}
@@ -224,8 +226,8 @@ class OverlappingLongRangeCounter extends LongRangeCounter {
elementaryIntervalUpto++;
}
if (containedHit && node.outputs != null) {
- for (int rangeIndex : node.outputs) {
- multiValuedDocRangeHits.set(rangeIndex);
+ for (IntCursor rangeIndex : node.outputs) {
+ multiValuedDocRangeHits.set(rangeIndex.value);
}
}
@@ -318,7 +320,7 @@ class OverlappingLongRangeCounter extends LongRangeCounter {
// Which range indices to output when a query goes
// through this node:
- List<Integer> outputs;
+ IntArrayList outputs;
public LongRangeNode(
long start,
@@ -352,7 +354,7 @@ class OverlappingLongRangeCounter extends LongRangeCounter {
// Our range is fully included in the incoming
// range; add to our output list:
if (outputs == null) {
- outputs = new ArrayList<>();
+ outputs = new IntArrayList();
}
outputs.add(index);
} else if (left != null) {
diff --git a/lucene/facet/src/java/org/apache/lucene/facet/taxonomy/directory/DirectoryTaxonomyReader.java b/lucene/facet/src/java/org/apache/lucene/facet/taxonomy/directory/DirectoryTaxonomyReader.java
index c1788d0a6a2..0b0ea71a58a 100644
--- a/lucene/facet/src/java/org/apache/lucene/facet/taxonomy/directory/DirectoryTaxonomyReader.java
+++ b/lucene/facet/src/java/org/apache/lucene/facet/taxonomy/directory/DirectoryTaxonomyReader.java
@@ -16,6 +16,8 @@
*/
package org.apache.lucene.facet.taxonomy.directory;
+import com.carrotsearch.hppc.IntArrayList;
+import com.carrotsearch.hppc.cursors.IntCursor;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
@@ -553,7 +555,7 @@ public class DirectoryTaxonomyReader extends TaxonomyReader implements Accountab
LeafReader leafReader;
LeafReaderContext leafReaderContext;
BinaryDocValues values = null;
- List<Integer> uncachedOrdinalPositions = new ArrayList<>();
+ IntArrayList uncachedOrdinalPositions = new IntArrayList();
for (int i = 0; i < ordinalsLength; i++) {
if (bulkPath[originalPosition[i]] == null) {
@@ -590,9 +592,9 @@ public class DirectoryTaxonomyReader extends TaxonomyReader implements Accountab
if (uncachedOrdinalPositions.isEmpty() == false) {
synchronized (categoryCache) {
- for (int i : uncachedOrdinalPositions) {
+ for (IntCursor i : uncachedOrdinalPositions) {
// add the value to the categoryCache after computation
- categoryCache.put(ordinals[i], bulkPath[originalPosition[i]]);
+ categoryCache.put(ordinals[i.value], bulkPath[originalPosition[i.value]]);
}
}
}
diff --git a/lucene/join/src/java/org/apache/lucene/search/join/DiversifyingNearestChildrenKnnCollector.java b/lucene/join/src/java/org/apache/lucene/search/join/DiversifyingNearestChildrenKnnCollector.java
index b71adb4f014..f79958e812b 100644
--- a/lucene/join/src/java/org/apache/lucene/search/join/DiversifyingNearestChildrenKnnCollector.java
+++ b/lucene/join/src/java/org/apache/lucene/search/join/DiversifyingNearestChildrenKnnCollector.java
@@ -17,13 +17,13 @@
package org.apache.lucene.search.join;
+import com.carrotsearch.hppc.IntIntHashMap;
import org.apache.lucene.search.AbstractKnnCollector;
import org.apache.lucene.search.ScoreDoc;
import org.apache.lucene.search.TopDocs;
import org.apache.lucene.search.TotalHits;
import org.apache.lucene.util.ArrayUtil;
import org.apache.lucene.util.BitSet;
-import org.apache.lucene.util.hppc.IntIntHashMap;
/**
* This collects the nearest children vectors. Diversifying the results over the provided parent
diff --git a/lucene/join/src/java/org/apache/lucene/search/join/PointInSetIncludingScoreQuery.java b/lucene/join/src/java/org/apache/lucene/search/join/PointInSetIncludingScoreQuery.java
index 55030086a44..1cdf62920de 100644
--- a/lucene/join/src/java/org/apache/lucene/search/join/PointInSetIncludingScoreQuery.java
+++ b/lucene/join/src/java/org/apache/lucene/search/join/PointInSetIncludingScoreQuery.java
@@ -17,10 +17,10 @@
package org.apache.lucene.search.join;
+import com.carrotsearch.hppc.FloatArrayList;
+import com.carrotsearch.hppc.cursors.FloatCursor;
import java.io.IOException;
-import java.util.ArrayList;
import java.util.Iterator;
-import java.util.List;
import java.util.function.BiFunction;
import org.apache.lucene.document.DoublePoint;
import org.apache.lucene.document.FloatPoint;
@@ -77,7 +77,7 @@ abstract class PointInSetIncludingScoreQuery extends Query implements Accountabl
final String field;
final int bytesPerDim;
- final List<Float> aggregatedJoinScores;
+ final FloatArrayList aggregatedJoinScores;
private final long ramBytesUsed; // cache
@@ -103,7 +103,7 @@ abstract class PointInSetIncludingScoreQuery extends Query implements Accountabl
}
this.bytesPerDim = bytesPerDim;
- aggregatedJoinScores = new ArrayList<>();
+ aggregatedJoinScores = new FloatArrayList();
PrefixCodedTerms.Builder builder = new PrefixCodedTerms.Builder();
BytesRefBuilder previous = null;
BytesRef current;
@@ -240,8 +240,8 @@ abstract class PointInSetIncludingScoreQuery extends Query implements Accountabl
private final FixedBitSet result;
private final float[] scores;
- private TermIterator iterator;
- private Iterator<Float> scoreIterator;
+ private final TermIterator iterator;
+ private final Iterator<FloatCursor> scoreIterator;
private BytesRef nextQueryPoint;
float nextScore;
private final BytesRef scratch = new BytesRef();
@@ -256,7 +256,7 @@ abstract class PointInSetIncludingScoreQuery extends Query implements Accountabl
this.scoreIterator = aggregatedJoinScores.iterator();
nextQueryPoint = iterator.next();
if (scoreIterator.hasNext()) {
- nextScore = scoreIterator.next();
+ nextScore = scoreIterator.next().value;
}
}
@@ -286,7 +286,7 @@ abstract class PointInSetIncludingScoreQuery extends Query implements Accountabl
// Query point is before index point, so we move to next query point
nextQueryPoint = iterator.next();
if (scoreIterator.hasNext()) {
- nextScore = scoreIterator.next();
+ nextScore = scoreIterator.next().value;
}
} else {
// Query point is after index point, so we don't collect and we return:
@@ -304,7 +304,7 @@ abstract class PointInSetIncludingScoreQuery extends Query implements Accountabl
// query point is before the start of this cell
nextQueryPoint = iterator.next();
if (scoreIterator.hasNext()) {
- nextScore = scoreIterator.next();
+ nextScore = scoreIterator.next().value;
}
continue;
}
diff --git a/lucene/sandbox/src/java/org/apache/lucene/sandbox/document/FloatPointNearestNeighbor.java b/lucene/sandbox/src/java/org/apache/lucene/sandbox/document/FloatPointNearestNeighbor.java
index 4e4417814a4..3f0ced4f520 100644
--- a/lucene/sandbox/src/java/org/apache/lucene/sandbox/document/FloatPointNearestNeighbor.java
+++ b/lucene/sandbox/src/java/org/apache/lucene/sandbox/document/FloatPointNearestNeighbor.java
@@ -31,6 +31,7 @@ import org.apache.lucene.search.ScoreDoc;
import org.apache.lucene.search.TopFieldDocs;
import org.apache.lucene.search.TotalHits;
import org.apache.lucene.util.Bits;
+import org.apache.lucene.util.hppc.IntArrayList;
/**
* KNN search on top of N dimensional indexed float points.
@@ -176,7 +177,7 @@ public class FloatPointNearestNeighbor {
private static NearestHit[] nearest(
List<PointValues> readers,
List<Bits> liveDocs,
- List<Integer> docBases,
+ IntArrayList docBases,
final int topN,
float[] origin)
throws IOException {
@@ -310,7 +311,7 @@ public class FloatPointNearestNeighbor {
throw new IllegalArgumentException("searcher must not be null");
}
List<PointValues> readers = new ArrayList<>();
- List<Integer> docBases = new ArrayList<>();
+ IntArrayList docBases = new IntArrayList();
List<Bits> liveDocs = new ArrayList<>();
int totalHits = 0;
for (LeafReaderContext leaf : searcher.getIndexReader().leaves()) {
diff --git a/lucene/sandbox/src/java/org/apache/lucene/sandbox/search/LatLonPointPrototypeQueries.java b/lucene/sandbox/src/java/org/apache/lucene/sandbox/search/LatLonPointPrototypeQueries.java
index 38cf543caf4..712a0fd2842 100644
--- a/lucene/sandbox/src/java/org/apache/lucene/sandbox/search/LatLonPointPrototypeQueries.java
+++ b/lucene/sandbox/src/java/org/apache/lucene/sandbox/search/LatLonPointPrototypeQueries.java
@@ -33,6 +33,7 @@ import org.apache.lucene.search.TopFieldDocs;
import org.apache.lucene.search.TotalHits;
import org.apache.lucene.util.Bits;
import org.apache.lucene.util.SloppyMath;
+import org.apache.lucene.util.hppc.IntArrayList;
/**
* Holder class for prototype sandboxed queries
@@ -89,7 +90,7 @@ public class LatLonPointPrototypeQueries {
throw new IllegalArgumentException("searcher must not be null");
}
List<PointValues> readers = new ArrayList<>();
- List<Integer> docBases = new ArrayList<>();
+ IntArrayList docBases = new IntArrayList();
List<Bits> liveDocs = new ArrayList<>();
int totalHits = 0;
for (LeafReaderContext leaf : searcher.getIndexReader().leaves()) {
diff --git a/lucene/sandbox/src/java/org/apache/lucene/sandbox/search/NearestNeighbor.java b/lucene/sandbox/src/java/org/apache/lucene/sandbox/search/NearestNeighbor.java
index a3fe984e651..c35a16e97a2 100644
--- a/lucene/sandbox/src/java/org/apache/lucene/sandbox/search/NearestNeighbor.java
+++ b/lucene/sandbox/src/java/org/apache/lucene/sandbox/search/NearestNeighbor.java
@@ -30,6 +30,7 @@ import org.apache.lucene.index.PointValues.PointTree;
import org.apache.lucene.index.PointValues.Relation;
import org.apache.lucene.util.Bits;
import org.apache.lucene.util.SloppyMath;
+import org.apache.lucene.util.hppc.IntArrayList;
/**
* KNN search on top of 2D lat/lon indexed points.
@@ -244,7 +245,7 @@ class NearestNeighbor {
double pointLon,
List<PointValues> readers,
List<Bits> liveDocs,
- List<Integer> docBases,
+ IntArrayList docBases,
final int n)
throws IOException {
diff --git a/lucene/sandbox/src/java/org/apache/lucene/sandbox/search/QueryProfilerTree.java b/lucene/sandbox/src/java/org/apache/lucene/sandbox/search/QueryProfilerTree.java
index 98860e9f56c..1044b0aa44c 100644
--- a/lucene/sandbox/src/java/org/apache/lucene/sandbox/search/QueryProfilerTree.java
+++ b/lucene/sandbox/src/java/org/apache/lucene/sandbox/search/QueryProfilerTree.java
@@ -23,6 +23,8 @@ import java.util.Collections;
import java.util.Deque;
import java.util.List;
import org.apache.lucene.search.Query;
+import org.apache.lucene.util.hppc.IntArrayList;
+import org.apache.lucene.util.hppc.IntCursor;
/**
* This class tracks the dependency tree for queries (scoring and rewriting) and generates {@link
@@ -33,13 +35,13 @@ class QueryProfilerTree {
private final ArrayList<QueryProfilerBreakdown> breakdowns;
/** Maps the Query to it's list of children. This is basically the dependency tree */
- private final ArrayList<ArrayList<Integer>> tree;
+ private final ArrayList<IntArrayList> tree;
/** A list of the original queries, keyed by index position */
private final ArrayList<Query> queries;
/** A list of top-level "roots". Each root can have its own tree of profiles */
- private final ArrayList<Integer> roots;
+ private final IntArrayList roots;
/** A temporary stack used to record where we are in the dependency tree. */
private final Deque<Integer> stack;
@@ -56,7 +58,7 @@ class QueryProfilerTree {
stack = new ArrayDeque<>(10);
tree = new ArrayList<>(10);
queries = new ArrayList<>(10);
- roots = new ArrayList<>(10);
+ roots = new IntArrayList(10);
}
/**
@@ -113,7 +115,7 @@ class QueryProfilerTree {
private QueryProfilerBreakdown addDependencyNode(Query query, int token) {
// Add a new slot in the dependency tree
- tree.add(new ArrayList<>(5));
+ tree.add(new IntArrayList(5));
// Save our query for lookup later
queries.add(query);
@@ -140,8 +142,8 @@ class QueryProfilerTree {
*/
public List<QueryProfilerResult> getTree() {
ArrayList<QueryProfilerResult> results = new ArrayList<>(roots.size());
- for (Integer root : roots) {
- results.add(doGetTree(root));
+ for (IntCursor root : roots) {
+ results.add(doGetTree(root.value));
}
return results;
}
@@ -155,13 +157,13 @@ class QueryProfilerTree {
private QueryProfilerResult doGetTree(int token) {
Query query = queries.get(token);
QueryProfilerBreakdown breakdown = breakdowns.get(token);
- List<Integer> children = tree.get(token);
+ IntArrayList children = tree.get(token);
List<QueryProfilerResult> childrenProfileResults = Collections.emptyList();
if (children != null) {
childrenProfileResults = new ArrayList<>(children.size());
- for (Integer child : children) {
- QueryProfilerResult childNode = doGetTree(child);
+ for (IntCursor child : children) {
+ QueryProfilerResult childNode = doGetTree(child.value);
childrenProfileResults.add(childNode);
}
}
@@ -198,7 +200,7 @@ class QueryProfilerTree {
*/
private void updateParent(int childToken) {
Integer parent = stack.peekLast();
- ArrayList<Integer> parentNode = tree.get(parent);
+ IntArrayList parentNode = tree.get(parent);
parentNode.add(childToken);
tree.set(parent, parentNode);
}
diff --git a/lucene/spatial3d/build.gradle b/lucene/spatial3d/build.gradle
index 0b258337cac..184c39cd4bb 100644
--- a/lucene/spatial3d/build.gradle
+++ b/lucene/spatial3d/build.gradle
@@ -21,6 +21,9 @@ description = '3D spatial planar geometry APIs'
dependencies {
moduleApi project(':lucene:core')
+
+ moduleImplementation 'com.carrotsearch:hppc'
+
moduleTestImplementation project(':lucene:test-framework')
// We have to exclude ourselves because spatial-test-fixtures depend
diff --git a/lucene/spatial3d/src/java/module-info.java b/lucene/spatial3d/src/java/module-info.java
index 9bffb23a468..7fd67a03b55 100644
--- a/lucene/spatial3d/src/java/module-info.java
+++ b/lucene/spatial3d/src/java/module-info.java
@@ -16,8 +16,10 @@
*/
/** 3D spatial planar geometry APIs */
+@SuppressWarnings({"requires-automatic"})
module org.apache.lucene.spatial3d {
requires org.apache.lucene.core;
+ requires com.carrotsearch.hppc;
exports org.apache.lucene.spatial3d;
exports org.apache.lucene.spatial3d.geom;
diff --git a/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoStandardPath.java b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoStandardPath.java
index 41bec878465..e100b51563d 100755
--- a/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoStandardPath.java
+++ b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoStandardPath.java
@@ -16,6 +16,7 @@
*/
package org.apache.lucene.spatial3d.geom;
+import com.carrotsearch.hppc.IntArrayList;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
@@ -1958,18 +1959,18 @@ class GeoStandardPath extends GeoBasePath {
private static class TreeBuilder {
private final List<PathComponent> componentStack;
- private final List<Integer> depthStack;
+ private final IntArrayList depthStack;
public TreeBuilder(final int max) {
componentStack = new ArrayList<>(max);
- depthStack = new ArrayList<>(max);
+ depthStack = new IntArrayList(max);
}
public void addComponent(final PathComponent component) {
componentStack.add(component);
depthStack.add(0);
while (depthStack.size() >= 2) {
- if (depthStack.get(depthStack.size() - 1).equals(depthStack.get(depthStack.size() - 2))) {
+ if (depthStack.get(depthStack.size() - 1) == depthStack.get(depthStack.size() - 2)) {
mergeTop();
} else {
break;
diff --git a/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/StandardObjects.java b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/StandardObjects.java
index f40691d7146..22e949bbd97 100644
--- a/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/StandardObjects.java
+++ b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/StandardObjects.java
@@ -17,9 +17,9 @@
package org.apache.lucene.spatial3d.geom;
+import com.carrotsearch.hppc.IntObjectHashMap;
import java.util.HashMap;
import java.util.Map;
-import org.apache.lucene.util.hppc.IntObjectHashMap;
/**
* Lookup tables for classes that can be serialized using a code.