mirror of https://github.com/apache/lucene.git
Convert more classes to record classes (#13328)
This commit is contained in:
parent
955986d836
commit
942065cc3e
|
@ -118,6 +118,8 @@ API Changes
|
|||
argument with a `FacetsCollectorManager` and update the return type to include both `TopDocs` results as well as
|
||||
facets results. (Luca Cavanna)
|
||||
|
||||
* GITHUB#13328: Convert many basic Lucene classes to record classes, including CollectionStatistics, TermStatistics and LeafMetadata. (Shubham Chaudhary)
|
||||
|
||||
New Features
|
||||
---------------------
|
||||
|
||||
|
|
|
@ -193,6 +193,7 @@ access the members using method calls instead of field accesses. Affected classe
|
|||
|
||||
- `IOContext`, `MergeInfo`, and `FlushInfo` (GITHUB#13205)
|
||||
- `BooleanClause` (GITHUB#13261)
|
||||
- Many basic Lucene classes, including `CollectionStatistics`, `TermStatistics` and `LeafMetadata` (GITHUB#13328)
|
||||
|
||||
### Boolean flags on IOContext replaced with a new ReadAdvice enum.
|
||||
|
||||
|
|
|
@ -52,7 +52,7 @@ class CheckCompoundPattern {
|
|||
|
||||
boolean prohibitsCompounding(CharsRef word, int breakPos, Root<?> rootBefore, Root<?> rootAfter) {
|
||||
if (isNonAffixedPattern(endChars)) {
|
||||
if (!charsMatch(word, breakPos - rootBefore.word.length(), rootBefore.word)) {
|
||||
if (!charsMatch(word, breakPos - rootBefore.word().length(), rootBefore.word())) {
|
||||
return false;
|
||||
}
|
||||
} else if (!charsMatch(word, breakPos - endChars.length(), endChars)) {
|
||||
|
@ -60,7 +60,7 @@ class CheckCompoundPattern {
|
|||
}
|
||||
|
||||
if (isNonAffixedPattern(beginChars)) {
|
||||
if (!charsMatch(word, breakPos, rootAfter.word)) {
|
||||
if (!charsMatch(word, breakPos, rootAfter.word())) {
|
||||
return false;
|
||||
}
|
||||
} else if (!charsMatch(word, breakPos, beginChars)) {
|
||||
|
@ -84,7 +84,7 @@ class CheckCompoundPattern {
|
|||
|
||||
private boolean hasAllFlags(Root<?> root, char[] flags) {
|
||||
for (char flag : flags) {
|
||||
if (!dictionary.hasFlag(root.entryId, flag)) {
|
||||
if (!dictionary.hasFlag(root.entryId(), flag)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -24,7 +24,6 @@ import java.util.ArrayList;
|
|||
import java.util.Comparator;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.PriorityQueue;
|
||||
import java.util.Set;
|
||||
import java.util.TreeSet;
|
||||
|
@ -111,7 +110,7 @@ class GeneratingSuggester {
|
|||
|
||||
private static boolean isWorseThan(int score, CharsRef candidate, Weighted<Root<String>> root) {
|
||||
return score < root.score
|
||||
|| score == root.score && CharSequence.compare(candidate, root.word.word) > 0;
|
||||
|| score == root.score && CharSequence.compare(candidate, root.word.word()) > 0;
|
||||
}
|
||||
|
||||
private void processSuggestibleWords(
|
||||
|
@ -162,11 +161,11 @@ class GeneratingSuggester {
|
|||
List<char[]> crossProducts = new ArrayList<>();
|
||||
Set<String> result = new LinkedHashSet<>();
|
||||
|
||||
if (!dictionary.hasFlag(root.entryId, dictionary.needaffix)) {
|
||||
result.add(root.word);
|
||||
if (!dictionary.hasFlag(root.entryId(), dictionary.needaffix)) {
|
||||
result.add(root.word());
|
||||
}
|
||||
|
||||
char[] wordChars = root.word.toCharArray();
|
||||
char[] wordChars = root.word().toCharArray();
|
||||
|
||||
// suffixes
|
||||
processAffixes(
|
||||
|
@ -180,7 +179,7 @@ class GeneratingSuggester {
|
|||
}
|
||||
|
||||
String suffix = misspelled.substring(misspelled.length() - suffixLength);
|
||||
String withSuffix = root.word.substring(0, root.word.length() - stripLength) + suffix;
|
||||
String withSuffix = root.word().substring(0, root.word().length() - stripLength) + suffix;
|
||||
result.add(withSuffix);
|
||||
if (dictionary.isCrossProduct(suffixId)) {
|
||||
crossProducts.add(withSuffix.toCharArray());
|
||||
|
@ -192,7 +191,7 @@ class GeneratingSuggester {
|
|||
true,
|
||||
misspelled,
|
||||
(prefixLength, prefixId) -> {
|
||||
if (!dictionary.hasFlag(root.entryId, dictionary.affixData(prefixId, AFFIX_FLAG))
|
||||
if (!dictionary.hasFlag(root.entryId(), dictionary.affixData(prefixId, AFFIX_FLAG))
|
||||
|| !dictionary.isCrossProduct(prefixId)) {
|
||||
return;
|
||||
}
|
||||
|
@ -217,7 +216,7 @@ class GeneratingSuggester {
|
|||
if (hasCompatibleFlags(root, prefixId)
|
||||
&& checkAffixCondition(prefixId, wordChars, stripLength, stemLength)) {
|
||||
String prefix = misspelled.substring(0, prefixLength);
|
||||
result.add(prefix + root.word.substring(stripLength));
|
||||
result.add(prefix + root.word().substring(stripLength));
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -263,7 +262,7 @@ class GeneratingSuggester {
|
|||
}
|
||||
|
||||
private boolean hasCompatibleFlags(Root<?> root, int affixId) {
|
||||
if (!dictionary.hasFlag(root.entryId, dictionary.affixData(affixId, AFFIX_FLAG))) {
|
||||
if (!dictionary.hasFlag(root.entryId(), dictionary.affixData(affixId, AFFIX_FLAG))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -447,28 +446,8 @@ class GeneratingSuggester {
|
|||
return commonScore;
|
||||
}
|
||||
|
||||
private static class Weighted<T extends Comparable<T>> implements Comparable<Weighted<T>> {
|
||||
final T word;
|
||||
final int score;
|
||||
|
||||
Weighted(T word, int score) {
|
||||
this.word = word;
|
||||
this.score = score;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (!(o instanceof Weighted)) return false;
|
||||
@SuppressWarnings("unchecked")
|
||||
Weighted<T> that = (Weighted<T>) o;
|
||||
return score == that.score && word.equals(that.word);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(word, score);
|
||||
}
|
||||
private record Weighted<T extends Comparable<T>>(T word, int score)
|
||||
implements Comparable<Weighted<T>> {
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
|
|
|
@ -132,7 +132,7 @@ public class Hunspell {
|
|||
Boolean checkSimpleWord(char[] wordChars, int length, WordCase originalCase) {
|
||||
Root<CharsRef> entry = findStem(wordChars, 0, length, originalCase, SIMPLE_WORD);
|
||||
if (entry != null) {
|
||||
return !dictionary.hasFlag(entry.entryId, dictionary.forbiddenword);
|
||||
return !dictionary.hasFlag(entry.entryId(), dictionary.forbiddenword);
|
||||
}
|
||||
|
||||
return null;
|
||||
|
@ -229,7 +229,7 @@ public class Hunspell {
|
|||
stem = findStem(word.chars, word.offset, breakPos + 1, originalCase, context);
|
||||
}
|
||||
if (stem != null
|
||||
&& !dictionary.hasFlag(stem.entryId, dictionary.forbiddenword)
|
||||
&& !dictionary.hasFlag(stem.entryId(), dictionary.forbiddenword)
|
||||
&& (prev == null || prev.mayCompound(stem, breakPos, originalCase))) {
|
||||
CompoundPart part = new CompoundPart(prev, word, breakPos, stem, null);
|
||||
if (checkCompoundsAfter(originalCase, part)) {
|
||||
|
@ -274,7 +274,7 @@ public class Hunspell {
|
|||
Root<CharsRef> lastRoot =
|
||||
findStem(word.chars, breakOffset, remainingLength, originalCase, COMPOUND_END);
|
||||
if (lastRoot != null
|
||||
&& !dictionary.hasFlag(lastRoot.entryId, dictionary.forbiddenword)
|
||||
&& !dictionary.hasFlag(lastRoot.entryId(), dictionary.forbiddenword)
|
||||
&& !(dictionary.checkCompoundDup && prev.root.equals(lastRoot))
|
||||
&& !hasForceUCaseProblem(lastRoot, originalCase, word.chars)
|
||||
&& prev.mayCompound(lastRoot, remainingLength, originalCase)) {
|
||||
|
@ -288,7 +288,7 @@ public class Hunspell {
|
|||
private boolean hasForceUCaseProblem(Root<?> root, WordCase originalCase, char[] wordChars) {
|
||||
if (originalCase == WordCase.TITLE || originalCase == WordCase.UPPER) return false;
|
||||
if (originalCase == null && Character.isUpperCase(wordChars[0])) return false;
|
||||
return dictionary.hasFlag(root.entryId, dictionary.forceUCase);
|
||||
return dictionary.hasFlag(root.entryId(), dictionary.forceUCase);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -16,36 +16,13 @@
|
|||
*/
|
||||
package org.apache.lucene.analysis.hunspell;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
class Root<T extends CharSequence> implements Comparable<Root<T>> {
|
||||
final T word;
|
||||
final int entryId;
|
||||
|
||||
Root(T word, int entryId) {
|
||||
this.word = word;
|
||||
this.entryId = entryId;
|
||||
}
|
||||
record Root<T extends CharSequence>(T word, int entryId) implements Comparable<Root<T>> {
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return word.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (!(o instanceof Root)) return false;
|
||||
@SuppressWarnings("unchecked")
|
||||
Root<T> root = (Root<T>) o;
|
||||
return entryId == root.entryId && word.equals(root.word);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(word, entryId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(Root<T> o) {
|
||||
return CharSequence.compare(word, o.word);
|
||||
|
|
|
@ -59,12 +59,12 @@ public class PatternTypingFilter extends TokenFilter {
|
|||
public final boolean incrementToken() throws IOException {
|
||||
if (input.incrementToken()) {
|
||||
for (PatternTypingRule rule : replacementAndFlagByPattern) {
|
||||
Matcher matcher = rule.getPattern().matcher(termAtt);
|
||||
Matcher matcher = rule.pattern().matcher(termAtt);
|
||||
if (matcher.find()) {
|
||||
// allow 2nd reset() and find() that occurs inside replaceFirst to avoid excess string
|
||||
// creation
|
||||
typeAtt.setType(matcher.replaceFirst(rule.getTypeTemplate()));
|
||||
flagAtt.setFlags(rule.getFlags());
|
||||
typeAtt.setType(matcher.replaceFirst(rule.typeTemplate()));
|
||||
flagAtt.setFlags(rule.flags());
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -74,27 +74,5 @@ public class PatternTypingFilter extends TokenFilter {
|
|||
}
|
||||
|
||||
/** Value holding class for pattern typing rules. */
|
||||
public static class PatternTypingRule {
|
||||
private final Pattern pattern;
|
||||
private final int flags;
|
||||
private final String typeTemplate;
|
||||
|
||||
public PatternTypingRule(Pattern pattern, int flags, String typeTemplate) {
|
||||
this.pattern = pattern;
|
||||
this.flags = flags;
|
||||
this.typeTemplate = typeTemplate;
|
||||
}
|
||||
|
||||
public Pattern getPattern() {
|
||||
return pattern;
|
||||
}
|
||||
|
||||
public int getFlags() {
|
||||
return flags;
|
||||
}
|
||||
|
||||
public String getTypeTemplate() {
|
||||
return typeTemplate;
|
||||
}
|
||||
}
|
||||
public record PatternTypingRule(Pattern pattern, int flags, String typeTemplate) {}
|
||||
}
|
||||
|
|
|
@ -142,22 +142,10 @@ public final class SynonymGraphFilter extends TokenFilter {
|
|||
}
|
||||
}
|
||||
|
||||
static class BufferedOutputToken {
|
||||
final String term;
|
||||
|
||||
// Non-null if this was an incoming token:
|
||||
final State state;
|
||||
|
||||
final int startNode;
|
||||
final int endNode;
|
||||
|
||||
public BufferedOutputToken(State state, String term, int startNode, int endNode) {
|
||||
this.state = state;
|
||||
this.term = term;
|
||||
this.startNode = startNode;
|
||||
this.endNode = endNode;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* @param state Non-null if this was an incoming token:
|
||||
*/
|
||||
record BufferedOutputToken(State state, String term, int startNode, int endNode) {}
|
||||
|
||||
/**
|
||||
* Apply previously built synonyms to incoming tokens.
|
||||
|
|
|
@ -18,17 +18,15 @@ package org.apache.lucene.analysis.synonym.word2vec;
|
|||
|
||||
import org.apache.lucene.util.BytesRef;
|
||||
|
||||
/** Wraps a term and boost */
|
||||
public class TermAndBoost {
|
||||
/** the term */
|
||||
public final BytesRef term;
|
||||
|
||||
/** the boost */
|
||||
public final float boost;
|
||||
|
||||
/**
|
||||
* Wraps a term and boost
|
||||
*
|
||||
* @param term the term
|
||||
* @param boost the boost
|
||||
*/
|
||||
public record TermAndBoost(BytesRef term, float boost) {
|
||||
/** Creates a new TermAndBoost */
|
||||
public TermAndBoost(BytesRef term, float boost) {
|
||||
this.term = BytesRef.deepCopyOf(term);
|
||||
this.boost = boost;
|
||||
public TermAndBoost {
|
||||
term = BytesRef.deepCopyOf(term);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -80,7 +80,7 @@ public final class Word2VecSynonymFilter extends TokenFilter {
|
|||
clearAttributes();
|
||||
restoreState(this.lastState);
|
||||
termAtt.setEmpty();
|
||||
termAtt.append(synonym.term.utf8ToString());
|
||||
termAtt.append(synonym.term().utf8ToString());
|
||||
typeAtt.setType(SynonymGraphFilter.TYPE_SYNONYM);
|
||||
posLenAtt.setPositionLength(1);
|
||||
posIncrementAtt.setPositionIncrement(0);
|
||||
|
|
|
@ -64,7 +64,7 @@ public class TestWord2VecSynonymProvider extends LuceneTestCase {
|
|||
|
||||
assertEquals(4, actualSynonymsResults.size());
|
||||
for (int i = 0; i < expectedSynonyms.length; i++) {
|
||||
assertEquals(new BytesRef(expectedSynonyms[i]), actualSynonymsResults.get(i).term);
|
||||
assertEquals(new BytesRef(expectedSynonyms[i]), actualSynonymsResults.get(i).term());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -83,8 +83,8 @@ public class TestWord2VecSynonymProvider extends LuceneTestCase {
|
|||
|
||||
BytesRef expectedFirstSynonymTerm = new BytesRef("b");
|
||||
double expectedFirstSynonymBoost = 1.0;
|
||||
assertEquals(expectedFirstSynonymTerm, actualSynonymsResults.get(0).term);
|
||||
assertEquals(expectedFirstSynonymBoost, actualSynonymsResults.get(0).boost, 0.001f);
|
||||
assertEquals(expectedFirstSynonymTerm, actualSynonymsResults.get(0).term());
|
||||
assertEquals(expectedFirstSynonymBoost, actualSynonymsResults.get(0).boost(), 0.001f);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
|
@ -139,19 +139,7 @@ public final class JapaneseCompletionFilter extends TokenFilter {
|
|||
}
|
||||
}
|
||||
|
||||
private static class CompletionToken {
|
||||
final String term;
|
||||
final boolean isFirst;
|
||||
final int startOffset;
|
||||
final int endOffset;
|
||||
|
||||
CompletionToken(String term, boolean isFirst, int startOffset, int endOffset) {
|
||||
this.term = term;
|
||||
this.isFirst = isFirst;
|
||||
this.startOffset = startOffset;
|
||||
this.endOffset = endOffset;
|
||||
}
|
||||
}
|
||||
private record CompletionToken(String term, boolean isFirst, int startOffset, int endOffset) {}
|
||||
|
||||
private static class CompletionTokenGenerator implements Iterator<CompletionToken> {
|
||||
|
||||
|
|
|
@ -180,13 +180,5 @@ public class KatakanaRomanizer {
|
|||
return null;
|
||||
}
|
||||
|
||||
private static class MatchedKeystroke {
|
||||
final int keystrokeLen;
|
||||
final int keystrokeIndex;
|
||||
|
||||
MatchedKeystroke(int keystrokeLen, int keystrokeIndex) {
|
||||
this.keystrokeLen = keystrokeLen;
|
||||
this.keystrokeIndex = keystrokeIndex;
|
||||
}
|
||||
}
|
||||
private record MatchedKeystroke(int keystrokeLen, int keystrokeIndex) {}
|
||||
}
|
||||
|
|
|
@ -268,19 +268,19 @@ final class Viterbi
|
|||
final KoMorphData.Morpheme morpheme = morphemes[i];
|
||||
final Token compoundToken;
|
||||
if (token.getPOSType() == POS.Type.COMPOUND) {
|
||||
assert endOffset - morpheme.surfaceForm.length() >= 0;
|
||||
assert endOffset - morpheme.surfaceForm().length() >= 0;
|
||||
compoundToken =
|
||||
new DecompoundToken(
|
||||
morpheme.posTag,
|
||||
morpheme.surfaceForm,
|
||||
endOffset - morpheme.surfaceForm.length(),
|
||||
morpheme.posTag(),
|
||||
morpheme.surfaceForm(),
|
||||
endOffset - morpheme.surfaceForm().length(),
|
||||
endOffset,
|
||||
backType);
|
||||
} else {
|
||||
compoundToken =
|
||||
new DecompoundToken(
|
||||
morpheme.posTag,
|
||||
morpheme.surfaceForm,
|
||||
morpheme.posTag(),
|
||||
morpheme.surfaceForm(),
|
||||
token.getStartOffset(),
|
||||
token.getEndOffset(),
|
||||
backType);
|
||||
|
@ -289,7 +289,7 @@ final class Viterbi
|
|||
compoundToken.setPositionIncrement(0);
|
||||
}
|
||||
++posLen;
|
||||
endOffset -= morpheme.surfaceForm.length();
|
||||
endOffset -= morpheme.surfaceForm().length();
|
||||
pending.add(compoundToken);
|
||||
if (VERBOSE) {
|
||||
System.out.println(" add token=" + pending.get(pending.size() - 1));
|
||||
|
|
|
@ -22,15 +22,7 @@ import org.apache.lucene.analysis.morph.MorphData;
|
|||
/** Represents Korean morphological information. */
|
||||
public interface KoMorphData extends MorphData {
|
||||
/** A morpheme extracted from a compound token. */
|
||||
class Morpheme {
|
||||
public final POS.Tag posTag;
|
||||
public final String surfaceForm;
|
||||
|
||||
public Morpheme(POS.Tag posTag, String surfaceForm) {
|
||||
this.posTag = posTag;
|
||||
this.surfaceForm = surfaceForm;
|
||||
}
|
||||
}
|
||||
record Morpheme(POS.Tag posTag, String surfaceForm) {}
|
||||
|
||||
/**
|
||||
* Get the {@link org.apache.lucene.analysis.ko.POS.Type} of specified word (morpheme, compound,
|
||||
|
|
|
@ -150,13 +150,13 @@ class TokenInfoDictionaryEntryWriter extends DictionaryEntryWriter {
|
|||
int compoundOffset = 0;
|
||||
for (KoMorphData.Morpheme morpheme : morphemes) {
|
||||
if (hasSinglePOS == false) {
|
||||
buffer.put((byte) morpheme.posTag.ordinal());
|
||||
buffer.put((byte) morpheme.posTag().ordinal());
|
||||
}
|
||||
if (posType != POS.Type.INFLECT) {
|
||||
buffer.put((byte) morpheme.surfaceForm.length());
|
||||
compoundOffset += morpheme.surfaceForm.length();
|
||||
buffer.put((byte) morpheme.surfaceForm().length());
|
||||
compoundOffset += morpheme.surfaceForm().length();
|
||||
} else {
|
||||
writeString(morpheme.surfaceForm);
|
||||
writeString(morpheme.surfaceForm());
|
||||
}
|
||||
assert compoundOffset <= entry[0].length() : Arrays.toString(entry);
|
||||
}
|
||||
|
|
|
@ -86,11 +86,11 @@ public class PartOfSpeechAttributeImpl extends AttributeImpl implements PartOfSp
|
|||
builder.append("+");
|
||||
}
|
||||
builder
|
||||
.append(morpheme.surfaceForm)
|
||||
.append(morpheme.surfaceForm())
|
||||
.append('/')
|
||||
.append(morpheme.posTag.name())
|
||||
.append(morpheme.posTag().name())
|
||||
.append('(')
|
||||
.append(morpheme.posTag.description())
|
||||
.append(morpheme.posTag().description())
|
||||
.append(')');
|
||||
}
|
||||
return builder.toString();
|
||||
|
|
|
@ -170,14 +170,14 @@ public class TestTokenInfoDictionary extends LuceneTestCase {
|
|||
if (decompound != null) {
|
||||
int offset = 0;
|
||||
for (KoMorphData.Morpheme morph : decompound) {
|
||||
assertTrue(UnicodeUtil.validUTF16String(morph.surfaceForm));
|
||||
assertFalse(morph.surfaceForm.isEmpty());
|
||||
assertEquals(morph.surfaceForm.trim(), morph.surfaceForm);
|
||||
assertTrue(UnicodeUtil.validUTF16String(morph.surfaceForm()));
|
||||
assertFalse(morph.surfaceForm().isEmpty());
|
||||
assertEquals(morph.surfaceForm().trim(), morph.surfaceForm());
|
||||
if (type != POS.Type.INFLECT) {
|
||||
assertEquals(
|
||||
morph.surfaceForm,
|
||||
surfaceForm.substring(offset, offset + morph.surfaceForm.length()));
|
||||
offset += morph.surfaceForm.length();
|
||||
morph.surfaceForm(),
|
||||
surfaceForm.substring(offset, offset + morph.surfaceForm().length()));
|
||||
offset += morph.surfaceForm().length();
|
||||
}
|
||||
}
|
||||
assertTrue(offset <= surfaceForm.length());
|
||||
|
|
|
@ -43,10 +43,10 @@ public class TestUserDictionary extends LuceneTestCase {
|
|||
dictionary.getMorphAttributes().getMorphemes(wordIds.get(1), sArray, 0, s.length());
|
||||
assertNotNull(decompound);
|
||||
assertEquals(2, decompound.length);
|
||||
assertEquals(decompound[0].posTag, POS.Tag.NNG);
|
||||
assertEquals(decompound[0].surfaceForm, "세종");
|
||||
assertEquals(decompound[1].posTag, POS.Tag.NNG);
|
||||
assertEquals(decompound[1].surfaceForm, "시");
|
||||
assertEquals(decompound[0].posTag(), POS.Tag.NNG);
|
||||
assertEquals(decompound[0].surfaceForm(), "세종");
|
||||
assertEquals(decompound[1].posTag(), POS.Tag.NNG);
|
||||
assertEquals(decompound[1].surfaceForm(), "시");
|
||||
|
||||
s = "c++";
|
||||
sArray = s.toCharArray();
|
||||
|
|
|
@ -103,19 +103,20 @@ final class ForUtil {
|
|||
for (int bpv = 1; bpv <= 32; ++bpv) {
|
||||
final FormatAndBits formatAndBits =
|
||||
PackedInts.fastestFormatAndBits(BLOCK_SIZE, bpv, acceptableOverheadRatio);
|
||||
assert formatAndBits.format.isSupported(formatAndBits.bitsPerValue);
|
||||
assert formatAndBits.bitsPerValue <= 32;
|
||||
assert formatAndBits.format().isSupported(formatAndBits.bitsPerValue());
|
||||
assert formatAndBits.bitsPerValue() <= 32;
|
||||
encodedSizes[bpv] =
|
||||
encodedSize(formatAndBits.format, PackedInts.VERSION_CURRENT, formatAndBits.bitsPerValue);
|
||||
encodedSize(
|
||||
formatAndBits.format(), PackedInts.VERSION_CURRENT, formatAndBits.bitsPerValue());
|
||||
encoders[bpv] =
|
||||
PackedInts.getEncoder(
|
||||
formatAndBits.format, PackedInts.VERSION_CURRENT, formatAndBits.bitsPerValue);
|
||||
formatAndBits.format(), PackedInts.VERSION_CURRENT, formatAndBits.bitsPerValue());
|
||||
decoders[bpv] =
|
||||
PackedInts.getDecoder(
|
||||
formatAndBits.format, PackedInts.VERSION_CURRENT, formatAndBits.bitsPerValue);
|
||||
formatAndBits.format(), PackedInts.VERSION_CURRENT, formatAndBits.bitsPerValue());
|
||||
iterations[bpv] = computeIterations(decoders[bpv]);
|
||||
|
||||
out.writeVInt(formatAndBits.format.getId() << 5 | (formatAndBits.bitsPerValue - 1));
|
||||
out.writeVInt(formatAndBits.format().getId() << 5 | (formatAndBits.bitsPerValue() - 1));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1931,7 +1931,7 @@ public class BKDWriter60 implements Closeable {
|
|||
private void computePackedValueBounds(
|
||||
BKDRadixSelector.PathSlice slice, byte[] minPackedValue, byte[] maxPackedValue)
|
||||
throws IOException {
|
||||
try (PointReader reader = slice.writer.getReader(slice.start, slice.count)) {
|
||||
try (PointReader reader = slice.writer().getReader(slice.start(), slice.count())) {
|
||||
if (reader.next() == false) {
|
||||
return;
|
||||
}
|
||||
|
@ -1995,16 +1995,16 @@ public class BKDWriter60 implements Closeable {
|
|||
// least number of unique bytes at commonPrefixLengths[dim], which makes compression more
|
||||
// efficient
|
||||
HeapPointWriter heapSource;
|
||||
if (points.writer instanceof HeapPointWriter == false) {
|
||||
if (points.writer() instanceof HeapPointWriter == false) {
|
||||
// Adversarial cases can cause this, e.g. merging big segments with most of the points
|
||||
// deleted
|
||||
heapSource = switchToHeap(points.writer);
|
||||
heapSource = switchToHeap(points.writer());
|
||||
} else {
|
||||
heapSource = (HeapPointWriter) points.writer;
|
||||
heapSource = (HeapPointWriter) points.writer();
|
||||
}
|
||||
|
||||
int from = Math.toIntExact(points.start);
|
||||
int to = Math.toIntExact(points.start + points.count);
|
||||
int from = Math.toIntExact(points.start());
|
||||
int to = Math.toIntExact(points.start() + points.count());
|
||||
// we store common prefix on scratch1
|
||||
computeCommonPrefixLength(heapSource, scratch1, from, to);
|
||||
|
||||
|
@ -2107,8 +2107,8 @@ public class BKDWriter60 implements Closeable {
|
|||
: "nodeID=" + nodeID + " splitValues.length=" + splitPackedValues.length;
|
||||
|
||||
// How many points will be in the left tree:
|
||||
long rightCount = points.count / 2;
|
||||
long leftCount = points.count - rightCount;
|
||||
long rightCount = points.count() / 2;
|
||||
long leftCount = points.count() - rightCount;
|
||||
|
||||
BKDRadixSelector.PathSlice[] slices = new BKDRadixSelector.PathSlice[2];
|
||||
|
||||
|
@ -2128,9 +2128,9 @@ public class BKDWriter60 implements Closeable {
|
|||
radixSelector.select(
|
||||
points,
|
||||
slices,
|
||||
points.start,
|
||||
points.start + points.count,
|
||||
points.start + leftCount,
|
||||
points.start(),
|
||||
points.start() + points.count(),
|
||||
points.start() + leftCount,
|
||||
splitDim,
|
||||
commonPrefixLen);
|
||||
|
||||
|
|
|
@ -72,7 +72,7 @@ public class TestIndexSortBackwardsCompatibility extends BackwardsCompatibilityT
|
|||
final Sort sort;
|
||||
try (DirectoryReader reader = DirectoryReader.open(directory)) {
|
||||
assertEquals(1, reader.leaves().size());
|
||||
sort = reader.leaves().get(0).reader().getMetaData().getSort();
|
||||
sort = reader.leaves().get(0).reader().getMetaData().sort();
|
||||
assertNotNull(sort);
|
||||
searchExampleIndex(reader);
|
||||
}
|
||||
|
@ -140,7 +140,7 @@ public class TestIndexSortBackwardsCompatibility extends BackwardsCompatibilityT
|
|||
public void testSortedIndex() throws Exception {
|
||||
try (DirectoryReader reader = DirectoryReader.open(directory)) {
|
||||
assertEquals(1, reader.leaves().size());
|
||||
Sort sort = reader.leaves().get(0).reader().getMetaData().getSort();
|
||||
Sort sort = reader.leaves().get(0).reader().getMetaData().sort();
|
||||
assertNotNull(sort);
|
||||
assertEquals("<long: \"dateDV\">!", sort.toString());
|
||||
// This will confirm the docs are really sorted
|
||||
|
|
|
@ -151,13 +151,13 @@ public class BM25NBClassifier implements Classifier<BytesRef> {
|
|||
if (!assignedClasses.isEmpty()) {
|
||||
Collections.sort(assignedClasses);
|
||||
// this is a negative number closest to 0 = a
|
||||
double smax = assignedClasses.get(0).getScore();
|
||||
double smax = assignedClasses.get(0).score();
|
||||
|
||||
double sumLog = 0;
|
||||
// log(sum(exp(x_n-a)))
|
||||
for (ClassificationResult<BytesRef> cr : assignedClasses) {
|
||||
// getScore-smax <=0 (both negative, smax is the smallest abs()
|
||||
sumLog += Math.exp(cr.getScore() - smax);
|
||||
sumLog += Math.exp(cr.score() - smax);
|
||||
}
|
||||
// loga=a+log(sum(exp(x_n-a))) = log(sum(exp(x_n)))
|
||||
double loga = smax;
|
||||
|
@ -165,8 +165,8 @@ public class BM25NBClassifier implements Classifier<BytesRef> {
|
|||
|
||||
// 1/sum*x = exp(log(x))*1/sum = exp(log(x)-log(sum))
|
||||
for (ClassificationResult<BytesRef> cr : assignedClasses) {
|
||||
double scoreDiff = cr.getScore() - loga;
|
||||
returnList.add(new ClassificationResult<>(cr.getAssignedClass(), Math.exp(scoreDiff)));
|
||||
double scoreDiff = cr.score() - loga;
|
||||
returnList.add(new ClassificationResult<>(cr.assignedClass(), Math.exp(scoreDiff)));
|
||||
}
|
||||
}
|
||||
return returnList;
|
||||
|
|
|
@ -148,7 +148,7 @@ public class BooleanPerceptronClassifier implements Classifier<Boolean> {
|
|||
if (textField != null && classField != null) {
|
||||
// assign class to the doc
|
||||
ClassificationResult<Boolean> classificationResult = assignClass(textField.stringValue());
|
||||
Boolean assignedClass = classificationResult.getAssignedClass();
|
||||
Boolean assignedClass = classificationResult.assignedClass();
|
||||
|
||||
Boolean correctClass = Boolean.valueOf(classField.stringValue());
|
||||
double modifier = Math.signum(correctClass.compareTo(assignedClass));
|
||||
|
|
|
@ -126,7 +126,7 @@ public class CachingNaiveBayesClassifier extends SimpleNaiveBayesClassifier {
|
|||
int removeIdx = -1;
|
||||
int i = 0;
|
||||
for (ClassificationResult<BytesRef> cr : ret) {
|
||||
if (cr.getAssignedClass().equals(cclass)) {
|
||||
if (cr.assignedClass().equals(cclass)) {
|
||||
removeIdx = i;
|
||||
break;
|
||||
}
|
||||
|
@ -137,7 +137,7 @@ public class CachingNaiveBayesClassifier extends SimpleNaiveBayesClassifier {
|
|||
ClassificationResult<BytesRef> toRemove = ret.get(removeIdx);
|
||||
ret.add(
|
||||
new ClassificationResult<>(
|
||||
toRemove.getAssignedClass(), toRemove.getScore() + Math.log(wordProbability)));
|
||||
toRemove.assignedClass(), toRemove.score() + Math.log(wordProbability)));
|
||||
ret.remove(removeIdx);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,44 +20,15 @@ package org.apache.lucene.classification;
|
|||
* The result of a call to {@link Classifier#assignClass(String)} holding an assigned class of type
|
||||
* <code>T</code> and a score.
|
||||
*
|
||||
* @param assignedClass the class <code>T</code> assigned by a {@link Classifier}
|
||||
* @param score score the score for the assignedClass as a <code>double</code>
|
||||
* @lucene.experimental
|
||||
*/
|
||||
public class ClassificationResult<T> implements Comparable<ClassificationResult<T>> {
|
||||
|
||||
private final T assignedClass;
|
||||
private final double score;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param assignedClass the class <code>T</code> assigned by a {@link Classifier}
|
||||
* @param score the score for the assignedClass as a <code>double</code>
|
||||
*/
|
||||
public ClassificationResult(T assignedClass, double score) {
|
||||
this.assignedClass = assignedClass;
|
||||
this.score = score;
|
||||
}
|
||||
|
||||
/**
|
||||
* retrieve the result class
|
||||
*
|
||||
* @return a <code>T</code> representing an assigned class
|
||||
*/
|
||||
public T getAssignedClass() {
|
||||
return assignedClass;
|
||||
}
|
||||
|
||||
/**
|
||||
* retrieve the result score
|
||||
*
|
||||
* @return a <code>double</code> representing a result score
|
||||
*/
|
||||
public double getScore() {
|
||||
return score;
|
||||
}
|
||||
public record ClassificationResult<T>(T assignedClass, double score)
|
||||
implements Comparable<ClassificationResult<T>> {
|
||||
|
||||
@Override
|
||||
public int compareTo(ClassificationResult<T> o) {
|
||||
return Double.compare(o.getScore(), this.getScore());
|
||||
return Double.compare(o.score(), this.score());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -108,9 +108,9 @@ public class KNearestFuzzyClassifier implements Classifier<BytesRef> {
|
|||
ClassificationResult<BytesRef> assignedClass = null;
|
||||
double maxscore = -Double.MAX_VALUE;
|
||||
for (ClassificationResult<BytesRef> cl : assignedClasses) {
|
||||
if (cl.getScore() > maxscore) {
|
||||
if (cl.score() > maxscore) {
|
||||
assignedClass = cl;
|
||||
maxscore = cl.getScore();
|
||||
maxscore = cl.score();
|
||||
}
|
||||
}
|
||||
return assignedClass;
|
||||
|
@ -193,7 +193,7 @@ public class KNearestFuzzyClassifier implements Classifier<BytesRef> {
|
|||
if (sumdoc < k) {
|
||||
for (ClassificationResult<BytesRef> cr : temporaryList) {
|
||||
returnList.add(
|
||||
new ClassificationResult<>(cr.getAssignedClass(), cr.getScore() * k / (double) sumdoc));
|
||||
new ClassificationResult<>(cr.assignedClass(), cr.score() * k / (double) sumdoc));
|
||||
}
|
||||
} else {
|
||||
returnList = temporaryList;
|
||||
|
|
|
@ -129,9 +129,9 @@ public class KNearestNeighborClassifier implements Classifier<BytesRef> {
|
|||
ClassificationResult<BytesRef> assignedClass = null;
|
||||
double maxscore = -Double.MAX_VALUE;
|
||||
for (ClassificationResult<BytesRef> cl : assignedClasses) {
|
||||
if (cl.getScore() > maxscore) {
|
||||
if (cl.score() > maxscore) {
|
||||
assignedClass = cl;
|
||||
maxscore = cl.getScore();
|
||||
maxscore = cl.score();
|
||||
}
|
||||
}
|
||||
return assignedClass;
|
||||
|
@ -229,7 +229,7 @@ public class KNearestNeighborClassifier implements Classifier<BytesRef> {
|
|||
if (sumdoc < k) {
|
||||
for (ClassificationResult<BytesRef> cr : temporaryList) {
|
||||
returnList.add(
|
||||
new ClassificationResult<>(cr.getAssignedClass(), cr.getScore() * k / (double) sumdoc));
|
||||
new ClassificationResult<>(cr.assignedClass(), cr.score() * k / (double) sumdoc));
|
||||
}
|
||||
} else {
|
||||
returnList = temporaryList;
|
||||
|
|
|
@ -105,9 +105,9 @@ public class SimpleNaiveBayesClassifier implements Classifier<BytesRef> {
|
|||
ClassificationResult<BytesRef> assignedClass = null;
|
||||
double maxscore = -Double.MAX_VALUE;
|
||||
for (ClassificationResult<BytesRef> c : assignedClasses) {
|
||||
if (c.getScore() > maxscore) {
|
||||
if (c.score() > maxscore) {
|
||||
assignedClass = c;
|
||||
maxscore = c.getScore();
|
||||
maxscore = c.score();
|
||||
}
|
||||
}
|
||||
return assignedClass;
|
||||
|
@ -297,13 +297,13 @@ public class SimpleNaiveBayesClassifier implements Classifier<BytesRef> {
|
|||
if (!assignedClasses.isEmpty()) {
|
||||
Collections.sort(assignedClasses);
|
||||
// this is a negative number closest to 0 = a
|
||||
double smax = assignedClasses.get(0).getScore();
|
||||
double smax = assignedClasses.get(0).score();
|
||||
|
||||
double sumLog = 0;
|
||||
// log(sum(exp(x_n-a)))
|
||||
for (ClassificationResult<BytesRef> cr : assignedClasses) {
|
||||
// getScore-smax <=0 (both negative, smax is the smallest abs()
|
||||
sumLog += Math.exp(cr.getScore() - smax);
|
||||
sumLog += Math.exp(cr.score() - smax);
|
||||
}
|
||||
// loga=a+log(sum(exp(x_n-a))) = log(sum(exp(x_n)))
|
||||
double loga = smax;
|
||||
|
@ -311,8 +311,8 @@ public class SimpleNaiveBayesClassifier implements Classifier<BytesRef> {
|
|||
|
||||
// 1/sum*x = exp(log(x))*1/sum = exp(log(x)-log(sum))
|
||||
for (ClassificationResult<BytesRef> cr : assignedClasses) {
|
||||
double scoreDiff = cr.getScore() - loga;
|
||||
returnList.add(new ClassificationResult<>(cr.getAssignedClass(), Math.exp(scoreDiff)));
|
||||
double scoreDiff = cr.score() - loga;
|
||||
returnList.add(new ClassificationResult<>(cr.assignedClass(), Math.exp(scoreDiff)));
|
||||
}
|
||||
}
|
||||
return returnList;
|
||||
|
|
|
@ -80,9 +80,9 @@ public class SimpleNaiveBayesDocumentClassifier extends SimpleNaiveBayesClassifi
|
|||
ClassificationResult<BytesRef> assignedClass = null;
|
||||
double maxscore = -Double.MAX_VALUE;
|
||||
for (ClassificationResult<BytesRef> c : assignedClasses) {
|
||||
if (c.getScore() > maxscore) {
|
||||
if (c.score() > maxscore) {
|
||||
assignedClass = c;
|
||||
maxscore = c.getScore();
|
||||
maxscore = c.score();
|
||||
}
|
||||
}
|
||||
return assignedClass;
|
||||
|
|
|
@ -107,7 +107,7 @@ public class ConfusionMatrixGenerator {
|
|||
time += end - start;
|
||||
|
||||
if (result != null) {
|
||||
T assignedClass = result.getAssignedClass();
|
||||
T assignedClass = result.assignedClass();
|
||||
if (assignedClass != null) {
|
||||
counter++;
|
||||
String classified =
|
||||
|
|
|
@ -138,13 +138,13 @@ public class DatasetSplitter {
|
|||
// iterate over existing documents
|
||||
StoredFields storedFields = originalIndex.storedFields();
|
||||
for (GroupDocs<Object> group : topGroups.groups) {
|
||||
assert group.totalHits.relation == TotalHits.Relation.EQUAL_TO;
|
||||
long totalHits = group.totalHits.value;
|
||||
assert group.totalHits().relation == TotalHits.Relation.EQUAL_TO;
|
||||
long totalHits = group.totalHits().value;
|
||||
double testSize = totalHits * testRatio;
|
||||
int tc = 0;
|
||||
double cvSize = totalHits * crossValidationRatio;
|
||||
int cvc = 0;
|
||||
for (ScoreDoc scoreDoc : group.scoreDocs) {
|
||||
for (ScoreDoc scoreDoc : group.scoreDocs()) {
|
||||
|
||||
// create a new document for indexing
|
||||
Document doc = createNewDoc(storedFields, ft, scoreDoc, fieldNames);
|
||||
|
|
|
@ -91,7 +91,7 @@ public abstract class ClassificationTestBase<T> extends LuceneTestCase {
|
|||
Classifier<T> classifier, String inputDoc, T expectedResult) throws Exception {
|
||||
ClassificationResult<T> classificationResult = classifier.assignClass(inputDoc);
|
||||
assertNotNull(classificationResult);
|
||||
T assignedClass = classificationResult.getAssignedClass();
|
||||
T assignedClass = classificationResult.assignedClass();
|
||||
assertNotNull(assignedClass);
|
||||
assertEquals(
|
||||
"got an assigned class of " + assignedClass,
|
||||
|
@ -101,7 +101,7 @@ public abstract class ClassificationTestBase<T> extends LuceneTestCase {
|
|||
assignedClass instanceof BytesRef
|
||||
? ((BytesRef) assignedClass).utf8ToString()
|
||||
: assignedClass);
|
||||
double score = classificationResult.getScore();
|
||||
double score = classificationResult.score();
|
||||
assertTrue("score should be between 0 and 1, got:" + score, score <= 1 && score >= 0);
|
||||
return classificationResult;
|
||||
}
|
||||
|
@ -130,18 +130,17 @@ public abstract class ClassificationTestBase<T> extends LuceneTestCase {
|
|||
getSampleIndex(analyzer);
|
||||
|
||||
ClassificationResult<T> classificationResult = classifier.assignClass(inputDoc);
|
||||
assertNotNull(classificationResult.getAssignedClass());
|
||||
assertNotNull(classificationResult.assignedClass());
|
||||
assertEquals(
|
||||
"got an assigned class of " + classificationResult.getAssignedClass(),
|
||||
"got an assigned class of " + classificationResult.assignedClass(),
|
||||
expectedResult,
|
||||
classificationResult.getAssignedClass());
|
||||
double score = classificationResult.getScore();
|
||||
classificationResult.assignedClass());
|
||||
double score = classificationResult.score();
|
||||
assertTrue("score should be between 0 and 1, got: " + score, score <= 1 && score >= 0);
|
||||
updateSampleIndex();
|
||||
ClassificationResult<T> secondClassificationResult = classifier.assignClass(inputDoc);
|
||||
assertEquals(
|
||||
classificationResult.getAssignedClass(), secondClassificationResult.getAssignedClass());
|
||||
assertEquals(Double.valueOf(score), Double.valueOf(secondClassificationResult.getScore()));
|
||||
assertEquals(classificationResult.assignedClass(), secondClassificationResult.assignedClass());
|
||||
assertEquals(Double.valueOf(score), Double.valueOf(secondClassificationResult.score()));
|
||||
}
|
||||
|
||||
protected LeafReader getSampleIndex(Analyzer analyzer) throws IOException {
|
||||
|
|
|
@ -88,7 +88,7 @@ public class TestKNearestNeighborClassifier extends ClassificationTestBase<Bytes
|
|||
textFieldName),
|
||||
TECHNOLOGY_INPUT,
|
||||
TECHNOLOGY_RESULT);
|
||||
assertTrue(resultDS.getScore() != resultLMS.getScore());
|
||||
assertTrue(resultDS.score() != resultLMS.score());
|
||||
} finally {
|
||||
IOUtils.close(leafReader);
|
||||
}
|
||||
|
@ -113,7 +113,7 @@ public class TestKNearestNeighborClassifier extends ClassificationTestBase<Bytes
|
|||
leafReader, null, analyzer, null, 6, 1, 1, categoryFieldName, textFieldName);
|
||||
List<ClassificationResult<BytesRef>> classes =
|
||||
knnClassifier.getClasses(STRONG_TECHNOLOGY_INPUT);
|
||||
assertTrue(classes.get(0).getScore() > classes.get(1).getScore());
|
||||
assertTrue(classes.get(0).score() > classes.get(1).score());
|
||||
checkCorrectClassification(knnClassifier, STRONG_TECHNOLOGY_INPUT, TECHNOLOGY_RESULT);
|
||||
} finally {
|
||||
IOUtils.close(leafReader);
|
||||
|
@ -139,7 +139,7 @@ public class TestKNearestNeighborClassifier extends ClassificationTestBase<Bytes
|
|||
leafReader, null, analyzer, null, 3, 1, 1, categoryFieldName, textFieldName);
|
||||
List<ClassificationResult<BytesRef>> classes =
|
||||
knnClassifier.getClasses(SUPER_STRONG_TECHNOLOGY_INPUT);
|
||||
assertTrue(classes.get(0).getScore() > classes.get(1).getScore());
|
||||
assertTrue(classes.get(0).score() > classes.get(1).score());
|
||||
checkCorrectClassification(knnClassifier, SUPER_STRONG_TECHNOLOGY_INPUT, TECHNOLOGY_RESULT);
|
||||
} finally {
|
||||
IOUtils.close(leafReader);
|
||||
|
|
|
@ -58,12 +58,12 @@ public abstract class DocumentClassificationTestBase<T> extends ClassificationTe
|
|||
protected double checkCorrectDocumentClassification(
|
||||
DocumentClassifier<T> classifier, Document inputDoc, T expectedResult) throws Exception {
|
||||
ClassificationResult<T> classificationResult = classifier.assignClass(inputDoc);
|
||||
assertNotNull(classificationResult.getAssignedClass());
|
||||
assertNotNull(classificationResult.assignedClass());
|
||||
assertEquals(
|
||||
"got an assigned class of " + classificationResult.getAssignedClass(),
|
||||
"got an assigned class of " + classificationResult.assignedClass(),
|
||||
expectedResult,
|
||||
classificationResult.getAssignedClass());
|
||||
double score = classificationResult.getScore();
|
||||
classificationResult.assignedClass());
|
||||
double score = classificationResult.score();
|
||||
assertTrue("score should be between 0 and 1, got:" + score, score <= 1 && score >= 0);
|
||||
return score;
|
||||
}
|
||||
|
|
|
@ -69,28 +69,15 @@ public class BlockTermsWriter extends FieldsConsumer {
|
|||
private final TermsIndexWriterBase termsIndexWriter;
|
||||
private final int maxDoc;
|
||||
|
||||
private static class FieldMetaData {
|
||||
public final FieldInfo fieldInfo;
|
||||
public final long numTerms;
|
||||
public final long termsStartPointer;
|
||||
public final long sumTotalTermFreq;
|
||||
public final long sumDocFreq;
|
||||
public final int docCount;
|
||||
|
||||
public FieldMetaData(
|
||||
FieldInfo fieldInfo,
|
||||
long numTerms,
|
||||
long termsStartPointer,
|
||||
long sumTotalTermFreq,
|
||||
long sumDocFreq,
|
||||
int docCount) {
|
||||
private record FieldMetaData(
|
||||
FieldInfo fieldInfo,
|
||||
long numTerms,
|
||||
long termsStartPointer,
|
||||
long sumTotalTermFreq,
|
||||
long sumDocFreq,
|
||||
int docCount) {
|
||||
private FieldMetaData {
|
||||
assert numTerms > 0;
|
||||
this.fieldInfo = fieldInfo;
|
||||
this.termsStartPointer = termsStartPointer;
|
||||
this.numTerms = numTerms;
|
||||
this.sumTotalTermFreq = sumTotalTermFreq;
|
||||
this.sumDocFreq = sumDocFreq;
|
||||
this.docCount = docCount;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -127,7 +127,7 @@ public class VariableGapTermsIndexWriter extends TermsIndexWriterBase {
|
|||
|
||||
@Override
|
||||
public boolean isIndexTerm(BytesRef term, TermStats stats) {
|
||||
if (stats.docFreq >= docFreqThresh || count >= interval) {
|
||||
if (stats.docFreq() >= docFreqThresh || count >= interval) {
|
||||
count = 1;
|
||||
return true;
|
||||
} else {
|
||||
|
|
|
@ -34,19 +34,14 @@ final class FSTOrdsOutputs extends Outputs<FSTOrdsOutputs.Output> {
|
|||
|
||||
private static final BytesRef NO_BYTES = new BytesRef();
|
||||
|
||||
public static final class Output {
|
||||
public final BytesRef bytes;
|
||||
// Inclusive:
|
||||
public final long startOrd;
|
||||
// Inclusive:
|
||||
public final long endOrd;
|
||||
|
||||
public Output(BytesRef bytes, long startOrd, long endOrd) {
|
||||
/**
|
||||
* @param startOrd Inclusive:
|
||||
* @param endOrd Inclusive:
|
||||
*/
|
||||
public record Output(BytesRef bytes, long startOrd, long endOrd) {
|
||||
public Output {
|
||||
assert startOrd >= 0 : "startOrd=" + startOrd;
|
||||
assert endOrd >= 0 : "endOrd=" + endOrd;
|
||||
this.bytes = bytes;
|
||||
this.startOrd = startOrd;
|
||||
this.endOrd = endOrd;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -60,24 +55,6 @@ final class FSTOrdsOutputs extends Outputs<FSTOrdsOutputs.Output> {
|
|||
}
|
||||
return startOrd + " to " + x;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int hash = bytes.hashCode();
|
||||
hash = (int) (hash ^ startOrd);
|
||||
hash = (int) (hash ^ endOrd);
|
||||
return hash;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object _other) {
|
||||
if (_other instanceof Output) {
|
||||
Output other = (Output) _other;
|
||||
return bytes.equals(other.bytes) && startOrd == other.startOrd && endOrd == other.endOrd;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -139,38 +139,19 @@ public final class OrdsBlockTreeTermsWriter extends FieldsConsumer {
|
|||
final PostingsWriterBase postingsWriter;
|
||||
final FieldInfos fieldInfos;
|
||||
|
||||
private static class FieldMetaData {
|
||||
public final FieldInfo fieldInfo;
|
||||
public final Output rootCode;
|
||||
public final long numTerms;
|
||||
public final long indexStartFP;
|
||||
public final long sumTotalTermFreq;
|
||||
public final long sumDocFreq;
|
||||
public final int docCount;
|
||||
public final BytesRef minTerm;
|
||||
public final BytesRef maxTerm;
|
||||
|
||||
public FieldMetaData(
|
||||
FieldInfo fieldInfo,
|
||||
Output rootCode,
|
||||
long numTerms,
|
||||
long indexStartFP,
|
||||
long sumTotalTermFreq,
|
||||
long sumDocFreq,
|
||||
int docCount,
|
||||
BytesRef minTerm,
|
||||
BytesRef maxTerm) {
|
||||
private record FieldMetaData(
|
||||
FieldInfo fieldInfo,
|
||||
Output rootCode,
|
||||
long numTerms,
|
||||
long indexStartFP,
|
||||
long sumTotalTermFreq,
|
||||
long sumDocFreq,
|
||||
int docCount,
|
||||
BytesRef minTerm,
|
||||
BytesRef maxTerm) {
|
||||
private FieldMetaData {
|
||||
assert numTerms > 0;
|
||||
this.fieldInfo = fieldInfo;
|
||||
assert rootCode != null : "field=" + fieldInfo.name + " numTerms=" + numTerms;
|
||||
this.rootCode = rootCode;
|
||||
this.indexStartFP = indexStartFP;
|
||||
this.numTerms = numTerms;
|
||||
this.sumTotalTermFreq = sumTotalTermFreq;
|
||||
this.sumDocFreq = sumDocFreq;
|
||||
this.docCount = docCount;
|
||||
this.minTerm = minTerm;
|
||||
this.maxTerm = maxTerm;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -293,15 +274,7 @@ public final class OrdsBlockTreeTermsWriter extends FieldsConsumer {
|
|||
}
|
||||
}
|
||||
|
||||
private static final class SubIndex {
|
||||
public final FST<Output> index;
|
||||
public final long termOrdStart;
|
||||
|
||||
public SubIndex(FST<Output> index, long termOrdStart) {
|
||||
this.index = index;
|
||||
this.termOrdStart = termOrdStart;
|
||||
}
|
||||
}
|
||||
private record SubIndex(FST<Output> index, long termOrdStart) {}
|
||||
|
||||
private static final class PendingBlock extends PendingEntry {
|
||||
public final BytesRef prefix;
|
||||
|
@ -438,7 +411,7 @@ public final class OrdsBlockTreeTermsWriter extends FieldsConsumer {
|
|||
// long blockTermCount = output.endOrd - output.startOrd + 1;
|
||||
Output newOutput =
|
||||
FST_OUTPUTS.newOutput(
|
||||
output.bytes, termOrdOffset + output.startOrd, output.endOrd - termOrdOffset);
|
||||
output.bytes(), termOrdOffset + output.startOrd(), output.endOrd() - termOrdOffset);
|
||||
// System.out.println(" append sub=" + indexEnt.input + " output=" + indexEnt.output +
|
||||
// " termOrdOffset=" + termOrdOffset + " blockTermCount=" + blockTermCount + " newOutput="
|
||||
// + newOutput + " endOrd=" + (termOrdOffset+Long.MAX_VALUE-output.endOrd));
|
||||
|
@ -969,9 +942,11 @@ public final class OrdsBlockTreeTermsWriter extends FieldsConsumer {
|
|||
out.writeVInt(field.fieldInfo.number);
|
||||
assert field.numTerms > 0;
|
||||
out.writeVLong(field.numTerms);
|
||||
out.writeVInt(field.rootCode.bytes.length);
|
||||
out.writeVInt(field.rootCode.bytes().length);
|
||||
out.writeBytes(
|
||||
field.rootCode.bytes.bytes, field.rootCode.bytes.offset, field.rootCode.bytes.length);
|
||||
field.rootCode.bytes().bytes,
|
||||
field.rootCode.bytes().offset,
|
||||
field.rootCode.bytes().length);
|
||||
if (field.fieldInfo.getIndexOptions() != IndexOptions.DOCS) {
|
||||
out.writeVLong(field.sumTotalTermFreq);
|
||||
}
|
||||
|
|
|
@ -79,7 +79,8 @@ final class OrdsFieldReader extends Terms {
|
|||
// }
|
||||
|
||||
rootBlockFP =
|
||||
(new ByteArrayDataInput(rootCode.bytes.bytes, rootCode.bytes.offset, rootCode.bytes.length))
|
||||
(new ByteArrayDataInput(
|
||||
rootCode.bytes().bytes, rootCode.bytes().offset, rootCode.bytes().length))
|
||||
.readVLong()
|
||||
>>> OrdsBlockTreeTermsWriter.OUTPUT_FLAGS_NUM_BITS;
|
||||
|
||||
|
|
|
@ -142,8 +142,8 @@ final class OrdsIntersectTermsEnumFrame {
|
|||
// + frameIndexData + " trans=" + (transitions.length != 0 ? transitions[0] : "n/a" + " state="
|
||||
// + state));
|
||||
|
||||
if (output != null && output.bytes != null && transitionCount != 0) {
|
||||
BytesRef frameIndexData = output.bytes;
|
||||
if (output != null && output.bytes() != null && transitionCount != 0) {
|
||||
BytesRef frameIndexData = output.bytes();
|
||||
|
||||
// Floor frame
|
||||
if (floorData.length < frameIndexData.length) {
|
||||
|
|
|
@ -149,7 +149,8 @@ public final class OrdsSegmentTermsEnum extends BaseTermsEnum {
|
|||
// Pushes a frame we seek'd to
|
||||
OrdsSegmentTermsEnumFrame pushFrame(FST.Arc<Output> arc, Output frameData, int length)
|
||||
throws IOException {
|
||||
scratchReader.reset(frameData.bytes.bytes, frameData.bytes.offset, frameData.bytes.length);
|
||||
scratchReader.reset(
|
||||
frameData.bytes().bytes, frameData.bytes().offset, frameData.bytes().length);
|
||||
final long code = scratchReader.readVLong();
|
||||
final long fpSeek = code >>> OrdsBlockTreeTermsWriter.OUTPUT_FLAGS_NUM_BITS;
|
||||
// System.out.println(" fpSeek=" + fpSeek);
|
||||
|
@ -160,11 +161,11 @@ public final class OrdsSegmentTermsEnum extends BaseTermsEnum {
|
|||
|
||||
// Must setFloorData before pushFrame in case pushFrame tries to rewind:
|
||||
if (f.isFloor) {
|
||||
f.termOrdOrig = frameData.startOrd;
|
||||
f.setFloorData(scratchReader, frameData.bytes);
|
||||
f.termOrdOrig = frameData.startOrd();
|
||||
f.setFloorData(scratchReader, frameData.bytes());
|
||||
}
|
||||
|
||||
pushFrame(arc, fpSeek, length, frameData.startOrd);
|
||||
pushFrame(arc, fpSeek, length, frameData.startOrd());
|
||||
|
||||
return f;
|
||||
}
|
||||
|
@ -891,7 +892,7 @@ public final class OrdsSegmentTermsEnum extends BaseTermsEnum {
|
|||
} else if (isSeekFrame && !f.isFloor) {
|
||||
final ByteArrayDataInput reader =
|
||||
new ByteArrayDataInput(
|
||||
output.bytes.bytes, output.bytes.offset, output.bytes.length);
|
||||
output.bytes().bytes, output.bytes().offset, output.bytes().length);
|
||||
final long codeOrig = reader.readVLong();
|
||||
final long code =
|
||||
(f.fp << OrdsBlockTreeTermsWriter.OUTPUT_FLAGS_NUM_BITS)
|
||||
|
@ -1210,7 +1211,8 @@ public final class OrdsSegmentTermsEnum extends BaseTermsEnum {
|
|||
OrdsBlockTreeTermsWriter.FST_OUTPUTS.add(output, arc.nextFinalOutput());
|
||||
// System.out.println(" isFinal: " + finalOutput.startOrd + "-" +
|
||||
// (Long.MAX_VALUE-finalOutput.endOrd));
|
||||
if (targetOrd >= finalOutput.startOrd && targetOrd <= Long.MAX_VALUE - finalOutput.endOrd) {
|
||||
if (targetOrd >= finalOutput.startOrd()
|
||||
&& targetOrd <= Long.MAX_VALUE - finalOutput.endOrd()) {
|
||||
// Only one range should match across all arc leaving this node
|
||||
// assert bestOutput == null;
|
||||
bestOutput = finalOutput;
|
||||
|
@ -1247,9 +1249,9 @@ public final class OrdsSegmentTermsEnum extends BaseTermsEnum {
|
|||
}
|
||||
// System.out.println(" cycle mid=" + mid + " targetOrd=" + targetOrd + " output=" +
|
||||
// minArcOutput.startOrd + "-" + (Long.MAX_VALUE-minArcOutput.endOrd));
|
||||
if (targetOrd > Long.MAX_VALUE - minArcOutput.endOrd) {
|
||||
if (targetOrd > Long.MAX_VALUE - minArcOutput.endOrd()) {
|
||||
low = mid + 1;
|
||||
} else if (targetOrd < minArcOutput.startOrd) {
|
||||
} else if (targetOrd < minArcOutput.startOrd()) {
|
||||
high = mid - 1;
|
||||
} else {
|
||||
// System.out.println(" found!!");
|
||||
|
@ -1282,10 +1284,10 @@ public final class OrdsSegmentTermsEnum extends BaseTermsEnum {
|
|||
// this arc:
|
||||
final Output minArcOutput =
|
||||
OrdsBlockTreeTermsWriter.FST_OUTPUTS.add(output, arc.output());
|
||||
long endOrd = Long.MAX_VALUE - minArcOutput.endOrd;
|
||||
long endOrd = Long.MAX_VALUE - minArcOutput.endOrd();
|
||||
// System.out.println(" endOrd=" + endOrd + " targetOrd=" + targetOrd);
|
||||
|
||||
if (targetOrd >= minArcOutput.startOrd && targetOrd <= endOrd) {
|
||||
if (targetOrd >= minArcOutput.startOrd() && targetOrd <= endOrd) {
|
||||
// Recurse on this arc:
|
||||
output = minArcOutput;
|
||||
result.setIntAt(upto++, arc.label());
|
||||
|
|
|
@ -1124,16 +1124,16 @@ final class SimpleTextBKDWriter implements Closeable {
|
|||
// least number of unique bytes at commonPrefixLengths[dim], which makes compression more
|
||||
// efficient
|
||||
HeapPointWriter heapSource;
|
||||
if (points.writer instanceof HeapPointWriter == false) {
|
||||
if (points.writer() instanceof HeapPointWriter == false) {
|
||||
// Adversarial cases can cause this, e.g. merging big segments with most of the points
|
||||
// deleted
|
||||
heapSource = switchToHeap(points.writer);
|
||||
heapSource = switchToHeap(points.writer());
|
||||
} else {
|
||||
heapSource = (HeapPointWriter) points.writer;
|
||||
heapSource = (HeapPointWriter) points.writer();
|
||||
}
|
||||
|
||||
int from = Math.toIntExact(points.start);
|
||||
int to = Math.toIntExact(points.start + points.count);
|
||||
int from = Math.toIntExact(points.start());
|
||||
int to = Math.toIntExact(points.start() + points.count());
|
||||
|
||||
// we store common prefix on scratch1
|
||||
computeCommonPrefixLength(heapSource, scratch1);
|
||||
|
@ -1220,8 +1220,8 @@ final class SimpleTextBKDWriter implements Closeable {
|
|||
: "nodeID=" + nodeID + " splitValues.length=" + splitPackedValues.length;
|
||||
|
||||
// How many points will be in the left tree:
|
||||
long rightCount = points.count / 2;
|
||||
long leftCount = points.count - rightCount;
|
||||
long rightCount = points.count() / 2;
|
||||
long leftCount = points.count() - rightCount;
|
||||
|
||||
int commonPrefixLen =
|
||||
Arrays.mismatch(
|
||||
|
@ -1241,9 +1241,9 @@ final class SimpleTextBKDWriter implements Closeable {
|
|||
radixSelector.select(
|
||||
points,
|
||||
pathSlices,
|
||||
points.start,
|
||||
points.start + points.count,
|
||||
points.start + leftCount,
|
||||
points.start(),
|
||||
points.start() + points.count(),
|
||||
points.start() + leftCount,
|
||||
splitDim,
|
||||
commonPrefixLen);
|
||||
|
||||
|
|
|
@ -144,14 +144,7 @@ public class SimpleTextLiveDocsFormat extends LiveDocsFormat {
|
|||
}
|
||||
|
||||
// read-only
|
||||
static class SimpleTextBits implements Bits {
|
||||
final BitSet bits;
|
||||
final int size;
|
||||
|
||||
SimpleTextBits(BitSet bits, int size) {
|
||||
this.bits = bits;
|
||||
this.size = size;
|
||||
}
|
||||
record SimpleTextBits(BitSet bits, int size) implements Bits {
|
||||
|
||||
@Override
|
||||
public boolean get(int index) {
|
||||
|
|
|
@ -25,13 +25,4 @@ import org.apache.lucene.codecs.uniformsplit.FieldMetadata;
|
|||
*
|
||||
* @lucene.experimental
|
||||
*/
|
||||
public class FieldMetadataTermState {
|
||||
|
||||
public final FieldMetadata fieldMetadata;
|
||||
public final BlockTermState state;
|
||||
|
||||
public FieldMetadataTermState(FieldMetadata fieldMetadata, BlockTermState state) {
|
||||
this.fieldMetadata = fieldMetadata;
|
||||
this.state = state;
|
||||
}
|
||||
}
|
||||
public record FieldMetadataTermState(FieldMetadata fieldMetadata, BlockTermState state) {}
|
||||
|
|
|
@ -57,7 +57,7 @@ public class STBlockLine extends BlockLine {
|
|||
*/
|
||||
public void collectFields(Collection<FieldMetadata> collector) {
|
||||
for (FieldMetadataTermState fieldTermState : termStates) {
|
||||
collector.add(fieldTermState.fieldMetadata);
|
||||
collector.add(fieldTermState.fieldMetadata());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -82,13 +82,13 @@ public class STBlockLine extends BlockLine {
|
|||
assert size > 0 : "not valid block line with :" + size + " lines.";
|
||||
if (size == 1) {
|
||||
// When there is only 1 field, write its id as negative, followed by the field TermState.
|
||||
int fieldID = line.termStates.get(0).fieldMetadata.getFieldInfo().number;
|
||||
int fieldID = line.termStates.get(0).fieldMetadata().getFieldInfo().number;
|
||||
termStatesOutput.writeZInt(-fieldID);
|
||||
fieldMetadataTermState = line.termStates.get(0);
|
||||
encoder.writeTermState(
|
||||
termStatesOutput,
|
||||
fieldMetadataTermState.fieldMetadata.getFieldInfo(),
|
||||
fieldMetadataTermState.state);
|
||||
fieldMetadataTermState.fieldMetadata().getFieldInfo(),
|
||||
fieldMetadataTermState.state());
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -96,15 +96,15 @@ public class STBlockLine extends BlockLine {
|
|||
// First iteration writes the fields ids.
|
||||
for (int i = 0; i < size; i++) {
|
||||
fieldMetadataTermState = line.termStates.get(i);
|
||||
termStatesOutput.writeVInt(fieldMetadataTermState.fieldMetadata.getFieldInfo().number);
|
||||
termStatesOutput.writeVInt(fieldMetadataTermState.fieldMetadata().getFieldInfo().number);
|
||||
}
|
||||
// Second iteration writes the corresponding field TermStates.
|
||||
for (int i = 0; i < size; i++) {
|
||||
fieldMetadataTermState = line.termStates.get(i);
|
||||
encoder.writeTermState(
|
||||
termStatesOutput,
|
||||
fieldMetadataTermState.fieldMetadata.getFieldInfo(),
|
||||
fieldMetadataTermState.state);
|
||||
fieldMetadataTermState.fieldMetadata().getFieldInfo(),
|
||||
fieldMetadataTermState.state());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -225,15 +225,7 @@ public class TestSTBlockReader extends LuceneTestCase {
|
|||
return lines;
|
||||
}
|
||||
|
||||
private static class BlockLineDefinition {
|
||||
final TermBytes termBytes;
|
||||
final List<String> fields;
|
||||
|
||||
BlockLineDefinition(TermBytes termBytes, List<String> fields) {
|
||||
this.termBytes = termBytes;
|
||||
this.fields = fields;
|
||||
}
|
||||
}
|
||||
private record BlockLineDefinition(TermBytes termBytes, List<String> fields) {}
|
||||
|
||||
private static class MockSTBlockLine extends STBlockLine {
|
||||
|
||||
|
|
|
@ -170,24 +170,8 @@ public class AutomatonToTokenStream {
|
|||
}
|
||||
|
||||
/** Edge between position nodes. These edges will be output as tokens in the TokenStream */
|
||||
private static class EdgeToken {
|
||||
public final int destination;
|
||||
public final int value;
|
||||
|
||||
public EdgeToken(int destination, int value) {
|
||||
this.destination = destination;
|
||||
this.value = value;
|
||||
}
|
||||
}
|
||||
private record EdgeToken(int destination, int value) {}
|
||||
|
||||
/** Node that contains original node id and position in TokenStream */
|
||||
private static class RemapNode {
|
||||
public final int id;
|
||||
public final int pos;
|
||||
|
||||
public RemapNode(int id, int pos) {
|
||||
this.id = id;
|
||||
this.pos = pos;
|
||||
}
|
||||
}
|
||||
private record RemapNode(int id, int pos) {}
|
||||
}
|
||||
|
|
|
@ -16,24 +16,10 @@
|
|||
*/
|
||||
package org.apache.lucene.codecs;
|
||||
|
||||
import org.apache.lucene.index.TermsEnum; // javadocs
|
||||
|
||||
/**
|
||||
* Holder for per-term statistics.
|
||||
*
|
||||
* @see TermsEnum#docFreq
|
||||
* @see TermsEnum#totalTermFreq
|
||||
* @param docFreq How many documents have at least one occurrence of this term.
|
||||
* @param totalTermFreq Total number of times this term occurs across all documents in the field.
|
||||
*/
|
||||
public class TermStats {
|
||||
/** How many documents have at least one occurrence of this term. */
|
||||
public final int docFreq;
|
||||
|
||||
/** Total number of times this term occurs across all documents in the field. */
|
||||
public final long totalTermFreq;
|
||||
|
||||
/** Sole constructor. */
|
||||
public TermStats(int docFreq, long totalTermFreq) {
|
||||
this.docFreq = docFreq;
|
||||
this.totalTermFreq = totalTermFreq;
|
||||
}
|
||||
}
|
||||
public record TermStats(int docFreq, long totalTermFreq) {}
|
||||
|
|
|
@ -104,15 +104,7 @@ public final class Lucene90CompoundFormat extends CompoundFormat {
|
|||
}
|
||||
}
|
||||
|
||||
private static class SizedFile {
|
||||
private final String name;
|
||||
private final long length;
|
||||
|
||||
private SizedFile(String name, long length) {
|
||||
this.name = name;
|
||||
this.length = length;
|
||||
}
|
||||
}
|
||||
private record SizedFile(String name, long length) {}
|
||||
|
||||
private static class SizedFileQueue extends PriorityQueue<SizedFile> {
|
||||
SizedFileQueue(int maxSize) {
|
||||
|
|
|
@ -325,17 +325,7 @@ public final class Lucene90CompressingTermVectorsReader extends TermVectorsReade
|
|||
return blockState.docBase <= docID && docID < blockState.docBase + blockState.chunkDocs;
|
||||
}
|
||||
|
||||
private static class BlockState {
|
||||
final long startPointer;
|
||||
final int docBase;
|
||||
final int chunkDocs;
|
||||
|
||||
BlockState(long startPointer, int docBase, int chunkDocs) {
|
||||
this.startPointer = startPointer;
|
||||
this.docBase = docBase;
|
||||
this.chunkDocs = chunkDocs;
|
||||
}
|
||||
}
|
||||
private record BlockState(long startPointer, int docBase, int chunkDocs) {}
|
||||
|
||||
@Override
|
||||
public Fields get(int doc) throws IOException {
|
||||
|
|
|
@ -299,14 +299,7 @@ public abstract class PerFieldKnnVectorsFormat extends KnnVectorsFormat {
|
|||
}
|
||||
}
|
||||
|
||||
private static class WriterAndSuffix implements Closeable {
|
||||
final KnnVectorsWriter writer;
|
||||
final int suffix;
|
||||
|
||||
WriterAndSuffix(KnnVectorsWriter writer, int suffix) {
|
||||
this.writer = writer;
|
||||
this.suffix = suffix;
|
||||
}
|
||||
private record WriterAndSuffix(KnnVectorsWriter writer, int suffix) implements Closeable {
|
||||
|
||||
@Override
|
||||
public void close() throws IOException {
|
||||
|
|
|
@ -35,30 +35,18 @@ import org.apache.lucene.util.SloppyMath;
|
|||
/** KNN search on top of 2D lat/lon indexed points. */
|
||||
class NearestNeighbor {
|
||||
|
||||
static class Cell implements Comparable<Cell> {
|
||||
final int readerIndex;
|
||||
final byte[] minPacked;
|
||||
final byte[] maxPacked;
|
||||
final PointTree index;
|
||||
|
||||
/**
|
||||
* The closest distance from a point in this cell to the query point, computed as a sort key
|
||||
* through {@link SloppyMath#haversinSortKey}. Note that this is an approximation to the closest
|
||||
* distance, and there could be a point in the cell that is closer.
|
||||
*/
|
||||
final double distanceSortKey;
|
||||
|
||||
public Cell(
|
||||
PointTree index,
|
||||
int readerIndex,
|
||||
byte[] minPacked,
|
||||
byte[] maxPacked,
|
||||
double distanceSortKey) {
|
||||
this.index = index;
|
||||
this.readerIndex = readerIndex;
|
||||
this.minPacked = minPacked.clone();
|
||||
this.maxPacked = maxPacked.clone();
|
||||
this.distanceSortKey = distanceSortKey;
|
||||
/**
|
||||
* @param distanceSortKey The closest distance from a point in this cell to the query point,
|
||||
* computed as a sort key through {@link SloppyMath#haversinSortKey}. Note that this is an
|
||||
* approximation to the closest distance, and there could be a point in the cell that is
|
||||
* closer.
|
||||
*/
|
||||
record Cell(
|
||||
PointTree index, int readerIndex, byte[] minPacked, byte[] maxPacked, double distanceSortKey)
|
||||
implements Comparable<Cell> {
|
||||
Cell {
|
||||
minPacked = minPacked.clone();
|
||||
maxPacked = maxPacked.clone();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -194,7 +194,7 @@ final class SortedNumericDocValuesRangeQuery extends Query {
|
|||
if (skipper.docCount() != reader.maxDoc()) {
|
||||
return null;
|
||||
}
|
||||
final Sort indexSort = reader.getMetaData().getSort();
|
||||
final Sort indexSort = reader.getMetaData().sort();
|
||||
if (indexSort == null
|
||||
|| indexSort.getSort().length == 0
|
||||
|| indexSort.getSort()[0].getField().equals(field) == false) {
|
||||
|
|
|
@ -247,7 +247,7 @@ final class SortedSetDocValuesRangeQuery extends Query {
|
|||
if (skipper.docCount() != reader.maxDoc()) {
|
||||
return null;
|
||||
}
|
||||
final Sort indexSort = reader.getMetaData().getSort();
|
||||
final Sort indexSort = reader.getMetaData().sort();
|
||||
if (indexSort == null
|
||||
|| indexSort.getSort().length == 0
|
||||
|| indexSort.getSort()[0].getField().equals(field) == false) {
|
||||
|
|
|
@ -32,8 +32,8 @@ final class BitsSlice implements Bits {
|
|||
// start is inclusive; end is exclusive (length = end-start)
|
||||
public BitsSlice(Bits parent, ReaderSlice slice) {
|
||||
this.parent = parent;
|
||||
this.start = slice.start;
|
||||
this.length = slice.length;
|
||||
this.start = slice.start();
|
||||
this.length = slice.length();
|
||||
assert length >= 0 : "length=" + length;
|
||||
}
|
||||
|
||||
|
|
|
@ -114,19 +114,11 @@ final class BufferedUpdatesStream implements Accountable {
|
|||
return bytesUsed.get();
|
||||
}
|
||||
|
||||
static class ApplyDeletesResult {
|
||||
|
||||
// True if any actual deletes took place:
|
||||
final boolean anyDeletes;
|
||||
|
||||
// If non-null, contains segments that are 100% deleted
|
||||
final List<SegmentCommitInfo> allDeleted;
|
||||
|
||||
ApplyDeletesResult(boolean anyDeletes, List<SegmentCommitInfo> allDeleted) {
|
||||
this.anyDeletes = anyDeletes;
|
||||
this.allDeleted = allDeleted;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* @param anyDeletes True if any actual deletes took place:
|
||||
* @param allDeleted If non-null, contains segments that are 100% deleted
|
||||
*/
|
||||
record ApplyDeletesResult(boolean anyDeletes, List<SegmentCommitInfo> allDeleted) {}
|
||||
|
||||
/**
|
||||
* Waits for all in-flight packets, which are already being resolved concurrently by indexing
|
||||
|
|
|
@ -1188,10 +1188,10 @@ public final class CheckIndex implements Closeable {
|
|||
FieldInfos fieldInfos = reader.getFieldInfos();
|
||||
if (metaData.hasBlocks()
|
||||
&& fieldInfos.getParentField() == null
|
||||
&& metaData.getCreatedVersionMajor() >= Version.LUCENE_10_0_0.major) {
|
||||
&& metaData.createdVersionMajor() >= Version.LUCENE_10_0_0.major) {
|
||||
throw new IllegalStateException(
|
||||
"parent field is not set but the index has document blocks and was created with version: "
|
||||
+ metaData.getCreatedVersionMajor());
|
||||
+ metaData.createdVersionMajor());
|
||||
}
|
||||
final DocIdSetIterator iter;
|
||||
if (metaData.hasBlocks() && fieldInfos.getParentField() != null) {
|
||||
|
@ -3143,12 +3143,7 @@ public final class CheckIndex implements Closeable {
|
|||
}
|
||||
}
|
||||
|
||||
private static class ConstantRelationIntersectVisitor implements IntersectVisitor {
|
||||
private final Relation relation;
|
||||
|
||||
ConstantRelationIntersectVisitor(Relation relation) {
|
||||
this.relation = relation;
|
||||
}
|
||||
private record ConstantRelationIntersectVisitor(Relation relation) implements IntersectVisitor {
|
||||
|
||||
@Override
|
||||
public void visit(int docID) throws IOException {
|
||||
|
|
|
@ -3118,22 +3118,22 @@ public class IndexWriter
|
|||
|
||||
private void validateMergeReader(CodecReader leaf) {
|
||||
LeafMetaData segmentMeta = leaf.getMetaData();
|
||||
if (segmentInfos.getIndexCreatedVersionMajor() != segmentMeta.getCreatedVersionMajor()) {
|
||||
if (segmentInfos.getIndexCreatedVersionMajor() != segmentMeta.createdVersionMajor()) {
|
||||
throw new IllegalArgumentException(
|
||||
"Cannot merge a segment that has been created with major version "
|
||||
+ segmentMeta.getCreatedVersionMajor()
|
||||
+ segmentMeta.createdVersionMajor()
|
||||
+ " into this index which has been created by major version "
|
||||
+ segmentInfos.getIndexCreatedVersionMajor());
|
||||
}
|
||||
|
||||
if (segmentInfos.getIndexCreatedVersionMajor() >= 7 && segmentMeta.getMinVersion() == null) {
|
||||
if (segmentInfos.getIndexCreatedVersionMajor() >= 7 && segmentMeta.minVersion() == null) {
|
||||
throw new IllegalStateException(
|
||||
"Indexes created on or after Lucene 7 must record the created version major, but "
|
||||
+ leaf
|
||||
+ " hides it");
|
||||
}
|
||||
|
||||
Sort leafIndexSort = segmentMeta.getSort();
|
||||
Sort leafIndexSort = segmentMeta.sort();
|
||||
if (config.getIndexSort() != null
|
||||
&& (leafIndexSort == null
|
||||
|| isCongruentSort(config.getIndexSort(), leafIndexSort) == false)) {
|
||||
|
@ -6396,16 +6396,16 @@ public class IndexWriter
|
|||
deleter.decRef(delFiles);
|
||||
}
|
||||
|
||||
if (result.anyDeletes) {
|
||||
if (result.anyDeletes()) {
|
||||
maybeMerge.set(true);
|
||||
checkpoint();
|
||||
}
|
||||
|
||||
if (result.allDeleted != null) {
|
||||
if (result.allDeleted() != null) {
|
||||
if (infoStream.isEnabled("IW")) {
|
||||
infoStream.message("IW", "drop 100% deleted segments: " + segString(result.allDeleted));
|
||||
infoStream.message("IW", "drop 100% deleted segments: " + segString(result.allDeleted()));
|
||||
}
|
||||
for (SegmentCommitInfo info : result.allDeleted) {
|
||||
for (SegmentCommitInfo info : result.allDeleted()) {
|
||||
dropDeletedSegment(info);
|
||||
}
|
||||
checkpoint();
|
||||
|
@ -6532,12 +6532,7 @@ public class IndexWriter
|
|||
}
|
||||
}
|
||||
|
||||
private static class IndexWriterMergeSource implements MergeScheduler.MergeSource {
|
||||
private final IndexWriter writer;
|
||||
|
||||
private IndexWriterMergeSource(IndexWriter writer) {
|
||||
this.writer = writer;
|
||||
}
|
||||
private record IndexWriterMergeSource(IndexWriter writer) implements MergeScheduler.MergeSource {
|
||||
|
||||
@Override
|
||||
public MergePolicy.OneMerge getNextMerge() {
|
||||
|
|
|
@ -24,18 +24,29 @@ import org.apache.lucene.util.Version;
|
|||
/**
|
||||
* Provides read-only metadata about a leaf.
|
||||
*
|
||||
* @param createdVersionMajor the Lucene version that created this index. This can be used to
|
||||
* implement backward compatibility on top of the codec API. A return value of {@code 6}
|
||||
* indicates that the created version is unknown.
|
||||
* @param minVersion the minimum Lucene version that contributed documents to this index, or {@code
|
||||
* null} if this information is not available.
|
||||
* @param sort the order in which documents from this index are sorted, or {@code null} if documents
|
||||
* are in no particular order.
|
||||
* @param hasBlocks Returns <code>true</code> iff this index contains blocks created with {@link
|
||||
* IndexWriter#addDocument(Iterable)} or it's corresponding update methods with at least 2 or
|
||||
* more documents per call. Note: This property was not recorded before {@link
|
||||
* Version#LUCENE_9_9_0} this method will return false for all leaves written before {@link
|
||||
* Version#LUCENE_9_9_0}
|
||||
* @see IndexWriter#updateDocuments(Term, Iterable)
|
||||
* @see IndexWriter#updateDocuments(Query, Iterable)
|
||||
* @see IndexWriter#softUpdateDocuments(Term, Iterable, Field...)
|
||||
* @see IndexWriter#addDocuments(Iterable)
|
||||
* @lucene.experimental
|
||||
*/
|
||||
public final class LeafMetaData {
|
||||
|
||||
private final int createdVersionMajor;
|
||||
private final Version minVersion;
|
||||
private final Sort sort;
|
||||
private final boolean hasBlocks;
|
||||
public record LeafMetaData(
|
||||
int createdVersionMajor, Version minVersion, Sort sort, boolean hasBlocks) {
|
||||
|
||||
/** Expert: Sole constructor. Public for use by custom {@link LeafReader} impls. */
|
||||
public LeafMetaData(int createdVersionMajor, Version minVersion, Sort sort, boolean hasBlocks) {
|
||||
this.createdVersionMajor = createdVersionMajor;
|
||||
public LeafMetaData {
|
||||
if (createdVersionMajor > Version.LATEST.major) {
|
||||
throw new IllegalArgumentException(
|
||||
"createdVersionMajor is in the future: " + createdVersionMajor);
|
||||
|
@ -47,48 +58,5 @@ public final class LeafMetaData {
|
|||
if (createdVersionMajor >= 7 && minVersion == null) {
|
||||
throw new IllegalArgumentException("minVersion must be set when createdVersionMajor is >= 7");
|
||||
}
|
||||
this.minVersion = minVersion;
|
||||
this.sort = sort;
|
||||
this.hasBlocks = hasBlocks;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the Lucene version that created this index. This can be used to implement backward
|
||||
* compatibility on top of the codec API. A return value of {@code 6} indicates that the created
|
||||
* version is unknown.
|
||||
*/
|
||||
public int getCreatedVersionMajor() {
|
||||
return createdVersionMajor;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the minimum Lucene version that contributed documents to this index, or {@code null} if
|
||||
* this information is not available.
|
||||
*/
|
||||
public Version getMinVersion() {
|
||||
return minVersion;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the order in which documents from this index are sorted, or {@code null} if documents
|
||||
* are in no particular order.
|
||||
*/
|
||||
public Sort getSort() {
|
||||
return sort;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns <code>true</code> iff this index contains blocks created with {@link
|
||||
* IndexWriter#addDocument(Iterable)} or it's corresponding update methods with at least 2 or more
|
||||
* documents per call. Note: This property was not recorded before {@link Version#LUCENE_9_9_0}
|
||||
* this method will return false for all leaves written before {@link Version#LUCENE_9_9_0}
|
||||
*
|
||||
* @see IndexWriter#updateDocuments(Term, Iterable)
|
||||
* @see IndexWriter#updateDocuments(Query, Iterable)
|
||||
* @see IndexWriter#softUpdateDocuments(Term, Iterable, Field...)
|
||||
* @see IndexWriter#addDocuments(Iterable)
|
||||
*/
|
||||
public boolean hasBlocks() {
|
||||
return hasBlocks;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -474,14 +474,8 @@ public abstract class LogMergePolicy extends MergePolicy {
|
|||
return spec;
|
||||
}
|
||||
|
||||
private static class SegmentInfoAndLevel implements Comparable<SegmentInfoAndLevel> {
|
||||
final SegmentCommitInfo info;
|
||||
final float level;
|
||||
|
||||
public SegmentInfoAndLevel(SegmentCommitInfo info, float level) {
|
||||
this.info = info;
|
||||
this.level = level;
|
||||
}
|
||||
private record SegmentInfoAndLevel(SegmentCommitInfo info, float level)
|
||||
implements Comparable<SegmentInfoAndLevel> {
|
||||
|
||||
// Sorts largest to smallest
|
||||
@Override
|
||||
|
|
|
@ -68,7 +68,7 @@ final class MappingMultiPostingsEnum extends PostingsEnum {
|
|||
int count = postingsEnum.getNumSubs();
|
||||
subs.clear();
|
||||
for (int i = 0; i < count; i++) {
|
||||
MappingPostingsSub sub = allSubs[subsArray[i].slice.readerIndex];
|
||||
MappingPostingsSub sub = allSubs[subsArray[i].slice.readerIndex()];
|
||||
sub.postings = subsArray[i].postingsEnum;
|
||||
subs.add(sub);
|
||||
}
|
||||
|
|
|
@ -236,7 +236,7 @@ public class MergeState {
|
|||
return;
|
||||
}
|
||||
for (CodecReader leaf : readers) {
|
||||
Sort segmentSort = leaf.getMetaData().getSort();
|
||||
Sort segmentSort = leaf.getMetaData().sort();
|
||||
if (segmentSort == null || isCongruentSort(indexSort, segmentSort) == false) {
|
||||
throw new IllegalArgumentException(
|
||||
"index sort mismatch: merged segment has sort="
|
||||
|
|
|
@ -115,7 +115,7 @@ public final class MultiPostingsEnum extends PostingsEnum {
|
|||
} else {
|
||||
upto++;
|
||||
current = subs[upto].postingsEnum;
|
||||
currentBase = subs[upto].slice.start;
|
||||
currentBase = subs[upto].slice.start();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -129,7 +129,7 @@ public final class MultiPostingsEnum extends PostingsEnum {
|
|||
} else {
|
||||
upto++;
|
||||
current = subs[upto].postingsEnum;
|
||||
currentBase = subs[upto].slice.start;
|
||||
currentBase = subs[upto].slice.start();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -70,10 +70,10 @@ final class MultiSorter {
|
|||
}
|
||||
if (metaData.hasBlocks()
|
||||
&& fieldInfos.getParentField() == null
|
||||
&& metaData.getCreatedVersionMajor() >= Version.LUCENE_10_0_0.major) {
|
||||
&& metaData.createdVersionMajor() >= Version.LUCENE_10_0_0.major) {
|
||||
throw new CorruptIndexException(
|
||||
"parent field is not set but the index has blocks and uses index sorting. indexCreatedVersionMajor: "
|
||||
+ metaData.getCreatedVersionMajor(),
|
||||
+ metaData.createdVersionMajor(),
|
||||
"IndexingChain");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -370,7 +370,7 @@ public final class MultiTermsEnum extends BaseTermsEnum {
|
|||
public TermsEnumWithSlice(int index, ReaderSlice subSlice) {
|
||||
super(null, index);
|
||||
this.subSlice = subSlice;
|
||||
assert subSlice.length >= 0 : "length=" + subSlice.length;
|
||||
assert subSlice.length() >= 0 : "length=" + subSlice.length();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -128,7 +128,7 @@ public class ParallelLeafReader extends LeafReader {
|
|||
for (final LeafReader reader : this.parallelReaders) {
|
||||
LeafMetaData leafMetaData = reader.getMetaData();
|
||||
|
||||
Sort leafIndexSort = leafMetaData.getSort();
|
||||
Sort leafIndexSort = leafMetaData.sort();
|
||||
if (indexSort == null) {
|
||||
indexSort = leafIndexSort;
|
||||
} else if (leafIndexSort != null && indexSort.equals(leafIndexSort) == false) {
|
||||
|
@ -140,13 +140,13 @@ public class ParallelLeafReader extends LeafReader {
|
|||
}
|
||||
|
||||
if (createdVersionMajor == -1) {
|
||||
createdVersionMajor = leafMetaData.getCreatedVersionMajor();
|
||||
} else if (createdVersionMajor != leafMetaData.getCreatedVersionMajor()) {
|
||||
createdVersionMajor = leafMetaData.createdVersionMajor();
|
||||
} else if (createdVersionMajor != leafMetaData.createdVersionMajor()) {
|
||||
throw new IllegalArgumentException(
|
||||
"cannot combine LeafReaders that have different creation versions: saw both version="
|
||||
+ createdVersionMajor
|
||||
+ " and "
|
||||
+ leafMetaData.getCreatedVersionMajor());
|
||||
+ leafMetaData.createdVersionMajor());
|
||||
}
|
||||
|
||||
final FieldInfos readerFieldInfos = reader.getFieldInfos();
|
||||
|
@ -177,7 +177,7 @@ public class ParallelLeafReader extends LeafReader {
|
|||
Version minVersion = Version.LATEST;
|
||||
boolean hasBlocks = false;
|
||||
for (final LeafReader reader : this.parallelReaders) {
|
||||
Version leafVersion = reader.getMetaData().getMinVersion();
|
||||
Version leafVersion = reader.getMetaData().minVersion();
|
||||
hasBlocks |= reader.getMetaData().hasBlocks();
|
||||
if (leafVersion == null) {
|
||||
minVersion = null;
|
||||
|
|
|
@ -19,31 +19,13 @@ package org.apache.lucene.index;
|
|||
/**
|
||||
* Subreader slice from a parent composite reader.
|
||||
*
|
||||
* @param start Document ID this slice starts from.
|
||||
* @param length Number of documents in this slice.
|
||||
* @param readerIndex Sub-reader index for this slice.
|
||||
* @lucene.internal
|
||||
*/
|
||||
public final class ReaderSlice {
|
||||
public record ReaderSlice(int start, int length, int readerIndex) {
|
||||
|
||||
/** Zero-length {@code ReaderSlice} array. */
|
||||
public static final ReaderSlice[] EMPTY_ARRAY = new ReaderSlice[0];
|
||||
|
||||
/** Document ID this slice starts from. */
|
||||
public final int start;
|
||||
|
||||
/** Number of documents in this slice. */
|
||||
public final int length;
|
||||
|
||||
/** Sub-reader index for this slice. */
|
||||
public final int readerIndex;
|
||||
|
||||
/** Sole constructor. */
|
||||
public ReaderSlice(int start, int length, int readerIndex) {
|
||||
this.start = start;
|
||||
this.length = length;
|
||||
this.readerIndex = readerIndex;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "slice start=" + start + " length=" + length + " readerIndex=" + readerIndex;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -74,7 +74,7 @@ final class SegmentMerger {
|
|||
this.fieldInfosBuilder = new FieldInfos.Builder(fieldNumbers);
|
||||
Version minVersion = Version.LATEST;
|
||||
for (CodecReader reader : readers) {
|
||||
Version leafMinVersion = reader.getMetaData().getMinVersion();
|
||||
Version leafMinVersion = reader.getMetaData().minVersion();
|
||||
if (leafMinVersion == null) {
|
||||
minVersion = null;
|
||||
break;
|
||||
|
|
|
@ -80,15 +80,15 @@ final class SlowCompositeCodecReaderWrapper extends CodecReader {
|
|||
for (CodecReader reader : codecReaders) {
|
||||
LeafMetaData readerMeta = reader.getMetaData();
|
||||
if (majorVersion == -1) {
|
||||
majorVersion = readerMeta.getCreatedVersionMajor();
|
||||
} else if (majorVersion != readerMeta.getCreatedVersionMajor()) {
|
||||
majorVersion = readerMeta.createdVersionMajor();
|
||||
} else if (majorVersion != readerMeta.createdVersionMajor()) {
|
||||
throw new IllegalArgumentException(
|
||||
"Cannot combine leaf readers created with different major versions");
|
||||
}
|
||||
if (minVersion == null) {
|
||||
minVersion = readerMeta.getMinVersion();
|
||||
} else if (minVersion.onOrAfter(readerMeta.getMinVersion())) {
|
||||
minVersion = readerMeta.getMinVersion();
|
||||
minVersion = readerMeta.minVersion();
|
||||
} else if (minVersion.onOrAfter(readerMeta.minVersion())) {
|
||||
minVersion = readerMeta.minVersion();
|
||||
}
|
||||
hasBlocks |= readerMeta.hasBlocks();
|
||||
}
|
||||
|
@ -293,17 +293,7 @@ final class SlowCompositeCodecReaderWrapper extends CodecReader {
|
|||
}
|
||||
}
|
||||
|
||||
private static class DocValuesSub<T extends DocIdSetIterator> {
|
||||
private final T sub;
|
||||
private final int docStart;
|
||||
private final int docEnd;
|
||||
|
||||
DocValuesSub(T sub, int docStart, int docEnd) {
|
||||
this.sub = sub;
|
||||
this.docStart = docStart;
|
||||
this.docEnd = docEnd;
|
||||
}
|
||||
}
|
||||
private record DocValuesSub<T extends DocIdSetIterator>(T sub, int docStart, int docEnd) {}
|
||||
|
||||
private static class MergedDocIdSetIterator<T extends DocIdSetIterator> extends DocIdSetIterator {
|
||||
|
||||
|
@ -564,11 +554,8 @@ final class SlowCompositeCodecReaderWrapper extends CodecReader {
|
|||
return new SlowCompositePointsReaderWrapper(codecReaders, docStarts);
|
||||
}
|
||||
|
||||
private static class PointValuesSub {
|
||||
private final PointValues sub;
|
||||
private final int docBase;
|
||||
|
||||
PointValuesSub(PointValues sub, int docBase) {
|
||||
private record PointValuesSub(PointValues sub, int docBase) {
|
||||
private PointValuesSub(PointValues sub, int docBase) {
|
||||
this.sub = Objects.requireNonNull(sub);
|
||||
this.docBase = docBase;
|
||||
}
|
||||
|
|
|
@ -222,10 +222,10 @@ public final class Sorter {
|
|||
}
|
||||
if (metaData.hasBlocks()
|
||||
&& fieldInfos.getParentField() == null
|
||||
&& metaData.getCreatedVersionMajor() >= Version.LUCENE_10_0_0.major) {
|
||||
&& metaData.createdVersionMajor() >= Version.LUCENE_10_0_0.major) {
|
||||
throw new CorruptIndexException(
|
||||
"parent field is not set but the index has blocks. indexCreatedVersionMajor: "
|
||||
+ metaData.getCreatedVersionMajor(),
|
||||
+ metaData.createdVersionMajor(),
|
||||
"Sorter");
|
||||
}
|
||||
|
||||
|
|
|
@ -52,15 +52,7 @@ import org.apache.lucene.util.packed.PackedInts;
|
|||
*/
|
||||
public final class SortingCodecReader extends FilterCodecReader {
|
||||
|
||||
private static class SortingBits implements Bits {
|
||||
|
||||
private final Bits in;
|
||||
private final Sorter.DocMap docMap;
|
||||
|
||||
SortingBits(final Bits in, Sorter.DocMap docMap) {
|
||||
this.in = in;
|
||||
this.docMap = docMap;
|
||||
}
|
||||
private record SortingBits(Bits in, Sorter.DocMap docMap) implements Bits {
|
||||
|
||||
@Override
|
||||
public boolean get(int index) {
|
||||
|
@ -349,10 +341,7 @@ public final class SortingCodecReader extends FilterCodecReader {
|
|||
LeafMetaData metaData = reader.getMetaData();
|
||||
LeafMetaData newMetaData =
|
||||
new LeafMetaData(
|
||||
metaData.getCreatedVersionMajor(),
|
||||
metaData.getMinVersion(),
|
||||
sort,
|
||||
metaData.hasBlocks());
|
||||
metaData.createdVersionMajor(), metaData.minVersion(), sort, metaData.hasBlocks());
|
||||
if (docMap == null) {
|
||||
// the reader is already sorted
|
||||
return new FilterCodecReader(reader) {
|
||||
|
@ -744,8 +733,8 @@ public final class SortingCodecReader extends FilterCodecReader {
|
|||
boolean isSortField = false;
|
||||
// For things that aren't sort fields, it's possible for sort to be null here
|
||||
// In the event that we accidentally cache twice, its better not to throw an NPE
|
||||
if (metaData.getSort() != null) {
|
||||
for (SortField sf : metaData.getSort().getSort()) {
|
||||
if (metaData.sort() != null) {
|
||||
for (SortField sf : metaData.sort().getSort()) {
|
||||
if (field.equals(sf.getField())) {
|
||||
isSortField = true;
|
||||
break;
|
||||
|
|
|
@ -17,8 +17,6 @@
|
|||
package org.apache.lucene.search;
|
||||
|
||||
import java.util.Objects;
|
||||
import org.apache.lucene.index.IndexReader; // javadocs
|
||||
import org.apache.lucene.index.Terms; // javadocs
|
||||
|
||||
/**
|
||||
* Contains statistics for a collection (field).
|
||||
|
@ -45,31 +43,41 @@ import org.apache.lucene.index.Terms; // javadocs
|
|||
* <p>Be careful when performing calculations on these values because they are represented as 64-bit
|
||||
* integer values, you may need to cast to {@code double} for your use.
|
||||
*
|
||||
* @param field Field's name.
|
||||
* <p>This value is never {@code null}.
|
||||
* @param maxDoc The total number of documents in the range [1 .. {@link Long#MAX_VALUE}],
|
||||
* regardless of whether they all contain values for this field.
|
||||
* <p>This value is always a positive number. @see IndexReader#maxDoc()
|
||||
* @param docCount The total number of documents that have at least one term for this field , in the
|
||||
* range [1 .. {@link #maxDoc()}].
|
||||
* <p>This value is always a positive number, and never exceeds {@link #maxDoc()}. @see
|
||||
* Terms#getDocCount()
|
||||
* @param sumTotalTermFreq The total number of tokens for this field , in the range [{@link
|
||||
* #sumDocFreq()} .. {@link Long#MAX_VALUE}]. This is the "word count" for this field across all
|
||||
* documents. It is the sum of {@link TermStatistics#totalTermFreq()} across all terms. It is
|
||||
* also the sum of each document's field length across all documents.
|
||||
* <p>This value is always a positive number, and always at least {@link #sumDocFreq()}. @see
|
||||
* Terms#getSumTotalTermFreq()
|
||||
* @param sumDocFreq The total number of posting list entries for this field, in the range [{@link
|
||||
* #docCount()} .. {@link #sumTotalTermFreq()}]. This is the sum of term-document pairs: the sum
|
||||
* of {@link TermStatistics#docFreq()} across all terms. It is also the sum of each document's
|
||||
* unique term count for this field across all documents.
|
||||
* <p>This value is always a positive number, always at least {@link #docCount()}, and never
|
||||
* exceeds {@link #sumTotalTermFreq()}. @see Terms#getSumDocFreq()
|
||||
* @lucene.experimental
|
||||
*/
|
||||
public class CollectionStatistics {
|
||||
private final String field;
|
||||
private final long maxDoc;
|
||||
private final long docCount;
|
||||
private final long sumTotalTermFreq;
|
||||
private final long sumDocFreq;
|
||||
|
||||
public record CollectionStatistics(
|
||||
String field, long maxDoc, long docCount, long sumTotalTermFreq, long sumDocFreq) {
|
||||
/**
|
||||
* Creates statistics instance for a collection (field).
|
||||
*
|
||||
* @param field Field's name
|
||||
* @param maxDoc total number of documents.
|
||||
* @param docCount number of documents containing the field.
|
||||
* @param sumTotalTermFreq number of tokens in the field.
|
||||
* @param sumDocFreq number of postings list entries for the field.
|
||||
* @throws IllegalArgumentException if {@code maxDoc} is negative or zero.
|
||||
* @throws IllegalArgumentException if {@code docCount} is negative or zero.
|
||||
* @throws IllegalArgumentException if {@code docCount} is more than {@code maxDoc}.
|
||||
* @throws IllegalArgumentException if {@code sumDocFreq} is less than {@code docCount}.
|
||||
* @throws IllegalArgumentException if {@code sumTotalTermFreq} is less than {@code sumDocFreq}.
|
||||
*/
|
||||
public CollectionStatistics(
|
||||
String field, long maxDoc, long docCount, long sumTotalTermFreq, long sumDocFreq) {
|
||||
public CollectionStatistics {
|
||||
Objects.requireNonNull(field);
|
||||
if (maxDoc <= 0) {
|
||||
throw new IllegalArgumentException("maxDoc must be positive, maxDoc: " + maxDoc);
|
||||
|
@ -102,94 +110,5 @@ public class CollectionStatistics {
|
|||
+ ", sumDocFreq: "
|
||||
+ sumDocFreq);
|
||||
}
|
||||
this.field = field;
|
||||
this.maxDoc = maxDoc;
|
||||
this.docCount = docCount;
|
||||
this.sumTotalTermFreq = sumTotalTermFreq;
|
||||
this.sumDocFreq = sumDocFreq;
|
||||
}
|
||||
|
||||
/**
|
||||
* The field's name.
|
||||
*
|
||||
* <p>This value is never {@code null}.
|
||||
*
|
||||
* @return field's name, not {@code null}
|
||||
*/
|
||||
public final String field() {
|
||||
return field;
|
||||
}
|
||||
|
||||
/**
|
||||
* The total number of documents, regardless of whether they all contain values for this field.
|
||||
*
|
||||
* <p>This value is always a positive number.
|
||||
*
|
||||
* @return total number of documents, in the range [1 .. {@link Long#MAX_VALUE}]
|
||||
* @see IndexReader#maxDoc()
|
||||
*/
|
||||
public final long maxDoc() {
|
||||
return maxDoc;
|
||||
}
|
||||
|
||||
/**
|
||||
* The total number of documents that have at least one term for this field.
|
||||
*
|
||||
* <p>This value is always a positive number, and never exceeds {@link #maxDoc()}.
|
||||
*
|
||||
* @return total number of documents containing this field, in the range [1 .. {@link #maxDoc()}]
|
||||
* @see Terms#getDocCount()
|
||||
*/
|
||||
public final long docCount() {
|
||||
return docCount;
|
||||
}
|
||||
|
||||
/**
|
||||
* The total number of tokens for this field. This is the "word count" for this field across all
|
||||
* documents. It is the sum of {@link TermStatistics#totalTermFreq()} across all terms. It is also
|
||||
* the sum of each document's field length across all documents.
|
||||
*
|
||||
* <p>This value is always a positive number, and always at least {@link #sumDocFreq()}.
|
||||
*
|
||||
* @return total number of tokens in the field, in the range [{@link #sumDocFreq()} .. {@link
|
||||
* Long#MAX_VALUE}]
|
||||
* @see Terms#getSumTotalTermFreq()
|
||||
*/
|
||||
public final long sumTotalTermFreq() {
|
||||
return sumTotalTermFreq;
|
||||
}
|
||||
|
||||
/**
|
||||
* The total number of posting list entries for this field. This is the sum of term-document
|
||||
* pairs: the sum of {@link TermStatistics#docFreq()} across all terms. It is also the sum of each
|
||||
* document's unique term count for this field across all documents.
|
||||
*
|
||||
* <p>This value is always a positive number, always at least {@link #docCount()}, and never
|
||||
* exceeds {@link #sumTotalTermFreq()}.
|
||||
*
|
||||
* @return number of posting list entries, in the range [{@link #docCount()} .. {@link
|
||||
* #sumTotalTermFreq()}]
|
||||
* @see Terms#getSumDocFreq()
|
||||
*/
|
||||
public final long sumDocFreq() {
|
||||
return sumDocFreq;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append("field=");
|
||||
sb.append('"');
|
||||
sb.append(field());
|
||||
sb.append('"');
|
||||
sb.append(",maxDoc=");
|
||||
sb.append(maxDoc());
|
||||
sb.append(",docCount=");
|
||||
sb.append(docCount());
|
||||
sb.append(",sumTotalTermFreq=");
|
||||
sb.append(sumTotalTermFreq());
|
||||
sb.append(",sumDocFreq=");
|
||||
sb.append(sumDocFreq);
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -398,7 +398,7 @@ public class IndexSortSortedNumericDocValuesRangeQuery extends Query {
|
|||
|
||||
private IteratorAndCount getDocIdSetIteratorOrNullFromBkd(
|
||||
LeafReaderContext context, DocIdSetIterator delegate) throws IOException {
|
||||
Sort indexSort = context.reader().getMetaData().getSort();
|
||||
Sort indexSort = context.reader().getMetaData().sort();
|
||||
if (indexSort == null
|
||||
|| indexSort.getSort().length == 0
|
||||
|| indexSort.getSort()[0].getField().equals(field) == false) {
|
||||
|
@ -498,7 +498,7 @@ public class IndexSortSortedNumericDocValuesRangeQuery extends Query {
|
|||
if (itAndCount != null) {
|
||||
return itAndCount;
|
||||
}
|
||||
Sort indexSort = context.reader().getMetaData().getSort();
|
||||
Sort indexSort = context.reader().getMetaData().sort();
|
||||
if (indexSort != null
|
||||
&& indexSort.getSort().length > 0
|
||||
&& indexSort.getSort()[0].getField().equals(field)) {
|
||||
|
|
|
@ -17,7 +17,6 @@
|
|||
|
||||
package org.apache.lucene.search;
|
||||
|
||||
import java.util.Objects;
|
||||
import java.util.concurrent.atomic.LongAccumulator;
|
||||
|
||||
/** Maintains the maximum score and its corresponding document id concurrently */
|
||||
|
@ -68,14 +67,7 @@ final class MaxScoreAccumulator {
|
|||
return new DocAndScore(docBase, score);
|
||||
}
|
||||
|
||||
static class DocAndScore implements Comparable<DocAndScore> {
|
||||
final int docBase;
|
||||
final float score;
|
||||
|
||||
DocAndScore(int docBase, float score) {
|
||||
this.docBase = docBase;
|
||||
this.score = score;
|
||||
}
|
||||
record DocAndScore(int docBase, float score) implements Comparable<DocAndScore> {
|
||||
|
||||
@Override
|
||||
public int compareTo(DocAndScore o) {
|
||||
|
@ -101,11 +93,6 @@ final class MaxScoreAccumulator {
|
|||
return docBase == result.docBase && Float.compare(result.score, score) == 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(docBase, score);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "DocAndScore{" + "docBase=" + docBase + ", score=" + score + '}';
|
||||
|
|
|
@ -66,23 +66,12 @@ public abstract class Scorable {
|
|||
* A child Scorer and its relationship to its parent. The meaning of the relationship depends upon
|
||||
* the parent query.
|
||||
*
|
||||
* <p>The relationship can be any string that makes sense to the parent Scorer.
|
||||
*
|
||||
* @param child Child Scorer. (note this is typically a direct child, and may itself also have
|
||||
* children).
|
||||
* @param relationship An arbitrary string relating this scorer to the parent.
|
||||
* @lucene.experimental
|
||||
*/
|
||||
public static class ChildScorable {
|
||||
/** Child Scorer. (note this is typically a direct child, and may itself also have children). */
|
||||
public final Scorable child;
|
||||
|
||||
/** An arbitrary string relating this scorer to the parent. */
|
||||
public final String relationship;
|
||||
|
||||
/**
|
||||
* Creates a new ChildScorer node with the specified relationship.
|
||||
*
|
||||
* <p>The relationship can be any string that makes sense to the parent Scorer.
|
||||
*/
|
||||
public ChildScorable(Scorable child, String relationship) {
|
||||
this.child = child;
|
||||
this.relationship = relationship;
|
||||
}
|
||||
}
|
||||
public record ChildScorable(Scorable child, String relationship) {}
|
||||
}
|
||||
|
|
|
@ -686,26 +686,5 @@ public final class SynonymQuery extends Query {
|
|||
}
|
||||
}
|
||||
|
||||
private static class TermAndBoost {
|
||||
final BytesRef term;
|
||||
final float boost;
|
||||
|
||||
TermAndBoost(BytesRef term, float boost) {
|
||||
this.term = term;
|
||||
this.boost = boost;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
TermAndBoost that = (TermAndBoost) o;
|
||||
return Float.compare(that.boost, boost) == 0 && Objects.equals(term, that.term);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(term, boost);
|
||||
}
|
||||
}
|
||||
private record TermAndBoost(BytesRef term, float boost) {}
|
||||
}
|
||||
|
|
|
@ -17,8 +17,6 @@
|
|||
package org.apache.lucene.search;
|
||||
|
||||
import java.util.Objects;
|
||||
import org.apache.lucene.index.Term;
|
||||
import org.apache.lucene.index.TermsEnum; // javadocs
|
||||
import org.apache.lucene.util.BytesRef;
|
||||
|
||||
/**
|
||||
|
@ -45,27 +43,34 @@ import org.apache.lucene.util.BytesRef;
|
|||
* <p>Be careful when performing calculations on these values because they are represented as 64-bit
|
||||
* integer values, you may need to cast to {@code double} for your use.
|
||||
*
|
||||
* @param term Term bytes.
|
||||
* <p>This value is never {@code null}.
|
||||
* @param docFreq number of documents containing the term in the collection, in the range [1 ..
|
||||
* {@link #totalTermFreq()}].
|
||||
* <p>This is the document-frequency for the term: the count of documents where the term appears
|
||||
* at least one time.
|
||||
* <p>This value is always a positive number, and never exceeds {@link #totalTermFreq}. It also
|
||||
* cannot exceed {@link CollectionStatistics#sumDocFreq()}. @see TermsEnum#docFreq()
|
||||
* @param totalTermFreq number of occurrences of the term in the collection, in the range [{@link
|
||||
* #docFreq()} .. {@link CollectionStatistics#sumTotalTermFreq()}].
|
||||
* <p>This is the token count for the term: the number of times it appears in the field across
|
||||
* all documents.
|
||||
* <p>This value is always a positive number, always at least {@link #docFreq()}, and never
|
||||
* exceeds {@link CollectionStatistics#sumTotalTermFreq()}. @see TermsEnum#totalTermFreq()
|
||||
* @lucene.experimental
|
||||
*/
|
||||
// TODO: actually add missing cross-checks to guarantee TermStatistics is in bounds of
|
||||
// CollectionStatistics,
|
||||
// otherwise many similarity functions will implode.
|
||||
public class TermStatistics {
|
||||
private final BytesRef term;
|
||||
private final long docFreq;
|
||||
private final long totalTermFreq;
|
||||
|
||||
public record TermStatistics(BytesRef term, long docFreq, long totalTermFreq) {
|
||||
/**
|
||||
* Creates statistics instance for a term.
|
||||
*
|
||||
* @param term Term bytes
|
||||
* @param docFreq number of documents containing the term in the collection.
|
||||
* @param totalTermFreq number of occurrences of the term in the collection.
|
||||
* @throws NullPointerException if {@code term} is {@code null}.
|
||||
* @throws IllegalArgumentException if {@code docFreq} is negative or zero.
|
||||
* @throws IllegalArgumentException if {@code totalTermFreq} is less than {@code docFreq}.
|
||||
*/
|
||||
public TermStatistics(BytesRef term, long docFreq, long totalTermFreq) {
|
||||
public TermStatistics {
|
||||
Objects.requireNonNull(term);
|
||||
if (docFreq <= 0) {
|
||||
throw new IllegalArgumentException("docFreq must be positive, docFreq: " + docFreq);
|
||||
|
@ -81,66 +86,5 @@ public class TermStatistics {
|
|||
+ ", docFreq: "
|
||||
+ docFreq);
|
||||
}
|
||||
this.term = term;
|
||||
this.docFreq = docFreq;
|
||||
this.totalTermFreq = totalTermFreq;
|
||||
}
|
||||
|
||||
/**
|
||||
* The term text.
|
||||
*
|
||||
* <p>This value is never {@code null}.
|
||||
*
|
||||
* @return term's text, not {@code null}
|
||||
*/
|
||||
public final BytesRef term() {
|
||||
return term;
|
||||
}
|
||||
|
||||
/**
|
||||
* The number of documents this term occurs in.
|
||||
*
|
||||
* <p>This is the document-frequency for the term: the count of documents where the term appears
|
||||
* at least one time.
|
||||
*
|
||||
* <p>This value is always a positive number, and never exceeds {@link #totalTermFreq}. It also
|
||||
* cannot exceed {@link CollectionStatistics#sumDocFreq()}.
|
||||
*
|
||||
* @return document frequency, in the range [1 .. {@link #totalTermFreq()}]
|
||||
* @see TermsEnum#docFreq()
|
||||
*/
|
||||
public final long docFreq() {
|
||||
return docFreq;
|
||||
}
|
||||
|
||||
/**
|
||||
* The total number of occurrences of this term.
|
||||
*
|
||||
* <p>This is the token count for the term: the number of times it appears in the field across all
|
||||
* documents.
|
||||
*
|
||||
* <p>This value is always a positive number, always at least {@link #docFreq()}, and never
|
||||
* exceeds {@link CollectionStatistics#sumTotalTermFreq()}.
|
||||
*
|
||||
* @return number of occurrences, in the range [{@link #docFreq()} .. {@link
|
||||
* CollectionStatistics#sumTotalTermFreq()}]
|
||||
* @see TermsEnum#totalTermFreq()
|
||||
*/
|
||||
public final long totalTermFreq() {
|
||||
return totalTermFreq;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append("term=");
|
||||
sb.append('"');
|
||||
sb.append(Term.toString(term()));
|
||||
sb.append('"');
|
||||
sb.append(",docFreq=");
|
||||
sb.append(docFreq());
|
||||
sb.append(",totalTermFreq=");
|
||||
sb.append(totalTermFreq());
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -54,7 +54,7 @@ public abstract class TopFieldCollector extends TopDocsCollector<Entry> {
|
|||
// as all segments are sorted in the same way, enough to check only the 1st segment for
|
||||
// indexSort
|
||||
if (searchSortPartOfIndexSort == null) {
|
||||
final Sort indexSort = context.reader().getMetaData().getSort();
|
||||
final Sort indexSort = context.reader().getMetaData().sort();
|
||||
searchSortPartOfIndexSort = canEarlyTerminate(sort, indexSort);
|
||||
if (searchSortPartOfIndexSort) {
|
||||
firstComparator.disableSkipping();
|
||||
|
@ -367,9 +367,9 @@ public abstract class TopFieldCollector extends TopDocsCollector<Entry> {
|
|||
// if the local queue is not full because the threshold
|
||||
// is reached.
|
||||
DocAndScore maxMinScore = minScoreAcc.get();
|
||||
if (maxMinScore != null && maxMinScore.score > minCompetitiveScore) {
|
||||
scorer.setMinCompetitiveScore(maxMinScore.score);
|
||||
minCompetitiveScore = maxMinScore.score;
|
||||
if (maxMinScore != null && maxMinScore.score() > minCompetitiveScore) {
|
||||
scorer.setMinCompetitiveScore(maxMinScore.score());
|
||||
minCompetitiveScore = maxMinScore.score();
|
||||
totalHitsRelation = TotalHits.Relation.GREATER_THAN_OR_EQUAL_TO;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -232,7 +232,7 @@ public abstract class TopScoreDocCollector extends TopDocsCollector<ScoreDoc> {
|
|||
// the next float if the global minimum score is set on a document id that is
|
||||
// smaller than the ids in the current leaf
|
||||
float score =
|
||||
docBase >= maxMinScore.docBase ? Math.nextUp(maxMinScore.score) : maxMinScore.score;
|
||||
docBase >= maxMinScore.docBase() ? Math.nextUp(maxMinScore.score()) : maxMinScore.score();
|
||||
if (score > minCompetitiveScore) {
|
||||
assert hitsThresholdChecker.isThresholdReached();
|
||||
scorer.setMinCompetitiveScore(score);
|
||||
|
|
|
@ -464,15 +464,7 @@ public class TermOrdValComparator extends FieldComparator<BytesRef> {
|
|||
}
|
||||
}
|
||||
|
||||
private static class PostingsEnumAndOrd {
|
||||
private final PostingsEnum postings;
|
||||
private final int ord;
|
||||
|
||||
PostingsEnumAndOrd(PostingsEnum postings, int ord) {
|
||||
this.postings = postings;
|
||||
this.ord = ord;
|
||||
}
|
||||
}
|
||||
private record PostingsEnumAndOrd(PostingsEnum postings, int ord) {}
|
||||
|
||||
private class CompetitiveIterator extends DocIdSetIterator {
|
||||
|
||||
|
|
|
@ -62,18 +62,16 @@ public class QueryBuilder {
|
|||
protected boolean enableGraphQueries = true;
|
||||
protected boolean autoGenerateMultiTermSynonymsPhraseQuery = false;
|
||||
|
||||
/** Wraps a term and boost */
|
||||
public static class TermAndBoost {
|
||||
/** the term */
|
||||
public final BytesRef term;
|
||||
|
||||
/** the boost */
|
||||
public final float boost;
|
||||
|
||||
/**
|
||||
* Wraps a term and boost
|
||||
*
|
||||
* @param term the term
|
||||
* @param boost the boost
|
||||
*/
|
||||
public record TermAndBoost(BytesRef term, float boost) {
|
||||
/** Creates a new TermAndBoost */
|
||||
public TermAndBoost(BytesRef term, float boost) {
|
||||
this.term = BytesRef.deepCopyOf(term);
|
||||
this.boost = boost;
|
||||
public TermAndBoost {
|
||||
term = BytesRef.deepCopyOf(term);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -582,20 +582,5 @@ public final class BKDRadixSelector {
|
|||
}
|
||||
|
||||
/** Sliced reference to points in an PointWriter. */
|
||||
public static final class PathSlice {
|
||||
public final PointWriter writer;
|
||||
public final long start;
|
||||
public final long count;
|
||||
|
||||
public PathSlice(PointWriter writer, long start, long count) {
|
||||
this.writer = writer;
|
||||
this.start = start;
|
||||
this.count = count;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "PathSlice(start=" + start + " count=" + count + " writer=" + writer + ")";
|
||||
}
|
||||
}
|
||||
public record PathSlice(PointWriter writer, long start, long count) {}
|
||||
}
|
||||
|
|
|
@ -1823,7 +1823,7 @@ public class BKDWriter implements Closeable {
|
|||
private void computePackedValueBounds(
|
||||
BKDRadixSelector.PathSlice slice, byte[] minPackedValue, byte[] maxPackedValue)
|
||||
throws IOException {
|
||||
try (PointReader reader = slice.writer.getReader(slice.start, slice.count)) {
|
||||
try (PointReader reader = slice.writer().getReader(slice.start(), slice.count())) {
|
||||
if (reader.next() == false) {
|
||||
return;
|
||||
}
|
||||
|
@ -1887,16 +1887,16 @@ public class BKDWriter implements Closeable {
|
|||
// least number of unique bytes at commonPrefixLengths[dim], which makes compression more
|
||||
// efficient
|
||||
HeapPointWriter heapSource;
|
||||
if (points.writer instanceof HeapPointWriter == false) {
|
||||
if (points.writer() instanceof HeapPointWriter == false) {
|
||||
// Adversarial cases can cause this, e.g. merging big segments with most of the points
|
||||
// deleted
|
||||
heapSource = switchToHeap(points.writer);
|
||||
heapSource = switchToHeap(points.writer());
|
||||
} else {
|
||||
heapSource = (HeapPointWriter) points.writer;
|
||||
heapSource = (HeapPointWriter) points.writer();
|
||||
}
|
||||
|
||||
int from = Math.toIntExact(points.start);
|
||||
int to = Math.toIntExact(points.start + points.count);
|
||||
int from = Math.toIntExact(points.start());
|
||||
int to = Math.toIntExact(points.start() + points.count());
|
||||
// we store common prefix on scratch
|
||||
computeCommonPrefixLength(heapSource, scratch, from, to);
|
||||
|
||||
|
@ -2004,9 +2004,9 @@ public class BKDWriter implements Closeable {
|
|||
radixSelector.select(
|
||||
points,
|
||||
slices,
|
||||
points.start,
|
||||
points.start + points.count,
|
||||
points.start + leftCount,
|
||||
points.start(),
|
||||
points.start() + points.count(),
|
||||
points.start() + leftCount,
|
||||
splitDim,
|
||||
commonPrefixLen);
|
||||
|
||||
|
|
|
@ -149,12 +149,8 @@ public final class Util {
|
|||
}
|
||||
|
||||
/** Compares first by the provided comparator, and then tie breaks by path.input. */
|
||||
private static class TieBreakByInputComparator<T> implements Comparator<FSTPath<T>> {
|
||||
private final Comparator<T> comparator;
|
||||
|
||||
TieBreakByInputComparator(Comparator<T> comparator) {
|
||||
this.comparator = comparator;
|
||||
}
|
||||
private record TieBreakByInputComparator<T>(Comparator<T> comparator)
|
||||
implements Comparator<FSTPath<T>> {
|
||||
|
||||
@Override
|
||||
public int compare(FSTPath<T> a, FSTPath<T> b) {
|
||||
|
@ -430,15 +426,7 @@ public final class Util {
|
|||
/**
|
||||
* Holds a single input (IntsRef) + output, returned by {@link #shortestPaths shortestPaths()}.
|
||||
*/
|
||||
public static final class Result<T> {
|
||||
public final IntsRef input;
|
||||
public final T output;
|
||||
|
||||
public Result(IntsRef input, T output) {
|
||||
this.input = input;
|
||||
this.output = output;
|
||||
}
|
||||
}
|
||||
public record Result<T>(IntsRef input, T output) {}
|
||||
|
||||
/** Holds the results for a top N search using {@link TopNSearcher} */
|
||||
public static final class TopResults<T> implements Iterable<Result<T>> {
|
||||
|
|
|
@ -171,20 +171,7 @@ public class PackedInts {
|
|||
}
|
||||
|
||||
/** Simple class that holds a format and a number of bits per value. */
|
||||
public static class FormatAndBits {
|
||||
public final Format format;
|
||||
public final int bitsPerValue;
|
||||
|
||||
public FormatAndBits(Format format, int bitsPerValue) {
|
||||
this.format = format;
|
||||
this.bitsPerValue = bitsPerValue;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "FormatAndBits(format=" + format + " bitsPerValue=" + bitsPerValue + ")";
|
||||
}
|
||||
}
|
||||
public record FormatAndBits(Format format, int bitsPerValue) {}
|
||||
|
||||
/**
|
||||
* Try to find the {@link Format} and number of bits per value that would restore from disk the
|
||||
|
|
|
@ -47,7 +47,7 @@ public final class PagedMutable extends AbstractPagedMutable<PagedMutable> {
|
|||
}
|
||||
|
||||
PagedMutable(long size, int pageSize, PackedInts.FormatAndBits formatAndBits) {
|
||||
this(size, pageSize, formatAndBits.bitsPerValue, formatAndBits.format);
|
||||
this(size, pageSize, formatAndBits.bitsPerValue(), formatAndBits.format());
|
||||
}
|
||||
|
||||
PagedMutable(long size, int pageSize, int bitsPerValue, PackedInts.Format format) {
|
||||
|
|
|
@ -614,19 +614,7 @@ public class ScalarQuantizer {
|
|||
}
|
||||
}
|
||||
|
||||
private static class ScoreDocsAndScoreVariance {
|
||||
private final ScoreDoc[] scoreDocs;
|
||||
private final float scoreVariance;
|
||||
|
||||
public ScoreDocsAndScoreVariance(ScoreDoc[] scoreDocs, float scoreVariance) {
|
||||
this.scoreDocs = scoreDocs;
|
||||
this.scoreVariance = scoreVariance;
|
||||
}
|
||||
|
||||
public ScoreDoc[] getScoreDocs() {
|
||||
return scoreDocs;
|
||||
}
|
||||
}
|
||||
private record ScoreDocsAndScoreVariance(ScoreDoc[] scoreDocs, float scoreVariance) {}
|
||||
|
||||
private static class OnlineMeanAndVar {
|
||||
private double mean = 0.0;
|
||||
|
@ -687,7 +675,7 @@ public class ScalarQuantizer {
|
|||
for (int i = 0; i < nearestNeighbors.size(); i++) {
|
||||
float queryCorrection = quantizer.quantize(vectors.get(i), query, function);
|
||||
ScoreDocsAndScoreVariance scoreDocsAndScoreVariance = nearestNeighbors.get(i);
|
||||
ScoreDoc[] scoreDocs = scoreDocsAndScoreVariance.getScoreDocs();
|
||||
ScoreDoc[] scoreDocs = scoreDocsAndScoreVariance.scoreDocs();
|
||||
float scoreVariance = scoreDocsAndScoreVariance.scoreVariance;
|
||||
// calculate the score for the vector against its nearest neighbors but with quantized
|
||||
// scores now
|
||||
|
|
|
@ -388,28 +388,14 @@ public class TestDocumentWriter extends LuceneTestCase {
|
|||
field, new float[] {1, 2, 3, 4}, VectorSimilarityFunction.EUCLIDEAN));
|
||||
}
|
||||
|
||||
private static class MockIndexableField implements IndexableField {
|
||||
|
||||
private final String field;
|
||||
private final BytesRef value;
|
||||
private final IndexableFieldType fieldType;
|
||||
|
||||
MockIndexableField(String field, BytesRef value, IndexableFieldType fieldType) {
|
||||
this.field = field;
|
||||
this.value = value;
|
||||
this.fieldType = fieldType;
|
||||
}
|
||||
private record MockIndexableField(String field, BytesRef value, IndexableFieldType fieldType)
|
||||
implements IndexableField {
|
||||
|
||||
@Override
|
||||
public String name() {
|
||||
return field;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IndexableFieldType fieldType() {
|
||||
return fieldType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TokenStream tokenStream(Analyzer analyzer, TokenStream reuse) {
|
||||
return null;
|
||||
|
|
|
@ -2412,7 +2412,7 @@ public class TestIndexSorting extends LuceneTestCase {
|
|||
if (VERBOSE) {
|
||||
System.out.println("TEST: now compare r1=" + r1 + " r2=" + r2);
|
||||
}
|
||||
assertEquals(sort, getOnlyLeafReader(r2).getMetaData().getSort());
|
||||
assertEquals(sort, getOnlyLeafReader(r2).getMetaData().sort());
|
||||
assertReaderEquals("left: sorted by hand; right: sorted by Lucene", r1, r2);
|
||||
IOUtils.close(w1, w2, r1, r2, dir1, dir2);
|
||||
}
|
||||
|
|
|
@ -73,10 +73,7 @@ import org.apache.lucene.util.InfoStream;
|
|||
@SuppressCodecs("SimpleText") // too slow here
|
||||
public class TestIndexWriterExceptions extends LuceneTestCase {
|
||||
|
||||
private static class DocCopyIterator implements Iterable<Document> {
|
||||
private final Document doc;
|
||||
private final int count;
|
||||
|
||||
private record DocCopyIterator(Document doc, int count) implements Iterable<Document> {
|
||||
/* private field types */
|
||||
/* private field types */
|
||||
|
||||
|
@ -105,11 +102,6 @@ public class TestIndexWriterExceptions extends LuceneTestCase {
|
|||
custom5.setStoreTermVectorOffsets(true);
|
||||
}
|
||||
|
||||
public DocCopyIterator(Document doc, int count) {
|
||||
this.count = count;
|
||||
this.doc = doc;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterator<Document> iterator() {
|
||||
return new Iterator<Document>() {
|
||||
|
|
|
@ -138,7 +138,7 @@ public class TestSortingCodecReader extends LuceneTestCase {
|
|||
assertEquals(7, values.longValue());
|
||||
assertEquals(2, values.nextDoc());
|
||||
assertEquals(18, values.longValue());
|
||||
assertNotNull(leaf.getMetaData().getSort());
|
||||
assertNotNull(leaf.getMetaData().sort());
|
||||
IOUtils.close(r, w, dir, tmpDir);
|
||||
}
|
||||
|
||||
|
|
|
@ -625,15 +625,7 @@ public class TestTermsEnum extends LuceneTestCase {
|
|||
}
|
||||
}
|
||||
|
||||
private static class TermAndState {
|
||||
public final BytesRef term;
|
||||
public final TermState state;
|
||||
|
||||
public TermAndState(BytesRef term, TermState state) {
|
||||
this.term = term;
|
||||
this.state = state;
|
||||
}
|
||||
}
|
||||
private record TermAndState(BytesRef term, TermState state) {}
|
||||
|
||||
private void testRandomSeeks(IndexReader r, String... validTermStrings) throws IOException {
|
||||
final BytesRef[] validTerms = new BytesRef[validTermStrings.length];
|
||||
|
|
|
@ -269,16 +269,8 @@ public class TestVectorScorer extends LuceneTestCase {
|
|||
}
|
||||
|
||||
// A callable that scores the given ord and scorer and asserts the expected result.
|
||||
static class AssertingScoreCallable implements Callable<Optional<Throwable>> {
|
||||
final RandomVectorScorer scorer;
|
||||
final int ord;
|
||||
final float expectedScore;
|
||||
|
||||
AssertingScoreCallable(RandomVectorScorer scorer, int ord, float expectedScore) {
|
||||
this.scorer = scorer;
|
||||
this.ord = ord;
|
||||
this.expectedScore = expectedScore;
|
||||
}
|
||||
record AssertingScoreCallable(RandomVectorScorer scorer, int ord, float expectedScore)
|
||||
implements Callable<Optional<Throwable>> {
|
||||
|
||||
@Override
|
||||
public Optional<Throwable> call() throws Exception {
|
||||
|
|
|
@ -190,7 +190,7 @@ public class TestBooleanQueryVisitSubscorers extends LuceneTestCase {
|
|||
set.add((Scorer) scorer);
|
||||
} else {
|
||||
for (Scorable.ChildScorable child : scorer.getChildren()) {
|
||||
fillLeaves(child.child, set);
|
||||
fillLeaves(child.child(), set);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -330,8 +330,8 @@ public class TestBooleanQueryVisitSubscorers extends LuceneTestCase {
|
|||
final StringBuilder builder, final Scorable scorer, final int indent) throws IOException {
|
||||
builder.append(scorer.getClass().getSimpleName());
|
||||
for (final Scorable.ChildScorable childScorer : scorer.getChildren()) {
|
||||
indent(builder, indent + 1).append(childScorer.relationship).append(" ");
|
||||
summarizeScorer(builder, childScorer.child, indent + 2);
|
||||
indent(builder, indent + 1).append(childScorer.relationship()).append(" ");
|
||||
summarizeScorer(builder, childScorer.child(), indent + 2);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -122,13 +122,8 @@ public class TestCollectorManager extends LuceneTestCase {
|
|||
return generated;
|
||||
}
|
||||
|
||||
private static final class CompositeCollectorManager
|
||||
private record CompositeCollectorManager(List<Predicate<Integer>> predicates)
|
||||
implements CollectorManager<Collector, List<Integer>> {
|
||||
private final List<Predicate<Integer>> predicates;
|
||||
|
||||
CompositeCollectorManager(List<Predicate<Integer>> predicates) {
|
||||
this.predicates = predicates;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collector newCollector() throws IOException {
|
||||
|
|
|
@ -107,7 +107,7 @@ public class TestConstantScoreQuery extends LuceneTestCase {
|
|||
try {
|
||||
Collection<Scorable.ChildScorable> children = s.getChildren();
|
||||
if (children.size() == 0) return s;
|
||||
s = children.stream().findFirst().get().child;
|
||||
s = children.stream().findFirst().get().child();
|
||||
} catch (
|
||||
@SuppressWarnings("unused")
|
||||
Exception e) {
|
||||
|
|
|
@ -705,14 +705,7 @@ public class TestFuzzyQuery extends LuceneTestCase {
|
|||
IOUtils.close(r, dir);
|
||||
}
|
||||
|
||||
private static class TermAndScore implements Comparable<TermAndScore> {
|
||||
final String term;
|
||||
final float score;
|
||||
|
||||
public TermAndScore(String term, float score) {
|
||||
this.term = term;
|
||||
this.score = score;
|
||||
}
|
||||
private record TermAndScore(String term, float score) implements Comparable<TermAndScore> {
|
||||
|
||||
@Override
|
||||
public int compareTo(TermAndScore other) {
|
||||
|
@ -725,11 +718,6 @@ public class TestFuzzyQuery extends LuceneTestCase {
|
|||
return term.compareTo(other.term);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return term + " score=" + score;
|
||||
}
|
||||
}
|
||||
|
||||
// Poached from LuceneLevenshteinDistance.java (from suggest module): it supports transpositions
|
||||
|
|
|
@ -23,29 +23,29 @@ public class TestMaxScoreAccumulator extends LuceneTestCase {
|
|||
public void testSimple() {
|
||||
MaxScoreAccumulator acc = new MaxScoreAccumulator();
|
||||
acc.accumulate(0, 0f);
|
||||
assertEquals(0f, acc.get().score, 0);
|
||||
assertEquals(0, acc.get().docBase, 0);
|
||||
assertEquals(0f, acc.get().score(), 0);
|
||||
assertEquals(0, acc.get().docBase(), 0);
|
||||
acc.accumulate(10, 0f);
|
||||
assertEquals(0f, acc.get().score, 0);
|
||||
assertEquals(0, acc.get().docBase, 0);
|
||||
assertEquals(0f, acc.get().score(), 0);
|
||||
assertEquals(0, acc.get().docBase(), 0);
|
||||
acc.accumulate(100, 1000f);
|
||||
assertEquals(1000f, acc.get().score, 0);
|
||||
assertEquals(100, acc.get().docBase, 0);
|
||||
assertEquals(1000f, acc.get().score(), 0);
|
||||
assertEquals(100, acc.get().docBase(), 0);
|
||||
acc.accumulate(1000, 5f);
|
||||
assertEquals(1000f, acc.get().score, 0);
|
||||
assertEquals(100, acc.get().docBase, 0);
|
||||
assertEquals(1000f, acc.get().score(), 0);
|
||||
assertEquals(100, acc.get().docBase(), 0);
|
||||
acc.accumulate(99, 1000f);
|
||||
assertEquals(1000f, acc.get().score, 0);
|
||||
assertEquals(99, acc.get().docBase, 0);
|
||||
assertEquals(1000f, acc.get().score(), 0);
|
||||
assertEquals(99, acc.get().docBase(), 0);
|
||||
acc.accumulate(1000, 1001f);
|
||||
assertEquals(1001f, acc.get().score, 0);
|
||||
assertEquals(1000, acc.get().docBase, 0);
|
||||
assertEquals(1001f, acc.get().score(), 0);
|
||||
assertEquals(1000, acc.get().docBase(), 0);
|
||||
acc.accumulate(10, 1001f);
|
||||
assertEquals(1001f, acc.get().score, 0);
|
||||
assertEquals(10, acc.get().docBase, 0);
|
||||
assertEquals(1001f, acc.get().score(), 0);
|
||||
assertEquals(10, acc.get().docBase(), 0);
|
||||
acc.accumulate(100, 1001f);
|
||||
assertEquals(1001f, acc.get().score, 0);
|
||||
assertEquals(10, acc.get().docBase, 0);
|
||||
assertEquals(1001f, acc.get().score(), 0);
|
||||
assertEquals(10, acc.get().docBase(), 0);
|
||||
}
|
||||
|
||||
public void testRandom() {
|
||||
|
@ -56,7 +56,7 @@ public class TestMaxScoreAccumulator extends LuceneTestCase {
|
|||
for (int i = 0; i < numDocs; i++) {
|
||||
MaxScoreAccumulator.DocAndScore res =
|
||||
new MaxScoreAccumulator.DocAndScore(random().nextInt(maxDocs), random().nextFloat());
|
||||
acc.accumulate(res.docBase, res.score);
|
||||
acc.accumulate(res.docBase(), res.score());
|
||||
if (res.compareTo(max) > 0) {
|
||||
max = res;
|
||||
}
|
||||
|
|
|
@ -47,7 +47,7 @@ public class TestScorerPerf extends LuceneTestCase {
|
|||
return sets;
|
||||
}
|
||||
|
||||
private static final class CountingHitCollectorManager
|
||||
private record CountingHitCollectorManager()
|
||||
implements CollectorManager<CountingHitCollector, CountingHitCollector> {
|
||||
|
||||
@Override
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue