bool utf8 = (t.flags & HS_FLAG_UTF8) > 0;
set<pair<size_t, size_t>> matches;
- findMatches(*g, rm, t.input, matches, 0, t.notEod, utf8);
+ bool success = findMatches(*g, rm, t.input, matches, 0, t.notEod, utf8);
+ ASSERT_TRUE(success);
set<pair<size_t, size_t>> expected(begin(t.matches), end(t.matches));
namespace {
+/** \brief Max number of states (taking edit distance into account). */
+static constexpr size_t STATE_COUNT_MAX = 15000;
+
// returns all successors up to a given depth in a vector of sets, indexed by
// zero-based depth from source vertex
static
*
* Fills \a matches with offsets into the data stream where a match is found.
*/
-void findMatches(const NGHolder &g, const ReportManager &rm,
+bool findMatches(const NGHolder &g, const ReportManager &rm,
const string &input, MatchSet &matches,
const u32 edit_distance, const bool notEod, const bool utf8) {
assert(hasCorrectlyNumberedVertices(g));
// compile time, so make it an assert
assert(!edit_distance || !utf8);
- DEBUG_PRINTF("Finding matches\n");
+ const size_t total_states = num_vertices(g) * (3 * edit_distance + 1);
+ DEBUG_PRINTF("Finding matches (%zu total states)\n", total_states);
+ if (total_states > STATE_COUNT_MAX) {
+ DEBUG_PRINTF("too big\n");
+ return false;
+ }
GraphCache gc(edit_distance, g);
#ifdef DEBUG
state.next.count());
if (state.next.empty()) {
filterMatches(matches);
- return;
+ return true;
}
state.states = state.next;
state.prev = state.cur;
getMatches(g, matches, state, !notEod);
filterMatches(matches);
+ return true;
}
} // namespace ue2
-/** \brief Find all matches for a given graph when executed against \a input.
+/**
+ * \brief Find all matches for a given graph when executed against \a input.
*
- * Fills \a matches with offsets into the data stream where a match is found.
+ * Fills \a matches with offsets into the data stream where a match is found.
+ *
+ * Returns false if this graph is too large to find its matches in reasonable
+ * time.
*/
-void findMatches(const ue2::NGHolder &g, const ue2::ReportManager &rm,
+bool findMatches(const ue2::NGHolder &g, const ue2::ReportManager &rm,
const std::string &input,
std::set<std::pair<size_t, size_t>> &matches,
const unsigned int max_edit_distance, const bool notEod,