You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucene.apache.org by mi...@apache.org on 2011/12/18 16:36:07 UTC

svn commit: r1220433 - in /lucene/dev/branches/branch_3x: ./ lucene/ lucene/src/java/org/apache/lucene/search/

Author: mikemccand
Date: Sun Dec 18 15:36:07 2011
New Revision: 1220433

URL: http://svn.apache.org/viewvc?rev=1220433&view=rev
Log:
LUCENE-3639: fix a few bugs in shard searching

Modified:
    lucene/dev/branches/branch_3x/   (props changed)
    lucene/dev/branches/branch_3x/lucene/   (props changed)
    lucene/dev/branches/branch_3x/lucene/CHANGES.txt
    lucene/dev/branches/branch_3x/lucene/src/java/org/apache/lucene/search/ScoreDoc.java
    lucene/dev/branches/branch_3x/lucene/src/java/org/apache/lucene/search/SearcherLifetimeManager.java
    lucene/dev/branches/branch_3x/lucene/src/java/org/apache/lucene/search/TopDocs.java

Modified: lucene/dev/branches/branch_3x/lucene/CHANGES.txt
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_3x/lucene/CHANGES.txt?rev=1220433&r1=1220432&r2=1220433&view=diff
==============================================================================
--- lucene/dev/branches/branch_3x/lucene/CHANGES.txt (original)
+++ lucene/dev/branches/branch_3x/lucene/CHANGES.txt Sun Dec 18 15:36:07 2011
@@ -94,6 +94,12 @@ Bug fixes
   where they would create invalid offsets in some situations, leading to problems
   in highlighting. (Max Beutel via Robert Muir)
 
+* LUCENE-3639: TopDocs.merge was incorrectly setting TopDocs.maxScore to
+  Float.MIN_VALUE when it should be Float.NaN, when there were 0
+  hits.  Improved age calculation in SearcherLifetimeManager, to have
+  double precision and to compute age to be how long ago the searcher
+  was replaced with a new searcher (Mike McCandless)
+
 Documentation
 
 * LUCENE-3597: Fixed incorrect grouping documentation. (Martijn van Groningen, Robert Muir)

Modified: lucene/dev/branches/branch_3x/lucene/src/java/org/apache/lucene/search/ScoreDoc.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_3x/lucene/src/java/org/apache/lucene/search/ScoreDoc.java?rev=1220433&r1=1220432&r2=1220433&view=diff
==============================================================================
--- lucene/dev/branches/branch_3x/lucene/src/java/org/apache/lucene/search/ScoreDoc.java (original)
+++ lucene/dev/branches/branch_3x/lucene/src/java/org/apache/lucene/search/ScoreDoc.java Sun Dec 18 15:36:07 2011
@@ -46,6 +46,6 @@ public class ScoreDoc implements java.io
   // A convenience method for debugging.
   @Override
   public String toString() {
-    return "doc=" + doc + " score=" + score;
+    return "doc=" + doc + " score=" + score + " shardIndex=" + shardIndex;
   }
 }

Modified: lucene/dev/branches/branch_3x/lucene/src/java/org/apache/lucene/search/SearcherLifetimeManager.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_3x/lucene/src/java/org/apache/lucene/search/SearcherLifetimeManager.java?rev=1220433&r1=1220432&r2=1220433&view=diff
==============================================================================
--- lucene/dev/branches/branch_3x/lucene/src/java/org/apache/lucene/search/SearcherLifetimeManager.java (original)
+++ lucene/dev/branches/branch_3x/lucene/src/java/org/apache/lucene/search/SearcherLifetimeManager.java Sun Dec 18 15:36:07 2011
@@ -23,7 +23,6 @@ import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
 import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.TimeUnit;
 
 import org.apache.lucene.index.IndexReader;        // javadocs
 import org.apache.lucene.search.NRTManager;        // javadocs
