]> git.ipfire.org Git - thirdparty/suricata.git/commitdiff
Further optimize merging mpm and non-mpm rule ID lists.
authorKen Steele <ken@tilera.com>
Mon, 3 Nov 2014 03:27:07 +0000 (22:27 -0500)
committerVictor Julien <victor@inliniac.net>
Thu, 15 Jan 2015 10:52:04 +0000 (11:52 +0100)
When reaching the end of either list, merging is no longer required,
simply walk down the other list.

If the non-MPM list can't have duplicates, it would be worth removing
the duplicate check for the non-MPM list when it is the only non-empty list
remaining.

src/detect.c

index 5c37099e051aec817b73dc5c9478bd0a9f4b9911..48747df31403859daa14516096f135f4227f2eed 100644 (file)
@@ -781,9 +781,7 @@ end:
 static inline void DetectPrefilterMergeSort(DetectEngineCtx *de_ctx,
         DetectEngineThreadCtx *det_ctx, SigGroupHead *sgh)
 {
-    SigIntId mpm = (SigIntId)-1;
-    SigIntId nonmpm = (SigIntId)-1;
-
+    SigIntId mpm, nonmpm;
     det_ctx->match_array_cnt = 0;
     SigIntId *mpm_ptr = det_ctx->pmq.rule_id_array;
     SigIntId *nonmpm_ptr = sgh->non_mpm_id_array;
@@ -791,45 +789,74 @@ static inline void DetectPrefilterMergeSort(DetectEngineCtx *de_ctx,
     uint32_t n_cnt = sgh->non_mpm_id_cnt;
     SCLogDebug("PMQ rule id array count %d", det_ctx->pmq.rule_id_array_cnt);
     SCLogDebug("SGH non-MPM id count %d", sgh->non_mpm_id_cnt);
+    SigIntId *final_ptr;
+    uint32_t final_cnt;
+    SigIntId id;
+    SigIntId previous_id = (SigIntId)-1;
+    Signature **sig_array = de_ctx->sig_array;
+    Signature **match_array = det_ctx->match_array;
+    Signature *s;
 
     /* Load first values. */
     if (likely(m_cnt)) {
-        mpm = *(mpm_ptr++);
-        m_cnt--;
-    } else
-        mpm = (SigIntId)-1;
+        mpm = *mpm_ptr;
+    } else {
+        /* mpm list is empty */
+        final_ptr = nonmpm_ptr;
+        final_cnt = n_cnt;
+        goto final;
+    }
     if (likely(n_cnt)) {
-        nonmpm = *(nonmpm_ptr++);
-        n_cnt--;
-    } else
-        nonmpm = (SigIntId)-1;
-
-     SigIntId previous_id = (SigIntId)-1;
-     Signature **sig_array = de_ctx->sig_array;
-     Signature **match_array = det_ctx->match_array;
-     Signature *s;
-     while (1) {
-        SigIntId id = MIN(mpm, nonmpm);
-
-        if (unlikely(id == (SigIntId)-1))
-            break;
-        else {
-            s = sig_array[id];
-
-            if (id == mpm) {
-                if (likely(m_cnt)) {
-                    mpm = *(mpm_ptr++);
-                    m_cnt--;
-                } else
-                    mpm = -1;  // TODO - at this point, just copy of remaining array onto the end of the list.
-            } else { // (id == nonmpm)
-                if (likely(n_cnt)) {
-                    nonmpm = *(nonmpm_ptr++);
-                    n_cnt--;
-                } else
-                    nonmpm = -1;
-            }
-        }
+        nonmpm = *nonmpm_ptr;
+    } else {
+        /* non-mpm list is empty. */
+        final_ptr = mpm_ptr;
+        final_cnt = m_cnt;
+        goto final;
+    }
+    while (1) {
+         if (mpm <= nonmpm) {
+             /* Take from mpm list */
+             id = mpm;
+
+             s = sig_array[id];
+             /* As the mpm list can contain duplicates, check for that here. */
+             if (likely(id != previous_id)) {
+                 *match_array++ = s;
+                 previous_id = id;
+             }
+             if (unlikely(--m_cnt == 0)) {
+                 /* mpm list is now empty */
+                 final_ptr = nonmpm_ptr;
+                 final_cnt = n_cnt;
+                 goto final;
+             }
+             mpm_ptr++;
+             mpm = *mpm_ptr;
+         } else {
+             id = nonmpm;
+
+             s = sig_array[id];
+             /* As the mpm list can contain duplicates, check for that here. */
+             if (likely(id != previous_id)) {
+                 *match_array++ = s;
+                 previous_id = id;
+             }
+             if (unlikely(--n_cnt == 0)) {
+                 final_ptr = mpm_ptr;
+                 final_cnt = m_cnt;
+                 goto final;
+             }
+             nonmpm_ptr++;
+             nonmpm = *nonmpm_ptr;
+         }
+    }
+
+ final: /* Only one list remaining. Just walk that list. */
+
+    while (final_cnt-- > 0) {
+        id = *final_ptr++;
+        s = sig_array[id];
 
         /* As the mpm list can contain duplicates, check for that here. */
         if (likely(id != previous_id)) {
@@ -837,6 +864,7 @@ static inline void DetectPrefilterMergeSort(DetectEngineCtx *de_ctx,
             previous_id = id;
         }
     }
+
     det_ctx->match_array_cnt = match_array - det_ctx->match_array;
 
     BUG_ON((det_ctx->pmq.rule_id_array_cnt + sgh->non_mpm_id_cnt) < det_ctx->match_array_cnt);