Index: lucene/src/java/org/apache/lucene/search/FieldComparator.java =================================================================== --- lucene/src/java/org/apache/lucene/search/FieldComparator.java (revision 962912) +++ lucene/src/java/org/apache/lucene/search/FieldComparator.java (working copy) @@ -703,16 +703,13 @@ private int bottomSlot = -1; private int bottomOrd; + private boolean bottomSameReader; private String bottomValue; - private final boolean reversed; - private final int sortPos; public StringOrdValComparator(int numHits, String field, int sortPos, boolean reversed) { ords = new int[numHits]; values = new String[numHits]; readerGen = new int[numHits]; - this.sortPos = sortPos; - this.reversed = reversed; this.field = field; } @@ -741,53 +738,28 @@ @Override public int compareBottom(int doc) { assert bottomSlot != -1; - int order = this.order[doc]; - final int cmp = bottomOrd - order; - if (cmp != 0) { - return cmp; - } - - final String val2 = lookup[order]; - if (bottomValue == null) { - if (val2 == null) { - return 0; + if (bottomSameReader) { + return bottomOrd - this.order[doc]; + } else { + final int order = this.order[doc]; + final int cmp = bottomOrd - order; + if (cmp != 0) { + return cmp; } - // bottom wins - return -1; - } else if (val2 == null) { - // doc wins - return 1; - } - return bottomValue.compareTo(val2); - } - private void convert(int slot) { - readerGen[slot] = currentReaderGen; - int index = 0; - String value = values[slot]; - if (value == null) { - ords[slot] = 0; - return; - } - - if (sortPos == 0 && bottomSlot != -1 && bottomSlot != slot) { - // Since we are the primary sort, the entries in the - // queue are bounded by bottomOrd: - assert bottomOrd < lookup.length; - if (reversed) { - index = binarySearch(lookup, value, bottomOrd, lookup.length-1); - } else { - index = binarySearch(lookup, value, 0, bottomOrd); + final String val2 = lookup[order]; + if (bottomValue == null) { + if (val2 == null) { + return 0; + } + // bottom wins + return -1; + } else if (val2 == null) { + // doc wins + return 1; } - } else { - // Full binary search - index = binarySearch(lookup, value); + return bottomValue.compareTo(val2); } - - if (index < 0) { - index = -index - 2; - } - ords[slot] = index; } @Override @@ -807,21 +779,30 @@ lookup = currentReaderValues.lookup; assert lookup.length > 0; if (bottomSlot != -1) { - convert(bottomSlot); - bottomOrd = ords[bottomSlot]; + setBottom(bottomSlot); } } @Override public void setBottom(final int bottom) { bottomSlot = bottom; - if (readerGen[bottom] != currentReaderGen) { - convert(bottomSlot); + + bottomValue = values[bottomSlot]; + if (bottomValue == null) { + ords[bottomSlot] = 0; + bottomOrd = 0; + bottomSameReader = true; + } else { + final int index = binarySearch(lookup, bottomValue); + if (index < 0) { + bottomOrd = -index - 2; + bottomSameReader = false; + } else { + bottomOrd = index; + // exact value match + bottomSameReader = true; + } } - bottomOrd = ords[bottom]; - assert bottomOrd >= 0; - assert bottomOrd < lookup.length; - bottomValue = values[bottom]; } @Override