Implements a timout mechanism to prevent intersect iterators from taking too long for some queries, a=chris

Chris Pollett [2013-11-22 06:Nov:nd]
Implements a timout mechanism to prevent intersect iterators from taking too long for some queries, a=chris
Filename
lib/index_bundle_iterators/intersect_iterator.php
models/phrase_model.php
diff --git a/lib/index_bundle_iterators/intersect_iterator.php b/lib/index_bundle_iterators/intersect_iterator.php
index 1ce29bd45..1cef87893 100644
--- a/lib/index_bundle_iterators/intersect_iterator.php
+++ b/lib/index_bundle_iterators/intersect_iterator.php
@@ -103,6 +103,18 @@ class IntersectIterator extends IndexBundleIterator
      */
     var $weight;

+    /**
+     *  Whether to run a timer that shuts down the intersect iterator if
+     *  syncGenDocOffsetsAmongstIterators takes longer than the time out period
+     */
+    var $sync_timer_on;
+
+    /**
+     *  Number of seconds before timeout and stop
+     *  syncGenDocOffsetsAmongstIterators if slow
+     */
+    const SYNC_TIMEOUT = 5;
+
     /**
      * Creates an intersect iterator with the given parameters.
      *
@@ -120,6 +132,7 @@ class IntersectIterator extends IndexBundleIterator
         $this->quote_positions = $quote_positions;
         $this->weight = $weight;
         $this->results_per_block = 1;
+        $this->sync_timer_on = false;

         /*
              We take an initial guess of the num_docs we return as the sum
@@ -414,6 +427,11 @@ class IntersectIterator extends IndexBundleIterator
      */
     function syncGenDocOffsetsAmongstIterators()
     {
+        if($this->sync_timer_on) {
+            $timer_on = true;
+            $sync_time = time();
+            $time_out = self::SYNC_TIMEOUT + $sync_time;
+        }
         if(($biggest_gen_offset = $this->index_bundle_iterators[
                         0]->currentGenDocOffsetWithWord()) == -1) {
             return -1;
@@ -443,6 +461,9 @@ class IntersectIterator extends IndexBundleIterator
         $last_changed = -1;
         $i = 0;
         while($i != $last_changed) {
+            if($timer_on && time() > $time_out) {
+                return -1;
+            }
             if($last_changed == -1) $last_changed = 0;
             if($this->genDocOffsetCmp($gen_doc_offset[$i],
                 $biggest_gen_offset) < 0) {
diff --git a/models/phrase_model.php b/models/phrase_model.php
index 115ff78db..10c697baa 100755
--- a/models/phrase_model.php
+++ b/models/phrase_model.php
@@ -1645,6 +1645,11 @@ class PhraseModel extends ParallelModel
                         $word_iterators, $word_iterator_map, $quote_positions,
                         $weight);
                     $min_group_flag = true;
+                    if($save_timestamp_name == "") {
+                        $base_iterator->sync_timer_on = true;
+                    } else {
+                        $base_iterator->sync_timer_on = false;
+                    }
                 }
                 if($save_timestamp_name != "") {
                     if(isset($save_point[$save_count]) &&
ViewGit