LUCENE-2671: optimizations for numeric sort-missing-last

git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1043820 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Yonik Seeley 2010-12-09 02:05:58 +00:00
parent dbd157c797
commit f6d9b703d6
1 changed files with 125 additions and 76 deletions

View File

@ -38,6 +38,7 @@ import org.apache.lucene.search.cache.CachedArray.FloatValues;
import org.apache.lucene.search.cache.CachedArray.IntValues;
import org.apache.lucene.search.cache.CachedArray.LongValues;
import org.apache.lucene.search.cache.CachedArray.ShortValues;
import org.apache.lucene.util.Bits;
import org.apache.lucene.util.BytesRef;
import org.apache.lucene.util.packed.Direct8;
import org.apache.lucene.util.packed.Direct16;
@ -187,16 +188,25 @@ public abstract class FieldComparator {
protected final CachedArrayCreator<T> creator;
protected T cached;
protected final boolean checkMissing;
protected Bits valid;
public NumericComparator( CachedArrayCreator<T> c, boolean checkMissing ) {
this.creator = c;
this.checkMissing = checkMissing;
}
protected FieldComparator setup(T cached) {
this.cached = cached;
if (checkMissing)
valid = cached.valid;
return this;
}
}
/** Parses field's values as byte (using {@link
* FieldCache#getBytes} and sorts by ascending value */
public static final class ByteComparator extends NumericComparator<ByteValues> {
private byte[] docValues;
private final byte[] values;
private final byte missingValue;
private byte bottom;
@ -215,20 +225,26 @@ public abstract class FieldComparator {
@Override
public int compareBottom(int doc) {
final byte v2 = (checkMissing && !cached.valid.get(doc))
? missingValue : cached.values[doc];
byte v2 = docValues[doc];
if (valid != null && v2==0 && !valid.get(doc))
v2 = missingValue;
return bottom - v2;
}
@Override
public void copy(int slot, int doc) {
values[slot] = ( checkMissing && cached.valid != null && !cached.valid.get(doc) )
? missingValue : cached.values[doc];
byte v2 = docValues[doc];
if (valid != null && v2==0 && !valid.get(doc))
v2 = missingValue;
values[slot] = v2;
}
@Override
public FieldComparator setNextReader(IndexReader reader, int docBase) throws IOException {
cached = FieldCache.DEFAULT.getBytes(reader, creator.field, creator );
setup(FieldCache.DEFAULT.getBytes(reader, creator.field, creator));
docValues = cached.values;
return this;
}
@ -247,6 +263,7 @@ public abstract class FieldComparator {
/** Parses field's values as double (using {@link
* FieldCache#getDoubles} and sorts by ascending value */
public static final class DoubleComparator extends NumericComparator<DoubleValues> {
private double[] docValues;
private final double[] values;
private final double missingValue;
private double bottom;
@ -274,9 +291,10 @@ public abstract class FieldComparator {
@Override
public int compareBottom(int doc) {
final double v2 = (checkMissing && !cached.valid.get(doc))
? missingValue : cached.values[doc];
double v2 = docValues[doc];
if (valid != null && v2==0 && !valid.get(doc))
v2 = missingValue;
if (bottom > v2) {
return 1;
} else if (bottom < v2) {
@ -288,13 +306,17 @@ public abstract class FieldComparator {
@Override
public void copy(int slot, int doc) {
values[slot] = ( checkMissing && cached.valid != null && !cached.valid.get(doc) )
? missingValue : cached.values[doc];
double v2 = docValues[doc];
if (valid != null && v2==0 && !valid.get(doc))
v2 = missingValue;
values[slot] = v2;
}
@Override
public FieldComparator setNextReader(IndexReader reader, int docBase) throws IOException {
cached = FieldCache.DEFAULT.getDoubles(reader, creator.field, creator );
setup(FieldCache.DEFAULT.getDoubles(reader, creator.field, creator));
docValues = cached.values;
return this;
}
@ -312,6 +334,7 @@ public abstract class FieldComparator {
/** Parses field's values as float (using {@link
* FieldCache#getFloats} and sorts by ascending value */
public static final class FloatComparator extends NumericComparator<FloatValues> {
private float[] docValues;
private final float[] values;
private final float missingValue;
private float bottom;
@ -341,8 +364,10 @@ public abstract class FieldComparator {
@Override
public int compareBottom(int doc) {
// TODO: are there sneaky non-branch ways to compute sign of float?
final float v2 = (checkMissing && !cached.valid.get(doc))
? missingValue : cached.values[doc];
float v2 = docValues[doc];
if (valid != null && v2==0 && !valid.get(doc))
v2 = missingValue;
if (bottom > v2) {
return 1;
@ -355,13 +380,17 @@ public abstract class FieldComparator {
@Override
public void copy(int slot, int doc) {
values[slot] = ( checkMissing && cached.valid != null && !cached.valid.get(doc) )
? missingValue : cached.values[doc];
float v2 = docValues[doc];
if (valid != null && v2==0 && !valid.get(doc))
v2 = missingValue;
values[slot] = v2;
}
@Override
public FieldComparator setNextReader(IndexReader reader, int docBase) throws IOException {
cached = FieldCache.DEFAULT.getFloats(reader, creator.field, creator );
setup(FieldCache.DEFAULT.getFloats(reader, creator.field, creator));
docValues = cached.values;
return this;
}
@ -376,9 +405,66 @@ public abstract class FieldComparator {
}
}
/** Parses field's values as short (using {@link
* FieldCache#getShorts} and sorts by ascending value */
public static final class ShortComparator extends NumericComparator<ShortValues> {
private short[] docValues;
private final short[] values;
private short bottom;
private final short missingValue;
ShortComparator(int numHits, ShortValuesCreator creator, Short missingValue ) {
super( creator, missingValue != null );
values = new short[numHits];
this.missingValue = checkMissing
? missingValue.shortValue() : 0;
}
@Override
public int compare(int slot1, int slot2) {
return values[slot1] - values[slot2];
}
@Override
public int compareBottom(int doc) {
short v2 = docValues[doc];
if (valid != null && v2==0 && !valid.get(doc))
v2 = missingValue;
return bottom - v2;
}
@Override
public void copy(int slot, int doc) {
short v2 = docValues[doc];
if (valid != null && v2==0 && !valid.get(doc))
v2 = missingValue;
values[slot] = v2;
}
@Override
public FieldComparator setNextReader(IndexReader reader, int docBase) throws IOException {
setup( FieldCache.DEFAULT.getShorts(reader, creator.field, creator));
docValues = cached.values;
return this;
}
@Override
public void setBottom(final int bottom) {
this.bottom = values[bottom];
}
@Override
public Comparable<?> value(int slot) {
return Short.valueOf(values[slot]);
}
}
/** Parses field's values as int (using {@link
* FieldCache#getInts} and sorts by ascending value */
public static final class IntComparator extends NumericComparator<IntValues> {
private int[] docValues;
private final int[] values;
private int bottom; // Value of bottom of queue
final int missingValue;
@ -413,9 +499,10 @@ public abstract class FieldComparator {
// -1/+1/0 sign
// Cannot return bottom - values[slot2] because that
// may overflow
final int v2 = (checkMissing && !cached.valid.get(doc))
? missingValue : cached.values[doc];
int v2 = docValues[doc];
if (valid != null && v2==0 && !valid.get(doc))
v2 = missingValue;
if (bottom > v2) {
return 1;
} else if (bottom < v2) {
@ -427,13 +514,17 @@ public abstract class FieldComparator {
@Override
public void copy(int slot, int doc) {
values[slot] = ( checkMissing && cached.valid != null && !cached.valid.get(doc) )
? missingValue : cached.values[doc];
int v2 = docValues[doc];
if (valid != null && v2==0 && !valid.get(doc))
v2 = missingValue;
values[slot] = v2;
}
@Override
public FieldComparator setNextReader(IndexReader reader, int docBase) throws IOException {
cached = FieldCache.DEFAULT.getInts(reader, creator.field, creator);
setup(FieldCache.DEFAULT.getInts(reader, creator.field, creator));
docValues = cached.values;
return this;
}
@ -451,6 +542,7 @@ public abstract class FieldComparator {
/** Parses field's values as long (using {@link
* FieldCache#getLongs} and sorts by ascending value */
public static final class LongComparator extends NumericComparator<LongValues> {
private long[] docValues;
private final long[] values;
private long bottom;
private final long missingValue;
@ -481,8 +573,10 @@ public abstract class FieldComparator {
public int compareBottom(int doc) {
// TODO: there are sneaky non-branch ways to compute
// -1/+1/0 sign
final long v2 = (checkMissing && !cached.valid.get(doc))
? missingValue : cached.values[doc];
long v2 = docValues[doc];
if (valid != null && v2==0 && !valid.get(doc))
v2 = missingValue;
if (bottom > v2) {
return 1;
@ -495,13 +589,17 @@ public abstract class FieldComparator {
@Override
public void copy(int slot, int doc) {
values[slot] = ( checkMissing && cached.valid != null && !cached.valid.get(doc) )
? missingValue : cached.values[doc];
long v2 = docValues[doc];
if (valid != null && v2==0 && !valid.get(doc))
v2 = missingValue;
values[slot] = v2;
}
@Override
public FieldComparator setNextReader(IndexReader reader, int docBase) throws IOException {
cached = FieldCache.DEFAULT.getLongs(reader, creator.field, creator);
setup(FieldCache.DEFAULT.getLongs(reader, creator.field, creator));
docValues = cached.values;
return this;
}
@ -572,55 +670,6 @@ public abstract class FieldComparator {
}
}
/** Parses field's values as short (using {@link
* FieldCache#getShorts} and sorts by ascending value */
public static final class ShortComparator extends NumericComparator<ShortValues> {
private final short[] values;
private short bottom;
private final short missingValue;
ShortComparator(int numHits, ShortValuesCreator creator, Short missingValue ) {
super( creator, missingValue != null );
values = new short[numHits];
this.missingValue = checkMissing
? missingValue.shortValue() : 0;
}
@Override
public int compare(int slot1, int slot2) {
return values[slot1] - values[slot2];
}
@Override
public int compareBottom(int doc) {
final short v2 = (checkMissing && !cached.valid.get(doc))
? missingValue : cached.values[doc];
return bottom - v2;
}
@Override
public void copy(int slot, int doc) {
values[slot] = ( checkMissing && cached.valid != null && !cached.valid.get(doc) )
? missingValue : cached.values[doc];
}
@Override
public FieldComparator setNextReader(IndexReader reader, int docBase) throws IOException {
cached = FieldCache.DEFAULT.getShorts(reader, creator.field, creator );
return this;
}
@Override
public void setBottom(final int bottom) {
this.bottom = values[bottom];
}
@Override
public Comparable<?> value(int slot) {
return Short.valueOf(values[slot]);
}
}
/** Sorts by ascending docID */