mirror of https://github.com/apache/lucene.git
LUCENE-5493: merge Sorter and SortSorter (in progress)
git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/branches/lucene5493@1574949 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
44e2e3155f
commit
328fdf9217
|
@ -1,96 +0,0 @@
|
|||
package org.apache.lucene.index.sorter;
|
||||
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import org.apache.lucene.index.AtomicReader;
|
||||
import org.apache.lucene.search.FieldComparator;
|
||||
import org.apache.lucene.search.Scorer;
|
||||
import org.apache.lucene.search.Sort;
|
||||
import org.apache.lucene.search.SortField;
|
||||
|
||||
// nocommit: temporary class to engage the cutover!
|
||||
class SortSorter extends Sorter {
|
||||
final Sort sort;
|
||||
|
||||
public SortSorter(Sort sort) {
|
||||
this.sort = sort;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DocMap sort(AtomicReader reader) throws IOException {
|
||||
SortField fields[] = sort.getSort();
|
||||
final int reverseMul[] = new int[fields.length];
|
||||
final FieldComparator<?> comparators[] = new FieldComparator[fields.length];
|
||||
|
||||
for (int i = 0; i < fields.length; i++) {
|
||||
reverseMul[i] = fields[i].getReverse() ? -1 : 1;
|
||||
comparators[i] = fields[i].getComparator(1, i);
|
||||
comparators[i].setNextReader(reader.getContext());
|
||||
comparators[i].setScorer(FAKESCORER);
|
||||
}
|
||||
final DocComparator comparator = new DocComparator() {
|
||||
@Override
|
||||
public int compare(int docID1, int docID2) {
|
||||
try {
|
||||
for (int i = 0; i < comparators.length; i++) {
|
||||
// TODO: would be better if copy() didnt cause a term lookup in TermOrdVal & co,
|
||||
// the segments are always the same here...
|
||||
comparators[i].copy(0, docID1);
|
||||
comparators[i].setBottom(0);
|
||||
int comp = reverseMul[i] * comparators[i].compareBottom(docID2);
|
||||
if (comp != 0) {
|
||||
return comp;
|
||||
}
|
||||
}
|
||||
return Integer.compare(docID1, docID2); // docid order tiebreak
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
};
|
||||
return sort(reader.maxDoc(), comparator);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getID() {
|
||||
return sort.toString();
|
||||
}
|
||||
|
||||
static final Scorer FAKESCORER = new Scorer(null) {
|
||||
|
||||
@Override
|
||||
public float score() throws IOException { throw new UnsupportedOperationException(); }
|
||||
|
||||
@Override
|
||||
public int freq() throws IOException { throw new UnsupportedOperationException(); }
|
||||
|
||||
@Override
|
||||
public int docID() { throw new UnsupportedOperationException(); }
|
||||
|
||||
@Override
|
||||
public int nextDoc() throws IOException { throw new UnsupportedOperationException(); }
|
||||
|
||||
@Override
|
||||
public int advance(int target) throws IOException { throw new UnsupportedOperationException(); }
|
||||
|
||||
@Override
|
||||
public long cost() { throw new UnsupportedOperationException(); }
|
||||
};
|
||||
}
|
|
@ -22,19 +22,25 @@ import java.util.Comparator;
|
|||
|
||||
import org.apache.lucene.index.AtomicReader;
|
||||
import org.apache.lucene.index.IndexReader;
|
||||
import org.apache.lucene.search.FieldComparator;
|
||||
import org.apache.lucene.search.Scorer;
|
||||
import org.apache.lucene.search.Sort;
|
||||
import org.apache.lucene.search.SortField;
|
||||
import org.apache.lucene.util.TimSorter;
|
||||
import org.apache.lucene.util.packed.MonotonicAppendingLongBuffer;
|
||||
|
||||
/**
|
||||
* Sorts documents of a given index by returning a permutation on the document
|
||||
* IDs.
|
||||
* <p><b>NOTE</b>: A {@link Sorter} implementation can be easily written from
|
||||
* a {@link DocComparator document comparator} by using the
|
||||
* {@link #sort(int, DocComparator)} helper method. This is especially useful
|
||||
* when documents are directly comparable by their field values.
|
||||
* @lucene.experimental
|
||||
*/
|
||||
abstract class Sorter {
|
||||
final class Sorter {
|
||||
final Sort sort;
|
||||
|
||||
/** Creates a new Sorter to sort the index with {@code sort} */
|
||||
Sorter(Sort sort) {
|
||||
this.sort = sort;
|
||||
}
|
||||
|
||||
/**
|
||||
* A permutation of doc IDs. For every document ID between <tt>0</tt> and
|
||||
|
@ -54,7 +60,6 @@ abstract class Sorter {
|
|||
* {@link AtomicReader#maxDoc() number of documents} of the
|
||||
* {@link AtomicReader} which is sorted. */
|
||||
public abstract int size();
|
||||
|
||||
}
|
||||
|
||||
/** Check consistency of a {@link DocMap}, useful for assertions. */
|
||||
|
@ -202,7 +207,39 @@ abstract class Sorter {
|
|||
* <b>NOTE:</b> deleted documents are expected to appear in the mapping as
|
||||
* well, they will however be marked as deleted in the sorted view.
|
||||
*/
|
||||
public abstract DocMap sort(AtomicReader reader) throws IOException;
|
||||
public DocMap sort(AtomicReader reader) throws IOException {
|
||||
SortField fields[] = sort.getSort();
|
||||
final int reverseMul[] = new int[fields.length];
|
||||
final FieldComparator<?> comparators[] = new FieldComparator[fields.length];
|
||||
|
||||
for (int i = 0; i < fields.length; i++) {
|
||||
reverseMul[i] = fields[i].getReverse() ? -1 : 1;
|
||||
comparators[i] = fields[i].getComparator(1, i);
|
||||
comparators[i].setNextReader(reader.getContext());
|
||||
comparators[i].setScorer(FAKESCORER);
|
||||
}
|
||||
final DocComparator comparator = new DocComparator() {
|
||||
@Override
|
||||
public int compare(int docID1, int docID2) {
|
||||
try {
|
||||
for (int i = 0; i < comparators.length; i++) {
|
||||
// TODO: would be better if copy() didnt cause a term lookup in TermOrdVal & co,
|
||||
// the segments are always the same here...
|
||||
comparators[i].copy(0, docID1);
|
||||
comparators[i].setBottom(0);
|
||||
int comp = reverseMul[i] * comparators[i].compareBottom(docID2);
|
||||
if (comp != 0) {
|
||||
return comp;
|
||||
}
|
||||
}
|
||||
return Integer.compare(docID1, docID2); // docid order tiebreak
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
};
|
||||
return sort(reader.maxDoc(), comparator);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the identifier of this {@link Sorter}.
|
||||
|
@ -211,11 +248,34 @@ abstract class Sorter {
|
|||
* will have the same identifier. On the contrary, this identifier should be
|
||||
* different on different {@link Sorter sorters}.
|
||||
*/
|
||||
public abstract String getID();
|
||||
public String getID() {
|
||||
return sort.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return getID();
|
||||
}
|
||||
|
||||
static final Scorer FAKESCORER = new Scorer(null) {
|
||||
|
||||
@Override
|
||||
public float score() throws IOException { throw new UnsupportedOperationException(); }
|
||||
|
||||
@Override
|
||||
public int freq() throws IOException { throw new UnsupportedOperationException(); }
|
||||
|
||||
@Override
|
||||
public int docID() { throw new UnsupportedOperationException(); }
|
||||
|
||||
@Override
|
||||
public int nextDoc() throws IOException { throw new UnsupportedOperationException(); }
|
||||
|
||||
@Override
|
||||
public int advance(int target) throws IOException { throw new UnsupportedOperationException(); }
|
||||
|
||||
@Override
|
||||
public long cost() { throw new UnsupportedOperationException(); }
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -712,7 +712,7 @@ public class SortingAtomicReader extends FilterAtomicReader {
|
|||
* defined by <code>sorter</code>. If the reader is already sorted, this
|
||||
* method might return the reader as-is. */
|
||||
public static AtomicReader wrap(AtomicReader reader, Sort sort) throws IOException {
|
||||
return wrap(reader, new SortSorter(sort).sort(reader));
|
||||
return wrap(reader, new Sorter(sort).sort(reader));
|
||||
}
|
||||
|
||||
/** Expert: same as {@link #wrap(AtomicReader, Sort)} but operates directly on a {@link Sorter.DocMap}. */
|
||||
|
|
|
@ -179,7 +179,7 @@ public final class SortingMergePolicy extends MergePolicy {
|
|||
/** Create a new {@link MergePolicy} that sorts documents with <code>sort</code>. */
|
||||
public SortingMergePolicy(MergePolicy in, Sort sort) {
|
||||
this.in = in;
|
||||
this.sorter = new SortSorter(sort);
|
||||
this.sorter = new Sorter(sort);
|
||||
this.sort = sort;
|
||||
}
|
||||
|
||||
|
|
|
@ -33,7 +33,7 @@ public class SortingAtomicReaderTest extends SorterTestBase {
|
|||
|
||||
// sort the index by id (as integer, in NUMERIC_DV_FIELD)
|
||||
Sort sort = new Sort(new SortField(NUMERIC_DV_FIELD, SortField.Type.INT));
|
||||
final Sorter.DocMap docMap = new SortSorter(sort).sort(reader);
|
||||
final Sorter.DocMap docMap = new Sorter(sort).sort(reader);
|
||||
|
||||
// Sorter.compute also sorts the values
|
||||
NumericDocValues dv = reader.getNumericDocValues(NUMERIC_DV_FIELD);
|
||||
|
|
|
@ -98,7 +98,7 @@ public class TestBlockJoinSorter extends LuceneTestCase {
|
|||
final Sort childSort = new Sort(new SortField("child_val", SortField.Type.LONG));
|
||||
|
||||
final Sort sort = new Sort(new SortField("custom", new BlockJoinComparatorSource(parentsFilter, parentSort, childSort)));
|
||||
final Sorter sorter = new SortSorter(sort);
|
||||
final Sorter sorter = new Sorter(sort);
|
||||
final Sorter.DocMap docMap = sorter.sort(reader);
|
||||
assertEquals(reader.maxDoc(), docMap.size());
|
||||
|
||||
|
|
Loading…
Reference in New Issue