From 11e962d16b2a898ac3475a9f3d09fc328a9d2461 Mon Sep 17 00:00:00 2001 From: Uwe Schindler Date: Tue, 3 May 2011 13:07:24 +0000 Subject: [PATCH] LUCENE-3054: fix remaining quickSort git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1099041 13f79535-47bb-0310-9956-ffa450edef68 --- .../lucene/search/highlight/TokenSources.java | 2 +- .../org/apache/lucene/index/IndexReader.java | 2 +- .../lucene/search/MultiPhraseQuery.java | 2 +- .../org/apache/lucene/search/PhraseQuery.java | 2 +- .../apache/lucene/search/TopTermsRewrite.java | 2 +- .../lucene/search/spans/NearSpansOrdered.java | 2 +- .../apache/lucene/util/SorterTemplate.java | 26 +++++++++---------- 7 files changed, 19 insertions(+), 19 deletions(-) diff --git a/lucene/contrib/highlighter/src/java/org/apache/lucene/search/highlight/TokenSources.java b/lucene/contrib/highlighter/src/java/org/apache/lucene/search/highlight/TokenSources.java index 616d9e26670..9a9294f93fd 100644 --- a/lucene/contrib/highlighter/src/java/org/apache/lucene/search/highlight/TokenSources.java +++ b/lucene/contrib/highlighter/src/java/org/apache/lucene/search/highlight/TokenSources.java @@ -231,7 +231,7 @@ public class TokenSources { if (unsortedTokens != null) { tokensInOriginalOrder = unsortedTokens.toArray(new Token[unsortedTokens .size()]); - ArrayUtil.quickSort(tokensInOriginalOrder, new Comparator() { + ArrayUtil.mergeSort(tokensInOriginalOrder, new Comparator() { public int compare(Token t1, Token t2) { if (t1.startOffset() == t2.startOffset()) return t1.endOffset() - t2.endOffset(); diff --git a/lucene/src/java/org/apache/lucene/index/IndexReader.java b/lucene/src/java/org/apache/lucene/index/IndexReader.java index 9f3494c4654..b0f87f1913b 100644 --- a/lucene/src/java/org/apache/lucene/index/IndexReader.java +++ b/lucene/src/java/org/apache/lucene/index/IndexReader.java @@ -1420,7 +1420,7 @@ public abstract class IndexReader implements Cloneable,Closeable { cfr = new CompoundFileReader(dir, filename); String [] files = cfr.listAll(); - ArrayUtil.quickSort(files); // sort the array of filename so that the output is more readable + ArrayUtil.mergeSort(files); // sort the array of filename so that the output is more readable for (int i = 0; i < files.length; ++i) { long len = cfr.fileLength(files[i]); diff --git a/lucene/src/java/org/apache/lucene/search/MultiPhraseQuery.java b/lucene/src/java/org/apache/lucene/search/MultiPhraseQuery.java index 8e18b520263..fc9598078d8 100644 --- a/lucene/src/java/org/apache/lucene/search/MultiPhraseQuery.java +++ b/lucene/src/java/org/apache/lucene/search/MultiPhraseQuery.java @@ -219,7 +219,7 @@ public class MultiPhraseQuery extends Query { // sort by increasing docFreq order if (slop == 0) { - ArrayUtil.quickSort(postingsFreqs); + ArrayUtil.mergeSort(postingsFreqs); } if (slop == 0) { diff --git a/lucene/src/java/org/apache/lucene/search/PhraseQuery.java b/lucene/src/java/org/apache/lucene/search/PhraseQuery.java index a23bdbe69f6..70adec70f7f 100644 --- a/lucene/src/java/org/apache/lucene/search/PhraseQuery.java +++ b/lucene/src/java/org/apache/lucene/search/PhraseQuery.java @@ -234,7 +234,7 @@ public class PhraseQuery extends Query { // sort by increasing docFreq order if (slop == 0) { - ArrayUtil.quickSort(postingsFreqs); + ArrayUtil.mergeSort(postingsFreqs); } if (slop == 0) { // optimize exact case diff --git a/lucene/src/java/org/apache/lucene/search/TopTermsRewrite.java b/lucene/src/java/org/apache/lucene/search/TopTermsRewrite.java index 472e99de705..24356e27bcf 100644 --- a/lucene/src/java/org/apache/lucene/search/TopTermsRewrite.java +++ b/lucene/src/java/org/apache/lucene/search/TopTermsRewrite.java @@ -134,7 +134,7 @@ public abstract class TopTermsRewrite extends TermCollectingRew final Term placeholderTerm = new Term(query.field); final Q q = getTopLevelQuery(); final ScoreTerm[] scoreTerms = stQueue.toArray(new ScoreTerm[stQueue.size()]); - ArrayUtil.quickSort(scoreTerms, scoreTermSortByTermComp); + ArrayUtil.mergeSort(scoreTerms, scoreTermSortByTermComp); for (final ScoreTerm st : scoreTerms) { final Term term = placeholderTerm.createTerm(st.bytes); assert reader.docFreq(term) == st.termState.docFreq() : "reader DF is " + reader.docFreq(term) + " vs " + st.termState.docFreq(); diff --git a/lucene/src/java/org/apache/lucene/search/spans/NearSpansOrdered.java b/lucene/src/java/org/apache/lucene/search/spans/NearSpansOrdered.java index 2bc9f87d27f..0eae1582573 100644 --- a/lucene/src/java/org/apache/lucene/search/spans/NearSpansOrdered.java +++ b/lucene/src/java/org/apache/lucene/search/spans/NearSpansOrdered.java @@ -190,7 +190,7 @@ public class NearSpansOrdered extends Spans { /** Advance the subSpans to the same document */ private boolean toSameDoc() throws IOException { - ArrayUtil.quickSort(subSpansByDoc, spanDocComparator); + ArrayUtil.mergeSort(subSpansByDoc, spanDocComparator); int firstIndex = 0; int maxDoc = subSpansByDoc[subSpansByDoc.length - 1].doc(); while (subSpansByDoc[firstIndex].doc() != maxDoc) { diff --git a/lucene/src/java/org/apache/lucene/util/SorterTemplate.java b/lucene/src/java/org/apache/lucene/util/SorterTemplate.java index 8ff57532c92..1ce4619984f 100644 --- a/lucene/src/java/org/apache/lucene/util/SorterTemplate.java +++ b/lucene/src/java/org/apache/lucene/util/SorterTemplate.java @@ -30,7 +30,6 @@ package org.apache.lucene.util; public abstract class SorterTemplate { private static final int MERGESORT_THRESHOLD = 12; - private static final int MERGE_TO_QUICKSORT_THRESHOLD = 40; private static final int QUICKSORT_THRESHOLD = 7; /** Implement this method, that swaps slots {@code i} and {@code j} in your data */ @@ -63,17 +62,26 @@ public abstract class SorterTemplate { /** Sorts via in-place, but unstable, QuickSort algorithm. * For small collections falls back to {@link #insertionSort(int,int)}. */ - public final void quickSort(int lo, int hi) { - quickSort(lo, hi, MERGE_TO_QUICKSORT_THRESHOLD); + public final void quickSort(final int lo, final int hi) { + if (hi <= lo) return; + // from Integer's Javadocs: ceil(log2(x)) = 32 - numberOfLeadingZeros(x - 1) + quickSort(lo, hi, (Integer.SIZE - Integer.numberOfLeadingZeros(hi - lo)) << 1); } private void quickSort(int lo, int hi, int maxDepth) { + // fall back to insertion when array has short length final int diff = hi - lo; if (diff <= QUICKSORT_THRESHOLD) { insertionSort(lo, hi); return; } + // fall back to merge sort when recursion depth gets too big + if (--maxDepth == 0) { + mergeSort(lo, hi); + return; + } + final int mid = lo + (diff >>> 1); if (compare(lo, mid) > 0) { @@ -106,16 +114,8 @@ public abstract class SorterTemplate { } } - // fall back to merge sort when recursion depth gets too big - if (maxDepth == 0) { - // for testing: new Exception("Hit recursion depth limit").printStackTrace(); - mergeSort(lo, left); - mergeSort(left + 1, hi); - } else { - --maxDepth; - quickSort(lo, left, maxDepth); - quickSort(left + 1, hi, maxDepth); - } + quickSort(lo, left, maxDepth); + quickSort(left + 1, hi, maxDepth); } /** Sorts via stable in-place MergeSort algorithm