]> git.ipfire.org Git - thirdparty/suricata.git/commitdiff
Custom Quick Sort for Signature IDs
authorKen Steele <ken@tilera.com>
Sun, 2 Nov 2014 23:49:54 +0000 (18:49 -0500)
committerVictor Julien <victor@inliniac.net>
Thu, 15 Jan 2015 10:52:04 +0000 (11:52 +0100)
Use an in place Quick Sort instead of qsort(), which does merge sort and
calls memcpy().

Improves performance on my tests.

src/detect.c

index e3f4580335910cd2ec7c8cd87cc54c7356ea7cdc..5c37099e051aec817b73dc5c9478bd0a9f4b9911 100644 (file)
@@ -842,11 +842,29 @@ static inline void DetectPrefilterMergeSort(DetectEngineCtx *de_ctx,
     BUG_ON((det_ctx->pmq.rule_id_array_cnt + sgh->non_mpm_id_cnt) < det_ctx->match_array_cnt);
 }
 
-static int DoSortSigIntId(const void *a, const void *b)
+/* Return true is the list is sorted smallest to largest */
+static void QuickSortSigIntId(SigIntId *sids, uint32_t n)
 {
-    SigIntId x = *(SigIntId *)a;
-    SigIntId y = *(SigIntId *)b;
-    return x - y;
+    if (n < 2)
+        return;
+    SigIntId p = sids[n / 2];
+    SigIntId *l = sids;
+    SigIntId *r = sids + n - 1;
+    while (l <= r) {
+        if (*l < p)
+            l++;
+        else if (*r > p)
+            r--;
+        else {
+            SigIntId t = *l;
+            *l = *r;
+            *r = t;
+            l++;
+            r--;
+        }
+    }
+    QuickSortSigIntId(sids, r - sids + 1);
+    QuickSortSigIntId(l, sids + n - l);
 }
 
 #define SMS_USE_FLOW_SGH        0x01
@@ -1098,9 +1116,8 @@ static inline void DetectMpmPrefilter(DetectEngineCtx *de_ctx,
 
     /* Sort the rule list to lets look at pmq.
      * NOTE due to merging of 'stream' pmqs we *MAY* have duplicate entries */
-    if (det_ctx->pmq.rule_id_array_cnt) {
-        qsort(det_ctx->pmq.rule_id_array, det_ctx->pmq.rule_id_array_cnt,
-                sizeof(SigIntId), DoSortSigIntId);
+    if (det_ctx->pmq.rule_id_array_cnt > 1) {
+        QuickSortSigIntId(det_ctx->pmq.rule_id_array, det_ctx->pmq.rule_id_array_cnt);
     }
 }