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;
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)) {
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);