mirror of https://github.com/apache/lucene.git
LUCENE-8600: Use a faster sort in DocValuesFieldUpdates.
This commit is contained in:
parent
d185ba99de
commit
dcd4a288b4
|
@ -286,6 +286,10 @@ Optimizations
|
||||||
* LUCENE-8599: Use sparse bitset to store docs in SingleValueDocValuesFieldUpdates.
|
* LUCENE-8599: Use sparse bitset to store docs in SingleValueDocValuesFieldUpdates.
|
||||||
(Simon Willnauer, Adrien Grand)
|
(Simon Willnauer, Adrien Grand)
|
||||||
|
|
||||||
|
* LUCENE-8600: Doc-value updates get applied faster by sorting with quicksort,
|
||||||
|
rather than an in-place mergesort, which needs to perform fewer swaps.
|
||||||
|
(Adrien Grand)
|
||||||
|
|
||||||
Other
|
Other
|
||||||
|
|
||||||
* LUCENE-8573: BKDWriter now uses FutureArrays#mismatch to compute shared prefixes.
|
* LUCENE-8573: BKDWriter now uses FutureArrays#mismatch to compute shared prefixes.
|
||||||
|
|
|
@ -21,7 +21,7 @@ import org.apache.lucene.util.Accountable;
|
||||||
import org.apache.lucene.util.BitSet;
|
import org.apache.lucene.util.BitSet;
|
||||||
import org.apache.lucene.util.BitSetIterator;
|
import org.apache.lucene.util.BitSetIterator;
|
||||||
import org.apache.lucene.util.BytesRef;
|
import org.apache.lucene.util.BytesRef;
|
||||||
import org.apache.lucene.util.InPlaceMergeSorter;
|
import org.apache.lucene.util.IntroSorter;
|
||||||
import org.apache.lucene.util.PriorityQueue;
|
import org.apache.lucene.util.PriorityQueue;
|
||||||
import org.apache.lucene.util.RamUsageEstimator;
|
import org.apache.lucene.util.RamUsageEstimator;
|
||||||
import org.apache.lucene.util.SparseFixedBitSet;
|
import org.apache.lucene.util.SparseFixedBitSet;
|
||||||
|
@ -289,20 +289,57 @@ abstract class DocValuesFieldUpdates implements Accountable {
|
||||||
if (size < docs.size()) {
|
if (size < docs.size()) {
|
||||||
resize(size);
|
resize(size);
|
||||||
}
|
}
|
||||||
new InPlaceMergeSorter() {
|
if (size > 0) {
|
||||||
@Override
|
// We need a stable sort but InPlaceMergeSorter performs lots of swaps
|
||||||
protected void swap(int i, int j) {
|
// which hurts performance due to all the packed ints we are using.
|
||||||
DocValuesFieldUpdates.this.swap(i, j);
|
// Another option would be TimSorter, but it needs additional API (copy to
|
||||||
|
// temp storage, compare with item in temp storage, etc.) so we instead
|
||||||
|
// use quicksort and record ords of each update to guarantee stability.
|
||||||
|
final PackedInts.Mutable ords = PackedInts.getMutable(size, PackedInts.bitsRequired(size - 1), PackedInts.DEFAULT);
|
||||||
|
for (int i = 0; i < size; ++i) {
|
||||||
|
ords.set(i, i);
|
||||||
}
|
}
|
||||||
|
new IntroSorter() {
|
||||||
|
@Override
|
||||||
|
protected void swap(int i, int j) {
|
||||||
|
final long tmpOrd = ords.get(i);
|
||||||
|
ords.set(i, ords.get(j));
|
||||||
|
ords.set(j, tmpOrd);
|
||||||
|
|
||||||
@Override
|
DocValuesFieldUpdates.this.swap(i, j);
|
||||||
protected int compare(int i, int j) {
|
}
|
||||||
// increasing docID order:
|
|
||||||
// NOTE: we can have ties here, when the same docID was updated in the same segment, in which case we rely on sort being
|
@Override
|
||||||
// stable and preserving original order so the last update to that docID wins
|
protected int compare(int i, int j) {
|
||||||
return Long.compare(docs.get(i)>>>1, docs.get(j)>>>1);
|
// increasing docID order:
|
||||||
}
|
// NOTE: we can have ties here, when the same docID was updated in the same segment, in which case we rely on sort being
|
||||||
}.sort(0, size);
|
// stable and preserving original order so the last update to that docID wins
|
||||||
|
int cmp = Long.compare(docs.get(i)>>>1, docs.get(j)>>>1);
|
||||||
|
if (cmp == 0) {
|
||||||
|
cmp = (int) (ords.get(i) - ords.get(j));
|
||||||
|
}
|
||||||
|
return cmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
long pivotDoc;
|
||||||
|
int pivotOrd;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void setPivot(int i) {
|
||||||
|
pivotDoc = docs.get(i) >>> 1;
|
||||||
|
pivotOrd = (int) ords.get(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected int comparePivot(int j) {
|
||||||
|
int cmp = Long.compare(pivotDoc, docs.get(j) >>> 1);
|
||||||
|
if (cmp == 0) {
|
||||||
|
cmp = pivotOrd - (int) ords.get(j);
|
||||||
|
}
|
||||||
|
return cmp;
|
||||||
|
}
|
||||||
|
}.sort(0, size);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Returns true if this instance contains any updates. */
|
/** Returns true if this instance contains any updates. */
|
||||||
|
|
Loading…
Reference in New Issue