@@ -102,9 +101,11 @@ import org.apache.lucene.util.IOUtils;
 
 public class SearcherLifetimeManager implements Closeable {
 
+  static final double NANOS_PER_SEC = 1000000000.0;
+
   private static class SearcherTracker implements Comparable<SearcherTracker>, Closeable {
     public final IndexSearcher searcher;
-    public final long recordTimeSec;
+    public final double recordTimeSec;
     public final long version;
 
     public SearcherTracker(IndexSearcher searcher) {
@@ -113,7 +114,7 @@ public class SearcherLifetimeManager imp
       searcher.getIndexReader().incRef();
       // Use nanoTime not currentTimeMillis since it [in
       // theory] reduces risk from clock shift
-      recordTimeSec = TimeUnit.NANOSECONDS.toSeconds(System.nanoTime());
+      recordTimeSec = System.nanoTime() / NANOS_PER_SEC;
     }
 
     // Newer searchers are sort before older ones:
@@ -169,6 +170,7 @@ public class SearcherLifetimeManager imp
     final long version = searcher.getIndexReader().getVersion();
     SearcherTracker tracker = searchers.get(version);
     if (tracker == null) {
+      //System.out.println("RECORD version=" + version + " ms=" + System.currentTimeMillis());
       tracker = new SearcherTracker(searcher);
       if (searchers.putIfAbsent(version, tracker) != null) {
         // Another thread beat us -- must decRef to undo
@@ -216,28 +218,27 @@ public class SearcherLifetimeManager imp
   /** See {@link #prune}. */
   public interface Pruner {
     /** Return true if this searcher should be removed. 
-     *  @param ageSec how long ago this searcher was
-     *         recorded vs the most recently recorded
-     *         searcher
+     *  @param ageSec how much time has passed since this
+     *         searcher was the current (live) searcher
      *  @param searcher Searcher
      **/
-    public boolean doPrune(int ageSec, IndexSearcher searcher);
+    public boolean doPrune(double ageSec, IndexSearcher searcher);
   }
 
   /** Simple pruner that drops any searcher older by
    *  more than the specified seconds, than the newest
    *  searcher. */
   public final static class PruneByAge implements Pruner {
-    private final int maxAgeSec;
+    private final double maxAgeSec;
 
-    public PruneByAge(int maxAgeSec) {
-      if (maxAgeSec < 1) {
+    public PruneByAge(double maxAgeSec) {
+      if (maxAgeSec < 0) {
         throw new IllegalArgumentException("maxAgeSec must be > 0 (got " + maxAgeSec + ")");
       }
       this.maxAgeSec = maxAgeSec;
     }
 
-    public boolean doPrune(int ageSec, IndexSearcher searcher) {
+    public boolean doPrune(double ageSec, IndexSearcher searcher) {
       return ageSec > maxAgeSec;
     }
   }
@@ -259,14 +260,25 @@ public class SearcherLifetimeManager imp
       trackers.add(tracker);
     }
     Collections.sort(trackers);
-    final long newestSec = trackers.isEmpty() ? 0L : trackers.get(0).recordTimeSec;
+    double lastRecordTimeSec = 0.0;
+    final double now = System.nanoTime()/NANOS_PER_SEC;
     for (SearcherTracker tracker: trackers) {
-      final int ageSec = (int) (newestSec - tracker.recordTimeSec);
-      assert ageSec >= 0;
+      final double ageSec;
+      if (lastRecordTimeSec == 0.0) {
+        ageSec = 0.0;
+      } else {
+        ageSec = now - lastRecordTimeSec;
+      }
+      // First tracker is always age 0.0 sec, since it's
+      // still "live"; second tracker's age (= seconds since
+      // it was "live") is now minus first tracker's
+      // recordTime, etc:
       if (pruner.doPrune(ageSec, tracker.searcher)) {
+        //System.out.println("PRUNE version=" + tracker.version + " age=" + ageSec + " ms=" + System.currentTimeMillis());
         searchers.remove(tracker.version);
         tracker.close();
       }
+      lastRecordTimeSec = tracker.recordTimeSec;
     }
   }
 

Modified: lucene/dev/branches/branch_3x/lucene/src/java/org/apache/lucene/search/TopDocs.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_3x/lucene/src/java/org/apache/lucene/search/TopDocs.java?rev=1220433&r1=1220432&r2=1220433&view=diff
==============================================================================
--- lucene/dev/branches/branch_3x/lucene/src/java/org/apache/lucene/search/TopDocs.java (original)
+++ lucene/dev/branches/branch_3x/lucene/src/java/org/apache/lucene/search/TopDocs.java Sun Dec 18 15:36:07 2011
@@ -216,8 +216,10 @@ public class TopDocs implements java.io.
     float maxScore = Float.MIN_VALUE;
     for(int shardIDX=0;shardIDX<shardHits.length;shardIDX++) {
       final TopDocs shard = shardHits[shardIDX];
+      // totalHits can be non-zero even if no hits were
+      // collected, when searchAfter was used:
+      totalHitCount += shard.totalHits;
       if (shard.scoreDocs != null && shard.scoreDocs.length > 0) {
-        totalHitCount += shard.totalHits;
         availHitCount += shard.scoreDocs.length;
         queue.add(new ShardRef(shardIDX));
         maxScore = Math.max(maxScore, shard.getMaxScore());
@@ -225,6 +227,10 @@ public class TopDocs implements java.io.
       }
     }
 
+    if (availHitCount == 0) {
+      maxScore = Float.NaN;
+    }
+
     final ScoreDoc[] hits = new ScoreDoc[Math.min(topN, availHitCount)];
 
     int hitUpto = 0;