mirror of https://github.com/apache/lucene.git
Merge branch 'main' of https://gitbox.apache.org/repos/asf/lucene into jms2
This commit is contained in:
commit
f7fd21a0c6
|
@ -100,6 +100,8 @@ Optimizations
|
||||||
|
|
||||||
* LUCENE-10225: Improve IntroSelector with 3-ways partitioning. (Bruno Roustant, Adrien Grand)
|
* LUCENE-10225: Improve IntroSelector with 3-ways partitioning. (Bruno Roustant, Adrien Grand)
|
||||||
|
|
||||||
|
* LUCENE-10321: Tweak MultiRangeQuery interval tree creation to skip "pulling up" mins. (Greg Miller)
|
||||||
|
|
||||||
Bug Fixes
|
Bug Fixes
|
||||||
---------------------
|
---------------------
|
||||||
|
|
||||||
|
|
|
@ -25,6 +25,7 @@ import java.time.format.DateTimeFormatter;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
|
|
||||||
|
/** Formats {@link CircularLogBufferHandler.ImmutableLogRecord} to string. */
|
||||||
public class LogRecordFormatter
|
public class LogRecordFormatter
|
||||||
implements Function<CircularLogBufferHandler.ImmutableLogRecord, String> {
|
implements Function<CircularLogBufferHandler.ImmutableLogRecord, String> {
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -178,7 +178,7 @@ public abstract class MultiRangeQuery extends Query {
|
||||||
return new ConstantScoreWeight(this, boost) {
|
return new ConstantScoreWeight(this, boost) {
|
||||||
|
|
||||||
private PointValues.IntersectVisitor getIntersectVisitor(
|
private PointValues.IntersectVisitor getIntersectVisitor(
|
||||||
DocIdSetBuilder result, Range range) {
|
DocIdSetBuilder result, Relatable range) {
|
||||||
return new PointValues.IntersectVisitor() {
|
return new PointValues.IntersectVisitor() {
|
||||||
|
|
||||||
DocIdSetBuilder.BulkAdder adder;
|
DocIdSetBuilder.BulkAdder adder;
|
||||||
|
@ -241,7 +241,13 @@ public abstract class MultiRangeQuery extends Query {
|
||||||
+ bytesPerDim);
|
+ bytesPerDim);
|
||||||
}
|
}
|
||||||
|
|
||||||
Range range = create(rangeClauses, numDims, bytesPerDim, comparator);
|
Relatable range;
|
||||||
|
if (rangeClauses.size() == 1) {
|
||||||
|
range = getRange(rangeClauses.get(0), numDims, bytesPerDim, comparator);
|
||||||
|
} else {
|
||||||
|
range = createTree(rangeClauses, numDims, bytesPerDim, comparator);
|
||||||
|
}
|
||||||
|
|
||||||
boolean allDocsMatch;
|
boolean allDocsMatch;
|
||||||
if (values.getDocCount() == reader.maxDoc()) {
|
if (values.getDocCount() == reader.maxDoc()) {
|
||||||
final byte[] fieldPackedLower = values.getMinPackedValue();
|
final byte[] fieldPackedLower = values.getMinPackedValue();
|
||||||
|
@ -399,25 +405,30 @@ public abstract class MultiRangeQuery extends Query {
|
||||||
protected abstract String toString(int dimension, byte[] value);
|
protected abstract String toString(int dimension, byte[] value);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A range represents anything with a min/max value that can compute its relation with another
|
* Represents a range that can compute its relation with another range and can compute if a point
|
||||||
* range and can compute if a point is inside it
|
* is inside it
|
||||||
*/
|
*/
|
||||||
private interface Range {
|
private interface Relatable {
|
||||||
/** min value of this range */
|
|
||||||
byte[] getMinPackedValue();
|
|
||||||
/** max value of this range */
|
|
||||||
byte[] getMaxPackedValue();
|
|
||||||
/** return true if the provided point is inside the range */
|
/** return true if the provided point is inside the range */
|
||||||
boolean matches(byte[] packedValue);
|
boolean matches(byte[] packedValue);
|
||||||
/** return the relation between this range and the provided range */
|
/** return the relation between this range and the provided range */
|
||||||
PointValues.Relation relate(byte[] minPackedValue, byte[] maxPackedValue);
|
PointValues.Relation relate(byte[] minPackedValue, byte[] maxPackedValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A range represents anything with a min/max value that can compute its relation with another
|
||||||
|
* range and can compute if a point is inside it
|
||||||
|
*/
|
||||||
|
private interface Range extends Relatable {
|
||||||
|
/** min value of this range */
|
||||||
|
byte[] getMinPackedValue();
|
||||||
|
/** max value of this range */
|
||||||
|
byte[] getMaxPackedValue();
|
||||||
|
}
|
||||||
|
|
||||||
/** An interval tree of Ranges for speeding up computations */
|
/** An interval tree of Ranges for speeding up computations */
|
||||||
private static class RangeTree implements Range {
|
private static class RangeTree implements Relatable {
|
||||||
/** minimum value of this Range and its children */
|
/** maximum value contained in this range sub-tree */
|
||||||
private final byte[] minPackedValue;
|
|
||||||
/** maximum value of this Range and its children */
|
|
||||||
private final byte[] maxPackedValue;
|
private final byte[] maxPackedValue;
|
||||||
|
|
||||||
/** Left child, it can be null */
|
/** Left child, it can be null */
|
||||||
|
@ -439,7 +450,6 @@ public abstract class MultiRangeQuery extends Query {
|
||||||
ArrayUtil.ByteArrayComparator comparator,
|
ArrayUtil.ByteArrayComparator comparator,
|
||||||
int numIndexDim,
|
int numIndexDim,
|
||||||
int bytesPerDim) {
|
int bytesPerDim) {
|
||||||
this.minPackedValue = component.getMinPackedValue().clone();
|
|
||||||
this.maxPackedValue = component.getMaxPackedValue().clone();
|
this.maxPackedValue = component.getMaxPackedValue().clone();
|
||||||
this.component = component;
|
this.component = component;
|
||||||
this.split = split;
|
this.split = split;
|
||||||
|
@ -448,16 +458,6 @@ public abstract class MultiRangeQuery extends Query {
|
||||||
this.bytesPerDim = bytesPerDim;
|
this.bytesPerDim = bytesPerDim;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public byte[] getMinPackedValue() {
|
|
||||||
return minPackedValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public byte[] getMaxPackedValue() {
|
|
||||||
return maxPackedValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean matches(byte[] packedValue) {
|
public boolean matches(byte[] packedValue) {
|
||||||
boolean valid = true;
|
boolean valid = true;
|
||||||
|
@ -479,7 +479,10 @@ public abstract class MultiRangeQuery extends Query {
|
||||||
}
|
}
|
||||||
if (right != null
|
if (right != null
|
||||||
&& comparator.compare(
|
&& comparator.compare(
|
||||||
packedValue, split * bytesPerDim, minPackedValue, split * bytesPerDim)
|
packedValue,
|
||||||
|
split * bytesPerDim,
|
||||||
|
component.getMinPackedValue(),
|
||||||
|
split * bytesPerDim)
|
||||||
>= 0) {
|
>= 0) {
|
||||||
if (right.matches(packedValue)) {
|
if (right.matches(packedValue)) {
|
||||||
return true;
|
return true;
|
||||||
|
@ -512,7 +515,10 @@ public abstract class MultiRangeQuery extends Query {
|
||||||
}
|
}
|
||||||
if (right != null
|
if (right != null
|
||||||
&& comparator.compare(
|
&& comparator.compare(
|
||||||
maxPackedValue, split * bytesPerDim, this.minPackedValue, split * bytesPerDim)
|
maxPackedValue,
|
||||||
|
split * bytesPerDim,
|
||||||
|
component.getMinPackedValue(),
|
||||||
|
split * bytesPerDim)
|
||||||
>= 0) {
|
>= 0) {
|
||||||
relation = right.relate(minPackedValue, maxPackedValue);
|
relation = right.relate(minPackedValue, maxPackedValue);
|
||||||
if (relation != PointValues.Relation.CELL_OUTSIDE_QUERY) {
|
if (relation != PointValues.Relation.CELL_OUTSIDE_QUERY) {
|
||||||
|
@ -525,37 +531,17 @@ public abstract class MultiRangeQuery extends Query {
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Creates a tree from provided clauses */
|
/** Creates a tree from provided clauses */
|
||||||
static Range create(
|
static RangeTree createTree(
|
||||||
List<RangeClause> clauses,
|
List<RangeClause> clauses,
|
||||||
int numIndexDim,
|
int numIndexDim,
|
||||||
int bytesPerDim,
|
int bytesPerDim,
|
||||||
ArrayUtil.ByteArrayComparator comparator) {
|
ArrayUtil.ByteArrayComparator comparator) {
|
||||||
if (clauses.size() == 1) {
|
|
||||||
return getRange(clauses.get(0), numIndexDim, bytesPerDim, comparator);
|
|
||||||
}
|
|
||||||
Range[] ranges = new Range[clauses.size()];
|
Range[] ranges = new Range[clauses.size()];
|
||||||
for (int i = 0; i < clauses.size(); i++) {
|
for (int i = 0; i < clauses.size(); i++) {
|
||||||
ranges[i] = getRange(clauses.get(i), numIndexDim, bytesPerDim, comparator);
|
ranges[i] = getRange(clauses.get(i), numIndexDim, bytesPerDim, comparator);
|
||||||
}
|
}
|
||||||
RangeTree root =
|
|
||||||
createTree(ranges, 0, ranges.length - 1, 0, numIndexDim, bytesPerDim, comparator);
|
return createTree(ranges, 0, ranges.length - 1, 0, numIndexDim, bytesPerDim, comparator);
|
||||||
// pull up min values for the root node so it contains a consistent bounding box
|
|
||||||
for (Range range : ranges) {
|
|
||||||
for (int i = 0; i < numIndexDim; i++) {
|
|
||||||
int offset = i * bytesPerDim;
|
|
||||||
if (comparator.compare(root.minPackedValue, offset, range.getMinPackedValue(), offset)
|
|
||||||
> 0) {
|
|
||||||
System.arraycopy(
|
|
||||||
range.getMinPackedValue(), offset, root.minPackedValue, offset, bytesPerDim);
|
|
||||||
}
|
|
||||||
if (comparator.compare(root.maxPackedValue, offset, range.getMaxPackedValue(), offset)
|
|
||||||
< 0) {
|
|
||||||
System.arraycopy(
|
|
||||||
range.getMaxPackedValue(), offset, root.maxPackedValue, offset, bytesPerDim);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return root;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Creates tree from sorted ranges (with range low and high inclusive) */
|
/** Creates tree from sorted ranges (with range low and high inclusive) */
|
||||||
|
@ -602,50 +588,20 @@ public abstract class MultiRangeQuery extends Query {
|
||||||
if (newNode.left != null) {
|
if (newNode.left != null) {
|
||||||
for (int i = 0; i < numIndexDim; i++) {
|
for (int i = 0; i < numIndexDim; i++) {
|
||||||
int offset = i * bytesPerDim;
|
int offset = i * bytesPerDim;
|
||||||
if (comparator.compare(
|
if (comparator.compare(newNode.maxPackedValue, offset, newNode.left.maxPackedValue, offset)
|
||||||
newNode.minPackedValue, offset, newNode.left.getMinPackedValue(), offset)
|
|
||||||
> 0) {
|
|
||||||
System.arraycopy(
|
|
||||||
newNode.left.getMinPackedValue(),
|
|
||||||
offset,
|
|
||||||
newNode.minPackedValue,
|
|
||||||
offset,
|
|
||||||
bytesPerDim);
|
|
||||||
}
|
|
||||||
if (comparator.compare(
|
|
||||||
newNode.maxPackedValue, offset, newNode.left.getMaxPackedValue(), offset)
|
|
||||||
< 0) {
|
< 0) {
|
||||||
System.arraycopy(
|
System.arraycopy(
|
||||||
newNode.left.getMaxPackedValue(),
|
newNode.left.maxPackedValue, offset, newNode.maxPackedValue, offset, bytesPerDim);
|
||||||
offset,
|
|
||||||
newNode.maxPackedValue,
|
|
||||||
offset,
|
|
||||||
bytesPerDim);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (newNode.right != null) {
|
if (newNode.right != null) {
|
||||||
for (int i = 0; i < numIndexDim; i++) {
|
for (int i = 0; i < numIndexDim; i++) {
|
||||||
int offset = i * bytesPerDim;
|
int offset = i * bytesPerDim;
|
||||||
if (comparator.compare(
|
if (comparator.compare(newNode.maxPackedValue, offset, newNode.right.maxPackedValue, offset)
|
||||||
newNode.minPackedValue, offset, newNode.right.getMinPackedValue(), offset)
|
|
||||||
> 0) {
|
|
||||||
System.arraycopy(
|
|
||||||
newNode.right.getMinPackedValue(),
|
|
||||||
offset,
|
|
||||||
newNode.minPackedValue,
|
|
||||||
offset,
|
|
||||||
bytesPerDim);
|
|
||||||
}
|
|
||||||
if (comparator.compare(
|
|
||||||
newNode.maxPackedValue, offset, newNode.right.getMaxPackedValue(), offset)
|
|
||||||
< 0) {
|
< 0) {
|
||||||
System.arraycopy(
|
System.arraycopy(
|
||||||
newNode.right.getMaxPackedValue(),
|
newNode.right.maxPackedValue, offset, newNode.maxPackedValue, offset, bytesPerDim);
|
||||||
offset,
|
|
||||||
newNode.maxPackedValue,
|
|
||||||
offset,
|
|
||||||
bytesPerDim);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue