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

Loading…
Cancel
Save