Further optimize merging mpm and non-mpm rule ID lists.

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.
pull/1295/head
Ken Steele 11 years ago committed by Victor Julien
parent 86f4c6c47b
commit 403b5a4645

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

Loading…
Cancel
Save