| 4661 | } |
| 4662 | |
| 4663 | void Pattern::gen_match_hfa(DFA::State *start) |
| 4664 | { |
| 4665 | size_t max_level = HFA::MAX_DEPTH - 1; // max level from start state(s) is reduced when hashes exponentially increase |
| 4666 | HFA::State index = 1; // DFA states are enumarated for breadth-first matching with the state visit set in match_hfa() |
| 4667 | HFA::StateHashes hashes[HFA::MAX_DEPTH]; // up to MAX_DEPTH states deep into the DFA are hashed from the start state(s) |
| 4668 | gen_match_hfa_start(start, index, hashes[0]); |
| 4669 | for (size_t level = 1; level <= max_level; ++level) |
| 4670 | for (HFA::StateHashes::iterator from = hashes[level - 1].begin(); from != hashes[level - 1].end(); ++from) |
| 4671 | if (!gen_match_hfa_transitions(level, max_level, from->first, from->second, index, hashes[level])) |
| 4672 | break; |
| 4673 | // move the HFA to a new HFA with enumerated states for breadth-first matching with a bitset in match_hfa() |
| 4674 | for (size_t level = 0; level <= max_level; ++level) |
| 4675 | { |
| 4676 | HFA::StateHashes::iterator hashes_end = hashes[level].end(); |
| 4677 | for (HFA::StateHashes::iterator next = hashes[level].begin(); next != hashes_end; ++next) |
| 4678 | { |
| 4679 | HFA::HashRanges& set_ranges = hfa_.hashes[level][next->first->index]; |
| 4680 | HFA::HashRanges& get_ranges = next->second; |
| 4681 | for (size_t offset = std::max<size_t>(HFA::MAX_CHAIN - 1, level) + 1 - HFA::MAX_CHAIN; offset <= level; ++offset) |
| 4682 | set_ranges[offset].swap(get_ranges[offset]); |
| 4683 | } |
| 4684 | } |
| 4685 | } |
| 4686 | |
| 4687 | void Pattern::gen_match_hfa_start(DFA::State *start, HFA::State& index, HFA::StateHashes& hashes) |
| 4688 | { |