Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/Lucene.Net.Light.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/Util/ScorerDocQueue.cs')
-rw-r--r--src/core/Util/ScorerDocQueue.cs275
1 files changed, 275 insertions, 0 deletions
diff --git a/src/core/Util/ScorerDocQueue.cs b/src/core/Util/ScorerDocQueue.cs
new file mode 100644
index 0000000..ee6c259
--- /dev/null
+++ b/src/core/Util/ScorerDocQueue.cs
@@ -0,0 +1,275 @@
+/*
+ * 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.
+ */
+
+
+/* Derived from Lucene.Net.Util.PriorityQueue of March 2005 */
+using System;
+using Lucene.Net.Support;
+using DocIdSetIterator = Lucene.Net.Search.DocIdSetIterator;
+using Scorer = Lucene.Net.Search.Scorer;
+
+namespace Lucene.Net.Util
+{
+
+ /// <summary>A ScorerDocQueue maintains a partial ordering of its Scorers such that the
+ /// least Scorer can always be found in constant time. Put()'s and pop()'s
+ /// require log(size) time. The ordering is by Scorer.doc().
+ /// </summary>
+ public class ScorerDocQueue
+ {
+ // later: SpansQueue for spans with doc and term positions
+ private HeapedScorerDoc[] heap;
+ private int maxSize;
+ private int size;
+
+ private class HeapedScorerDoc
+ {
+ private void InitBlock(ScorerDocQueue enclosingInstance)
+ {
+ this.enclosingInstance = enclosingInstance;
+ }
+ private ScorerDocQueue enclosingInstance;
+ public ScorerDocQueue Enclosing_Instance
+ {
+ get
+ {
+ return enclosingInstance;
+ }
+
+ }
+ internal Scorer scorer;
+ internal int doc;
+
+ internal HeapedScorerDoc(ScorerDocQueue enclosingInstance, Scorer s):this(enclosingInstance, s, s.DocID())
+ {
+ }
+
+ internal HeapedScorerDoc(ScorerDocQueue enclosingInstance, Scorer scorer, int doc)
+ {
+ InitBlock(enclosingInstance);
+ this.scorer = scorer;
+ this.doc = doc;
+ }
+
+ internal virtual void Adjust()
+ {
+ doc = scorer.DocID();
+ }
+ }
+
+ private HeapedScorerDoc topHSD; // same as heap[1], only for speed
+
+ /// <summary>Create a ScorerDocQueue with a maximum size. </summary>
+ public ScorerDocQueue(int maxSize)
+ {
+ // assert maxSize >= 0;
+ size = 0;
+ int heapSize = maxSize + 1;
+ heap = new HeapedScorerDoc[heapSize];
+ this.maxSize = maxSize;
+ topHSD = heap[1]; // initially null
+ }
+
+ /// <summary> Adds a Scorer to a ScorerDocQueue in log(size) time.
+ /// If one tries to add more Scorers than maxSize
+ /// a RuntimeException (ArrayIndexOutOfBound) is thrown.
+ /// </summary>
+ public void Put(Scorer scorer)
+ {
+ size++;
+ heap[size] = new HeapedScorerDoc(this, scorer);
+ UpHeap();
+ }
+
+ /// <summary> Adds a Scorer to the ScorerDocQueue in log(size) time if either
+ /// the ScorerDocQueue is not full, or not lessThan(scorer, top()).
+ /// </summary>
+ /// <param name="scorer">
+ /// </param>
+ /// <returns> true if scorer is added, false otherwise.
+ /// </returns>
+ public virtual bool Insert(Scorer scorer)
+ {
+ if (size < maxSize)
+ {
+ Put(scorer);
+ return true;
+ }
+ else
+ {
+ int docNr = scorer.DocID();
+ if ((size > 0) && (!(docNr < topHSD.doc)))
+ {
+ // heap[1] is top()
+ heap[1] = new HeapedScorerDoc(this, scorer, docNr);
+ DownHeap();
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+ }
+ }
+
+ /// <summary>Returns the least Scorer of the ScorerDocQueue in constant time.
+ /// Should not be used when the queue is empty.
+ /// </summary>
+ public Scorer Top()
+ {
+ // assert size > 0;
+ return topHSD.scorer;
+ }
+
+ /// <summary>Returns document number of the least Scorer of the ScorerDocQueue
+ /// in constant time.
+ /// Should not be used when the queue is empty.
+ /// </summary>
+ public int TopDoc()
+ {
+ // assert size > 0;
+ return topHSD.doc;
+ }
+
+ public float TopScore()
+ {
+ // assert size > 0;
+ return topHSD.scorer.Score();
+ }
+
+ public bool TopNextAndAdjustElsePop()
+ {
+ return CheckAdjustElsePop(topHSD.scorer.NextDoc() != DocIdSetIterator.NO_MORE_DOCS);
+ }
+
+ public bool TopSkipToAndAdjustElsePop(int target)
+ {
+ return CheckAdjustElsePop(topHSD.scorer.Advance(target) != DocIdSetIterator.NO_MORE_DOCS);
+ }
+
+ private bool CheckAdjustElsePop(bool cond)
+ {
+ if (cond)
+ {
+ // see also adjustTop
+ topHSD.doc = topHSD.scorer.DocID();
+ }
+ else
+ {
+ // see also popNoResult
+ heap[1] = heap[size]; // move last to first
+ heap[size] = null;
+ size--;
+ }
+ DownHeap();
+ return cond;
+ }
+
+ /// <summary>Removes and returns the least scorer of the ScorerDocQueue in log(size)
+ /// time.
+ /// Should not be used when the queue is empty.
+ /// </summary>
+ public Scorer Pop()
+ {
+ // assert size > 0;
+ Scorer result = topHSD.scorer;
+ PopNoResult();
+ return result;
+ }
+
+ /// <summary>Removes the least scorer of the ScorerDocQueue in log(size) time.
+ /// Should not be used when the queue is empty.
+ /// </summary>
+ private void PopNoResult()
+ {
+ heap[1] = heap[size]; // move last to first
+ heap[size] = null;
+ size--;
+ DownHeap(); // adjust heap
+ }
+
+ /// <summary>Should be called when the scorer at top changes doc() value.
+ /// Still log(n) worst case, but it's at least twice as fast to <c>
+ /// { pq.top().change(); pq.adjustTop(); }
+ /// </c> instead of <c>
+ /// { o = pq.pop(); o.change(); pq.push(o); }
+ /// </c>
+ /// </summary>
+ public void AdjustTop()
+ {
+ // assert size > 0;
+ topHSD.Adjust();
+ DownHeap();
+ }
+
+ /// <summary>Returns the number of scorers currently stored in the ScorerDocQueue. </summary>
+ public int Size()
+ {
+ return size;
+ }
+
+ /// <summary>Removes all entries from the ScorerDocQueue. </summary>
+ public void Clear()
+ {
+ for (int i = 0; i <= size; i++)
+ {
+ heap[i] = null;
+ }
+ size = 0;
+ }
+
+ private void UpHeap()
+ {
+ int i = size;
+ HeapedScorerDoc node = heap[i]; // save bottom node
+ int j = Number.URShift(i, 1);
+ while ((j > 0) && (node.doc < heap[j].doc))
+ {
+ heap[i] = heap[j]; // shift parents down
+ i = j;
+ j = Number.URShift(j, 1);
+ }
+ heap[i] = node; // install saved node
+ topHSD = heap[1];
+ }
+
+ private void DownHeap()
+ {
+ int i = 1;
+ HeapedScorerDoc node = heap[i]; // save top node
+ int j = i << 1; // find smaller child
+ int k = j + 1;
+ if ((k <= size) && (heap[k].doc < heap[j].doc))
+ {
+ j = k;
+ }
+ while ((j <= size) && (heap[j].doc < node.doc))
+ {
+ heap[i] = heap[j]; // shift up child
+ i = j;
+ j = i << 1;
+ k = j + 1;
+ if (k <= size && (heap[k].doc < heap[j].doc))
+ {
+ j = k;
+ }
+ }
+ heap[i] = node; // install saved node
+ topHSD = heap[1];
+ }
+ }
+} \ No newline at end of file