]> git.ipfire.org Git - thirdparty/vectorscan.git/commitdiff
accel: limit how far we will search in findBest
authorJustin Viiret <justin.viiret@intel.com>
Wed, 17 May 2017 04:43:15 +0000 (14:43 +1000)
committerMatthew Barr <matthew.barr@intel.com>
Tue, 30 May 2017 04:00:45 +0000 (14:00 +1000)
src/nfagraph/ng_limex_accel.cpp

index beeb4a697993fa363e10156fce756fed77dbfaa9..80e08a7f9093c648ecacea8898224f1145a4319d 100644 (file)
@@ -215,16 +215,30 @@ struct SAccelScheme {
 };
 }
 
+/**
+ * \brief Limit on the number of (recursive) calls to findBestInternal().
+ */
+static constexpr size_t MAX_FINDBEST_CALLS = 1000000;
+
 static
-void findBest(vector<vector<CharReach> >::const_iterator pb,
-              vector<vector<CharReach> >::const_iterator pe,
-              const SAccelScheme &curr, SAccelScheme *best) {
+void findBestInternal(vector<vector<CharReach>>::const_iterator pb,
+                      vector<vector<CharReach>>::const_iterator pe,
+                      size_t *num_calls, const SAccelScheme &curr,
+                      SAccelScheme *best) {
     assert(curr.offset <= MAX_ACCEL_DEPTH);
+
+    if (++(*num_calls) > MAX_FINDBEST_CALLS) {
+        DEBUG_PRINTF("hit num_calls limit %zu\n", *num_calls);
+        return;
+    }
+
     DEBUG_PRINTF("paths left %zu\n", pe - pb);
     if (pb == pe) {
         if (curr < *best) {
-            DEBUG_PRINTF("new best\n");
             *best = curr;
+            DEBUG_PRINTF("new best: count=%zu, class=%s, offset=%u\n",
+                         best->cr.count(), describeClass(best->cr).c_str(),
+                         best->offset);
         }
         return;
     }
@@ -262,7 +276,7 @@ void findBest(vector<vector<CharReach> >::const_iterator pb,
             DEBUG_PRINTF("worse\n");
             continue;
         }
-        findBest(pb + 1, pe, in, best);
+        findBestInternal(pb + 1, pe, num_calls, in, best);
 
         if (curr.cr == best->cr) {
             return; /* could only get better by offset */
@@ -270,6 +284,19 @@ void findBest(vector<vector<CharReach> >::const_iterator pb,
     }
 }
 
+static
+SAccelScheme findBest(const vector<vector<CharReach>> &paths,
+                      const CharReach &terminating) {
+    SAccelScheme curr(terminating, 0U);
+    SAccelScheme best;
+    size_t num_calls = 0;
+    findBestInternal(paths.begin(), paths.end(), &num_calls, curr, &best);
+    DEBUG_PRINTF("findBest completed, num_calls=%zu\n", num_calls);
+    DEBUG_PRINTF("selected scheme: count=%zu, class=%s, offset=%u\n",
+                 best.cr.count(), describeClass(best.cr).c_str(), best.offset);
+    return best;
+}
+
 namespace {
 struct DAccelScheme {
     DAccelScheme(CharReach cr_in, u32 offset_in)
@@ -557,9 +584,7 @@ AccelScheme findBestAccelScheme(vector<vector<CharReach>> paths,
     /* if we were smart we would do something netflowy on the paths to find the
      * best cut. But we aren't, so we will just brute force it.
      */
-    SAccelScheme curr(terminating, 0U);
-    SAccelScheme best;
-    findBest(paths.begin(), paths.end(), curr, &best);
+    SAccelScheme best = findBest(paths, terminating);
 
     /* find best is a bit lazy in terms of minimising the offset, see if we can
      * make it better. need to find the min max offset that we need.*/