mirror of https://github.com/apache/lucene.git
LUCENE-2953: PriorityQueue's internal heap was made private final
git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1079707 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
b466795470
commit
bdaa02c3c0
|
@ -202,6 +202,12 @@ API Changes
|
|||
which takes Analyzer as a parameter, for easier customization by subclasses.
|
||||
(Robert Muir)
|
||||
|
||||
* LUCENE-2953: PriorityQueue's internal heap was made private, as subclassing
|
||||
with generics can lead to ClassCastException. For advanced use (e.g. in Solr)
|
||||
a method getHeapArray() was added to retrieve the internal heap array as a
|
||||
non-generic Object[]. Also the initialize(int) function was moved into the
|
||||
ctor. (Uwe Schindler, Yonik Seeley)
|
||||
|
||||
New features
|
||||
|
||||
* LUCENE-2604: Added RegexpQuery support to QueryParser. Regular expressions
|
||||
|
|
|
@ -524,7 +524,7 @@ class FragmentQueue extends PriorityQueue<TextFragment>
|
|||
{
|
||||
public FragmentQueue(int size)
|
||||
{
|
||||
initialize(size);
|
||||
super(size);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -255,7 +255,7 @@ final class TotalTermFreqComparatorSortDescending implements Comparator<TermStat
|
|||
**/
|
||||
final class TermStatsQueue extends PriorityQueue<TermStats> {
|
||||
TermStatsQueue(int size) {
|
||||
initialize(size);
|
||||
super(size);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -335,7 +335,7 @@ public class FuzzyLikeThisQuery extends Query
|
|||
|
||||
private static class ScoreTermQueue extends PriorityQueue<ScoreTerm> {
|
||||
public ScoreTermQueue(int size){
|
||||
initialize(size);
|
||||
super(size);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
|
|
|
@ -1006,7 +1006,7 @@ public final class MoreLikeThis {
|
|||
*/
|
||||
private static class FreqQ extends PriorityQueue<Object[]> {
|
||||
FreqQ (int s) {
|
||||
initialize(s);
|
||||
super(s);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -41,7 +41,7 @@ public final class SuggestWordQueue extends PriorityQueue<SuggestWord> {
|
|||
* @param size The size of the queue
|
||||
*/
|
||||
public SuggestWordQueue (int size) {
|
||||
initialize(size);
|
||||
super(size);
|
||||
comparator = DEFAULT_COMPARATOR;
|
||||
}
|
||||
|
||||
|
@ -51,7 +51,7 @@ public final class SuggestWordQueue extends PriorityQueue<SuggestWord> {
|
|||
* @param comparator The comparator.
|
||||
*/
|
||||
public SuggestWordQueue(int size, Comparator<SuggestWord> comparator){
|
||||
initialize(size);
|
||||
super(size);
|
||||
this.comparator = comparator;
|
||||
}
|
||||
|
||||
|
|
|
@ -129,7 +129,7 @@ public final class MultiFieldsEnum extends FieldsEnum {
|
|||
|
||||
private final static class FieldMergeQueue extends PriorityQueue<FieldsEnumWithSlice> {
|
||||
FieldMergeQueue(int size) {
|
||||
initialize(size);
|
||||
super(size);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -427,7 +427,7 @@ public final class MultiTermsEnum extends TermsEnum {
|
|||
private final static class TermMergeQueue extends PriorityQueue<TermsEnumWithSlice> {
|
||||
Comparator<BytesRef> termComp;
|
||||
TermMergeQueue(int size) {
|
||||
initialize(size);
|
||||
super(size);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -56,15 +56,13 @@ public abstract class FieldValueHitQueue extends PriorityQueue<FieldValueHitQueu
|
|||
|
||||
public OneComparatorFieldValueHitQueue(SortField[] fields, int size)
|
||||
throws IOException {
|
||||
super(fields);
|
||||
super(fields, size);
|
||||
|
||||
SortField field = fields[0];
|
||||
setComparator(0,field.getComparator(size, 0));
|
||||
oneReverseMul = field.reverse ? -1 : 1;
|
||||
|
||||
reverseMul[0] = oneReverseMul;
|
||||
|
||||
initialize(size);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -98,7 +96,7 @@ public abstract class FieldValueHitQueue extends PriorityQueue<FieldValueHitQueu
|
|||
|
||||
public MultiComparatorsFieldValueHitQueue(SortField[] fields, int size)
|
||||
throws IOException {
|
||||
super(fields);
|
||||
super(fields, size);
|
||||
|
||||
int numComparators = comparators.length;
|
||||
for (int i = 0; i < numComparators; ++i) {
|
||||
|
@ -107,8 +105,6 @@ public abstract class FieldValueHitQueue extends PriorityQueue<FieldValueHitQueu
|
|||
reverseMul[i] = field.reverse ? -1 : 1;
|
||||
setComparator(i, field.getComparator(size, i));
|
||||
}
|
||||
|
||||
initialize(size);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -133,7 +129,8 @@ public abstract class FieldValueHitQueue extends PriorityQueue<FieldValueHitQueu
|
|||
}
|
||||
|
||||
// prevent instantiation and extension.
|
||||
private FieldValueHitQueue(SortField[] fields) {
|
||||
private FieldValueHitQueue(SortField[] fields, int size) {
|
||||
super(size);
|
||||
// When we get here, fields.length is guaranteed to be > 0, therefore no
|
||||
// need to check it again.
|
||||
|
||||
|
|
|
@ -63,17 +63,15 @@ final class HitQueue extends PriorityQueue<ScoreDoc> {
|
|||
* @see #getSentinelObject()
|
||||
*/
|
||||
HitQueue(int size, boolean prePopulate) {
|
||||
this.prePopulate = prePopulate;
|
||||
initialize(size);
|
||||
super(size, prePopulate);
|
||||
}
|
||||
|
||||
// Returns null if prePopulate is false.
|
||||
@Override
|
||||
protected ScoreDoc getSentinelObject() {
|
||||
// Always set the doc Id to MAX_VALUE so that it won't be favored by
|
||||
// lessThan. This generally should not happen since if score is not NEG_INF,
|
||||
// TopScoreDocCollector will always add the object to the queue.
|
||||
return !prePopulate ? null : new ScoreDoc(Integer.MAX_VALUE, Float.NEGATIVE_INFINITY);
|
||||
return new ScoreDoc(Integer.MAX_VALUE, Float.NEGATIVE_INFINITY);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -432,7 +432,7 @@ class UnionDocsAndPositionsEnum extends DocsAndPositionsEnum {
|
|||
|
||||
private static final class DocsQueue extends PriorityQueue<DocsAndPositionsEnum> {
|
||||
DocsQueue(List<DocsAndPositionsEnum> docsEnums) throws IOException {
|
||||
initialize(docsEnums.size());
|
||||
super(docsEnums.size());
|
||||
|
||||
Iterator<DocsAndPositionsEnum> i = docsEnums.iterator();
|
||||
while (i.hasNext()) {
|
||||
|
|
|
@ -21,7 +21,7 @@ import org.apache.lucene.util.PriorityQueue;
|
|||
|
||||
final class PhraseQueue extends PriorityQueue<PhrasePositions> {
|
||||
PhraseQueue(int size) {
|
||||
initialize(size);
|
||||
super(size);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -53,7 +53,7 @@ public class NearSpansUnordered extends Spans {
|
|||
|
||||
private class CellQueue extends PriorityQueue<SpansCell> {
|
||||
public CellQueue(int size) {
|
||||
initialize(size);
|
||||
super(size);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -145,7 +145,7 @@ public class SpanOrQuery extends SpanQuery implements Cloneable {
|
|||
|
||||
private class SpanQueue extends PriorityQueue<Spans> {
|
||||
public SpanQueue(int size) {
|
||||
initialize(size);
|
||||
super(size);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -28,8 +28,52 @@ package org.apache.lucene.util;
|
|||
*/
|
||||
public abstract class PriorityQueue<T> {
|
||||
private int size;
|
||||
private int maxSize;
|
||||
protected T[] heap;
|
||||
private final int maxSize;
|
||||
private final T[] heap;
|
||||
|
||||
public PriorityQueue(int maxSize) {
|
||||
this(maxSize, true);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public PriorityQueue(int maxSize, boolean prepopulate) {
|
||||
size = 0;
|
||||
int heapSize;
|
||||
if (0 == maxSize)
|
||||
// We allocate 1 extra to avoid if statement in top()
|
||||
heapSize = 2;
|
||||
else {
|
||||
if (maxSize == Integer.MAX_VALUE) {
|
||||
// Don't wrap heapSize to -1, in this case, which
|
||||
// causes a confusing NegativeArraySizeException.
|
||||
// Note that very likely this will simply then hit
|
||||
// an OOME, but at least that's more indicative to
|
||||
// caller that this values is too big. We don't +1
|
||||
// in this case, but it's very unlikely in practice
|
||||
// one will actually insert this many objects into
|
||||
// the PQ:
|
||||
heapSize = Integer.MAX_VALUE;
|
||||
} else {
|
||||
// NOTE: we add +1 because all access to heap is
|
||||
// 1-based not 0-based. heap[0] is unused.
|
||||
heapSize = maxSize + 1;
|
||||
}
|
||||
}
|
||||
heap = (T[]) new Object[heapSize]; // T is unbounded type, so this unchecked cast works always
|
||||
this.maxSize = maxSize;
|
||||
|
||||
if (prepopulate) {
|
||||
// If sentinel objects are supported, populate the queue with them
|
||||
T sentinel = getSentinelObject();
|
||||
if (sentinel != null) {
|
||||
heap[1] = sentinel;
|
||||
for (int i = 2; i < heap.length; i++) {
|
||||
heap[i] = getSentinelObject();
|
||||
}
|
||||
size = maxSize;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** Determines the ordering of objects in this priority queue. Subclasses
|
||||
* must define this one method.
|
||||
|
@ -80,45 +124,6 @@ public abstract class PriorityQueue<T> {
|
|||
return null;
|
||||
}
|
||||
|
||||
/** Subclass constructors must call this. */
|
||||
@SuppressWarnings("unchecked")
|
||||
protected final void initialize(int maxSize) {
|
||||
size = 0;
|
||||
int heapSize;
|
||||
if (0 == maxSize)
|
||||
// We allocate 1 extra to avoid if statement in top()
|
||||
heapSize = 2;
|
||||
else {
|
||||
if (maxSize == Integer.MAX_VALUE) {
|
||||
// Don't wrap heapSize to -1, in this case, which
|
||||
// causes a confusing NegativeArraySizeException.
|
||||
// Note that very likely this will simply then hit
|
||||
// an OOME, but at least that's more indicative to
|
||||
// caller that this values is too big. We don't +1
|
||||
// in this case, but it's very unlikely in practice
|
||||
// one will actually insert this many objects into
|
||||
// the PQ:
|
||||
heapSize = Integer.MAX_VALUE;
|
||||
} else {
|
||||
// NOTE: we add +1 because all access to heap is
|
||||
// 1-based not 0-based. heap[0] is unused.
|
||||
heapSize = maxSize + 1;
|
||||
}
|
||||
}
|
||||
heap = (T[]) new Object[heapSize]; // T is unbounded type, so this unchecked cast works always
|
||||
this.maxSize = maxSize;
|
||||
|
||||
// If sentinel objects are supported, populate the queue with them
|
||||
T sentinel = getSentinelObject();
|
||||
if (sentinel != null) {
|
||||
heap[1] = sentinel;
|
||||
for (int i = 2; i < heap.length; i++) {
|
||||
heap[i] = getSentinelObject();
|
||||
}
|
||||
size = maxSize;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds an Object to a PriorityQueue in log(size) time. If one tries to add
|
||||
* more objects than maxSize from initialize an
|
||||
|
@ -247,4 +252,11 @@ public abstract class PriorityQueue<T> {
|
|||
}
|
||||
heap[i] = node; // install saved node
|
||||
}
|
||||
|
||||
/** This method returns the internal heap array as Object[].
|
||||
* @lucene.internal
|
||||
*/
|
||||
protected final Object[] getHeapArray() {
|
||||
return (Object[]) heap;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,8 +23,7 @@ public class TestPriorityQueue extends LuceneTestCase {
|
|||
|
||||
private static class IntegerQueue extends PriorityQueue<Integer> {
|
||||
public IntegerQueue(int count) {
|
||||
super();
|
||||
initialize(count);
|
||||
super(count);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -124,7 +124,7 @@ public class QualityQueriesFinder {
|
|||
|
||||
private static class TermsDfQueue extends PriorityQueue<TermDf> {
|
||||
TermsDfQueue (int maxSize) {
|
||||
initialize(maxSize);
|
||||
super(maxSize);
|
||||
}
|
||||
@Override
|
||||
protected boolean lessThan(TermDf tf1, TermDf tf2) {
|
||||
|
|
|
@ -354,13 +354,17 @@ public class ConcurrentLRUCache<K,V> {
|
|||
|
||||
private static class PQueue<K,V> extends PriorityQueue<CacheEntry<K,V>> {
|
||||
int myMaxSize;
|
||||
final Object[] heap;
|
||||
|
||||
PQueue(int maxSz) {
|
||||
super.initialize(maxSz);
|
||||
super(maxSz);
|
||||
heap = getHeapArray();
|
||||
myMaxSize = maxSz;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
Iterable<CacheEntry<K,V>> getValues() {
|
||||
return Collections.unmodifiableCollection(Arrays.asList(heap));
|
||||
return (Iterable) Collections.unmodifiableCollection(Arrays.asList(heap));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -370,12 +374,13 @@ public class ConcurrentLRUCache<K,V> {
|
|||
}
|
||||
|
||||
// necessary because maxSize is private in base class
|
||||
@SuppressWarnings("unchecked")
|
||||
public CacheEntry<K,V> myInsertWithOverflow(CacheEntry<K,V> element) {
|
||||
if (size() < myMaxSize) {
|
||||
add(element);
|
||||
return null;
|
||||
} else if (size() > 0 && !lessThan(element, heap[1])) {
|
||||
CacheEntry<K,V> ret = heap[1];
|
||||
} else if (size() > 0 && !lessThan(element, (CacheEntry<K,V>) heap[1])) {
|
||||
CacheEntry<K,V> ret = (CacheEntry<K,V>) heap[1];
|
||||
heap[1] = element;
|
||||
updateTop();
|
||||
return ret;
|
||||
|
|
|
@ -586,7 +586,7 @@ public class LukeRequestHandler extends RequestHandlerBase
|
|||
public TermHistogram histogram;
|
||||
|
||||
TopTermQueue(int size) {
|
||||
initialize(size);
|
||||
super(size);
|
||||
histogram = new TermHistogram();
|
||||
}
|
||||
|
||||
|
|
|
@ -82,6 +82,7 @@ class ShardFieldSortedHitQueue extends PriorityQueue {
|
|||
protected List<String> fieldNames = new ArrayList<String>();
|
||||
|
||||
public ShardFieldSortedHitQueue(SortField[] fields, int size) {
|
||||
super(size);
|
||||
final int n = fields.length;
|
||||
comparators = new Comparator[n];
|
||||
this.fields = new SortField[n];
|
||||
|
@ -107,8 +108,6 @@ class ShardFieldSortedHitQueue extends PriorityQueue {
|
|||
|
||||
//System.out.println("%%%%%%%%%%%%%%%%%% got "+fields[i].getType() +" for "+ fieldname +" fields[i].getReverse(): "+fields[i].getReverse());
|
||||
}
|
||||
|
||||
initialize(size);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -114,10 +114,7 @@ class PerSegmentSingleValuedFaceting {
|
|||
|
||||
|
||||
// now merge the per-segment results
|
||||
PriorityQueue<SegFacet> queue = new PriorityQueue<SegFacet>() {
|
||||
{
|
||||
initialize(leaves.length);
|
||||
}
|
||||
PriorityQueue<SegFacet> queue = new PriorityQueue<SegFacet>(leaves.length) {
|
||||
@Override
|
||||
protected boolean lessThan(SegFacet a, SegFacet b) {
|
||||
return a.tempBR.compareTo(b.tempBR) < 0;
|
||||
|
|
|
@ -39,7 +39,7 @@ public abstract class Lookup {
|
|||
public static final class LookupPriorityQueue extends PriorityQueue<LookupResult> {
|
||||
|
||||
public LookupPriorityQueue(int size) {
|
||||
initialize(size);
|
||||
super(size);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
Loading…
Reference in New Issue