, dc_closure()
, dc_prectbl(NULL)
, dc_tagvertbl(nfa.tags.size())
- , dc_taghistory(nfa.tags.size())
+ , dc_taghistory()
, dc_kernels()
, dc_buffers(dc_allocator)
, dc_newvers(newver_cmp_t(dc_taghistory))
, dc_stack_topsort()
, dc_stack_linear()
, dc_stack_dfs()
+ , dc_path1()
+ , dc_path2()
+ , dc_path3()
+ , dc_tagcount()
, dc_dump(opts)
, dc_clstats()
-{}
+{
+ const size_t ntags = nfa.tags.size();
+ dc_path1.reserve(ntags);
+ dc_path2.reserve(ntags);
+ dc_path3.reserve(ntags);
+ dc_tagcount.resize(ntags);
+}
dfa_t::~dfa_t()
static void reserve_buffers(determ_context_t &);
static uint32_t hash_kernel(const kernel_t *kernel);
static bool equal_lookahead_tags(determ_context_t &, const kernel_t *, const kernel_t *);
-static void group_by_tag(tag_path_t &p);
+static void group_by_tag(tag_path_t &path, tag_path_t &buf, std::vector<uint32_t> &count);
static void unwind(const tag_history_t &hist, tag_path_t &path, hidx_t idx);
static bool do_find_state(determ_context_t &ctx);
static tcmd_t *final_actions(determ_context_t &ctx, const clos_t &fin);
}
tag_history_t &thist = ctx.dc_taghistory;
- tag_path_t &p1 = thist.path1, &p2 = thist.path2;
+ tag_path_t &p1 = ctx.dc_path1, &p2 = ctx.dc_path2, &p3 = ctx.dc_path3;
+ std::vector<uint32_t> &count = ctx.dc_tagcount;
for (size_t i = 0; i < x->size; ++i) {
const hidx_t xl = x->tlook[i], yl = y->tlook[i];
if (p1.size() != p2.size()) return false;
- group_by_tag(p1);
- group_by_tag(p2);
+ group_by_tag(p1, p3, count);
+ group_by_tag(p2, p3, count);
if (p1 != p2) return false;
}
}
-void group_by_tag(tag_path_t &p)
+void group_by_tag(tag_path_t &path, tag_path_t &buf, std::vector<uint32_t> &count)
{
- // insertion sort (must be careful to preserve order of elements
- // with the same tag, but different negative bit)
- size_t i, j, n = p.size();
+ // counting sort with tag index as key
+ // must preserve relative order of elements with the same tag
- for (i = 1; i < n; ++i) {
- const tag_info_t info = p[i];
- const size_t tag = info.idx;
+ const size_t clen = count.size(), plen = path.size();
+ std::fill(count.begin(), count.end(), 0);
+ buf.resize(plen);
- for (j = i; j > 0 && p[j - 1].idx > tag; --j) {
- p[j] = p[j - 1];
- }
- p[j] = info;
+ for (size_t i = 0; i < plen; ++i) {
+ ++count[path[i].idx];
+ }
+
+ for (size_t i = 1; i < clen; ++i) {
+ count[i] += count[i - 1];
}
+
+ for (size_t i = plen; i --> 0; ) {
+ buf[--count[path[i].idx]] = path[i];
+ }
+
+ path.swap(buf);
}
};
std::vector<node_t> nodes;
- // reconstruct paths for comparison
- tag_path_t path1;
- tag_path_t path2;
-
- inline explicit tag_history_t(size_t ntags);
+ inline tag_history_t(): nodes() {};
inline hidx_t pred(hidx_t i) const { return nodes[i].pred; }
inline tag_info_t info(hidx_t i) const { return nodes[i].info; }
inline tagver_t elem(hidx_t i) const { return nodes[i].info.neg ? TAGVER_BOTTOM : TAGVER_CURSOR; }
FORBID_COPY(tag_history_t);
};
-tag_history_t::tag_history_t(size_t ntags)
- : nodes()
- , path1()
- , path2()
-{
- path1.reserve(ntags);
- path2.reserve(ntags);
-}
-
hidx_t tag_history_t::push(hidx_t idx, tag_info_t info)
{
node_t x = {idx, info};