mirror of
https://github.com/VectorCamp/vectorscan.git
synced 2025-11-18 18:20:35 +03:00
DFA state compression: 16-bit wide and sherman co-exist
This commit is contained in:
committed by
Chang, Harry
parent
c7c4119750
commit
c06d5e1c14
@@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user