Revision: 14582
          http://gate.svn.sourceforge.net/gate/?rev=14582&view=rev
Author:   valyt
Date:     2011-11-22 11:12:54 +0000 (Tue, 22 Nov 2011)
Log Message:
-----------
Our own binary search implementation, because we're worth it ;)

Modified Paths:
--------------
    mimir/trunk/mimir-core/src/gate/mimir/search/RankingQueryRunnerImpl.java

Modified: 
mimir/trunk/mimir-core/src/gate/mimir/search/RankingQueryRunnerImpl.java
===================================================================
--- mimir/trunk/mimir-core/src/gate/mimir/search/RankingQueryRunnerImpl.java    
2011-11-22 02:18:13 UTC (rev 14581)
+++ mimir/trunk/mimir-core/src/gate/mimir/search/RankingQueryRunnerImpl.java    
2011-11-22 11:12:54 UTC (rev 14582)
@@ -105,7 +105,8 @@
       try {
         int docIndex = (documentIndexes != null ? documentIndexes[start] : 
start);
         int docId = documentIds.getInt(docIndex);
-        if(queryExecutor.getLatestDocument() >= docId) {
+        if(queryExecutor.getLatestDocument() < 0 ||
+           queryExecutor.getLatestDocument() >= docId) {
           // we need to 'scroll back' the executor: get a new executor
           QueryExecutor oldExecutor = queryExecutor;
           queryExecutor = queryExecutor.getQueryNode().getQueryExecutor(
@@ -296,8 +297,7 @@
     documentHits = new ObjectArrayList<List<Binding>>();
     if(scorer != null) {
       documentScores = new DoubleArrayList();
-      documentsOrder = new IntArrayList(
-        queryExecutor.getQueryEngine().getRankingDocCount());
+      documentsOrder = new IntArrayList(docBlockSize);
     }
     hitCollectors = new Object2ObjectAVLTreeMap<int[], Future<?>>(
         new Comparator<int[]>(){
@@ -441,8 +441,8 @@
       // rank some documents
       int rankRangeStart = documentsOrder.size();
       int rankRangeEnd = index;
-      if(rankRangeEnd - rankRangeStart < 
-          queryExecutor.getQueryEngine().getRankingDocCount()) {
+      if((rankRangeEnd - rankRangeStart) < 
+          (queryExecutor.getQueryEngine().getRankingDocCount() -1)) {
         // extend the size of the chunk of documents to be ranked
         rankRangeEnd = rankRangeStart + 
             queryExecutor.getQueryEngine().getRankingDocCount(); 
@@ -466,7 +466,7 @@
         int smallestDocIndex = rankRangeStart < documentsOrder.size() ?
             documentsOrder.getInt(rankRangeStart) : -1;
         // the smallest score that's been seen in this new round 
-        double smallestNewScore = smallestDocIndex == -1 ? 0.0 : 
+        double smallestNewScore = smallestDocIndex == -1 ? 
Double.NEGATIVE_INFINITY : 
             documentScores.getDouble(smallestDocIndex);
         // we care about this new document if:
         // - we haven't collected enough documents yet, or
@@ -487,19 +487,10 @@
             documentsOrderWriteIndex--;
             documentsOrder.removeInt(documentsOrderWriteIndex);
           }
-          // find the rank for the new doc
-          // binary search for the insertion location
-          int rank = DoubleArrays.binarySearch(documentScores.elements(), 
-            rankRangeStart, documentsOrderWriteIndex, documentScore);
-          if(rank < 0) {
-            rank = -rank -1;
-          } else {
-            // skip all document with the same score (to keep ordering stable)
-            while(rank < documentsOrder.size() && 
-                documentScore <= 
documentScores.getDouble(documentsOrder.getInt(rank))){
-              rank++;
-            }            
-          }
+          // find the rank for the new doc in the documentsOrder list
+          int rank = findRank(documentScore, rankRangeStart, 
+              documentsOrderWriteIndex);
+          // and insert
           documentsOrder.add(rank, i);
           documentsOrderWriteIndex++;
         }
@@ -512,6 +503,41 @@
   }
   
   /**
+   * Given a document score, finds the correct insertion point into the 
+   * {@link #documentsOrder} list, within a given range of ranks.
+   * This method performs binary search followed by a linear scan so that the 
+   * returned insertion point is the largest correct one (i.e. later documents 
+   * with the same score get sorted after earlier ones, thus keeping the 
sorting
+   * stable).
+   *      
+   * @param documentScore the score for the new document.
+   * @param start the start of the search range within {@link #documentsOrder} 
+   * @param end the end of the search range within {@link #documentsOrder} 
+   * @return the largest correct insertion point
+   */
+  protected int findRank(double documentScore, int start, int end) {
+    // standard binary search
+    double midVal;
+    end--;
+    while (start <= end) {
+     int mid = (start + end) >>> 1;
+     midVal = documentScores.getDouble(documentsOrder.getInt(mid));
+     // note that the documentScores list is in decreasing order!
+     if (midVal > documentScore) start = mid + 1;
+     else if (midVal < documentScore) end = mid - 1;
+     else {
+       // we found a doc with exactly the same score: scan to the right
+       while(documentScores.getDouble(documentsOrder.getInt(mid)) == 
+           documentScore){
+         mid++;
+       }
+       return mid;
+     }
+    }
+    return start;
+  }
+  
+  /**
    * Makes sure all the documents in the specified range are queued for hit 
    * collection. 
    * @param interval the interval specified by 2 document ranks. The interval 
is

This was sent by the SourceForge.net collaborative development platform, the 
world's largest Open Source development site.


------------------------------------------------------------------------------
All the data continuously generated in your IT infrastructure 
contains a definitive record of customers, application performance, 
security threats, fraudulent activity, and more. Splunk takes this 
data and makes sense of it. IT sense. And common sense.
http://p.sf.net/sfu/splunk-novd2d
_______________________________________________
GATE-cvs mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/gate-cvs

Reply via email to