DFA state compression: 16-bit wide and sherman co-exist

This commit is contained in:
Hong, Yang A
2018-12-19 17:49:09 +08:00
committed by Chang, Harry
parent c7c4119750
commit c06d5e1c14
10 changed files with 894 additions and 72 deletions

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2015-2016, Intel Corporation
* Copyright (c) 2015-2018, Intel Corporation
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
@@ -82,3 +82,108 @@ u32 doSherman16(const char *sherman_state, u8 cprime, const u16 *succ_table,
u32 daddy = *(const u16 *)(sherman_state + SHERMAN_DADDY_OFFSET);
return succ_table[(daddy << as) + cprime];
}
static really_inline
u16 doWide16(const char *wide_entry, const u8 **c_inout, const u8 *end,
const u8 *remap, const u16 *s, char *qstate, u16 *offset) {
// Internal relative offset after the last visit of the wide state.
if (qstate != NULL) { // stream mode
*offset = *(const u16 *)(qstate + 2);
}
u8 successful = 0;
const u8 *c = *c_inout;
u32 len_c = end - c;
u16 width = *(const u16 *)(wide_entry + WIDE_WIDTH_OFFSET);
assert(width >= 8);
const u8 *symbols = (const u8 *)(wide_entry + WIDE_SYMBOL_OFFSET16);
const u16 *trans = (const u16 *)(wide_entry +
WIDE_TRANSITION_OFFSET16(width));
assert(*offset < width);
u16 len_w = width - *offset;
const u8 *sym = symbols + *offset;
char tmp[16];
u16 pos = 0;
if (*offset == 0 && remap[*c] != *sym) {
goto normal;
}
// both in (16, +oo).
while (len_w >= 16 && len_c >= 16) {
m128 str_w = loadu128(sym);
for (size_t i = 0; i < 16; i++) {
tmp[i] = remap[*(c + i)];
}
m128 str_c = loadu128(tmp);
u32 z = movemask128(eq128(str_w, str_c));
pos = ctz32(~z);
assert(pos <= 16);
if (pos < 16) {
goto normal;
}
sym += 16;
c += 16;
len_w -= 16;
len_c -= 16;
}
pos = 0;
// at least one in (0, 16).
u32 loadLength_w = MIN(len_w, 16);
u32 loadLength_c = MIN(len_c, 16);
m128 str_w = loadbytes128(sym, loadLength_w);
for (size_t i = 0; i < loadLength_c; i++) {
tmp[i] = remap[*(c + i)];
}
m128 str_c = loadbytes128(tmp, loadLength_c);
u32 z = movemask128(eq128(str_w, str_c));
pos = ctz32(~z);
pos = MIN(pos, MIN(loadLength_w, loadLength_c));
if (loadLength_w <= loadLength_c) {
assert(pos <= loadLength_w);
// successful matching.
if (pos == loadLength_w) {
c -= 1;
successful = 1;
}
// failure, do nothing.
} else {
assert(pos <= loadLength_c);
// successful partial matching.
if (pos == loadLength_c) {
c -= 1;
goto partial;
}
// failure, do nothing.
}
normal:
*offset = 0;
if (qstate != NULL) {
// Internal relative offset.
unaligned_store_u16(qstate + 2, *offset);
}
c += pos;
*c_inout = c;
return successful ? *trans : *(trans + 1 + remap[*c]);
partial:
*offset = sym - symbols + pos;
if (qstate != NULL) {
// Internal relative offset.
unaligned_store_u16(qstate + 2, *offset);
}
c += pos;
*c_inout = c;
return *s;
}