// see note [estimating total size of paths in skeleton]
// We don't need all patterns that cause undefined behaviour.
// We only need some examples, the shorter the better.
-arccount_t Node::naked_ways (const way_t & prefix, std::vector<way_t> & ways)
+Node::nakeds_t Node::naked_ways (const way_t & prefix, std::vector<way_t> & ways)
{
if (!rule.is_none ())
{
- return arccount_t (0u);
+ return nakeds_t (0u);
}
else if (end ())
{
ways.push_back (prefix);
- return arccount_t (prefix.size ());
+ return nakeds_t (prefix.size ());
}
else if (loop < 2)
{
local_inc _ (loop);
- arccount_t size (0u);
+ nakeds_t size (0u);
for (arcsets_t::iterator i = arcsets.begin (); i != arcsets.end (); ++i)
{
way_t w = prefix;
size = size + i->first->naked_ways (w, ways);
if (size.overflow ())
{
- return arccount_t::limit ();
+ return nakeds_t::limit ();
}
}
return size;
}
else
{
- return arccount_t (0u);
+ return nakeds_t (0u);
}
}
template <typename cunit_t, typename key_t>
static void permutate_one (FILE * input, FILE * keys, const multipath_t & path);
template <typename cunit_t, typename key_t>
- static arccount_t cover_one (FILE * input, FILE * keys, const multipath_t & prefix, const path_t & suffix);
+ static Node::covers_t cover_one (FILE * input, FILE * keys, const multipath_t & prefix, const path_t & suffix);
/*
* note [estimating total size of paths in skeleton]
* does overflow, an error is reported and re2c aborts.
*
*/
-arccount_t Node::sizeof_permutate (arccount_t wid, arccount_t len)
+Node::permuts_t Node::sizeof_permutate (permuts_t wid, permuts_t len)
{
if (end ())
{
else if (loop < 2)
{
local_inc _ (loop);
- arccount_t size (0u);
- const arccount_t new_len = len + arccount_t (1u);
+ permuts_t size (0u);
+ const permuts_t new_len = len + permuts_t (1u);
for (arcs_t::iterator i = arcs.begin (); i != arcs.end (); ++i)
{
- const arccount_t new_wid = wid * arccount_t (i->second.size ());
+ const permuts_t new_wid = wid * permuts_t (i->second.size ());
if (new_wid.overflow ())
{
- return arccount_t::limit ();
+ return permuts_t::limit ();
}
size = size + i->first->sizeof_permutate (new_wid, new_len);
if (size.overflow ())
{
- return arccount_t::limit ();
+ return permuts_t::limit ();
}
}
return size;
}
else
{
- return arccount_t (0u);
+ return permuts_t (0u);
}
}
*
*/
template <typename cunit_t, typename key_t>
- arccount_t Node::cover (const multipath_t & prefix, FILE * input, FILE * keys)
+ Node::covers_t Node::cover (const multipath_t & prefix, FILE * input, FILE * keys)
{
- arccount_t size (0u);
+ covers_t size (0u);
if (suffix != NULL)
{
size = cover_one<cunit_t, key_t> (input, keys, prefix, *suffix);
size = size + i->first->cover<cunit_t, key_t> (new_prefix, input, keys);
if (size.overflow ())
{
- return arccount_t::limit ();
+ return covers_t::limit ();
}
if (i->first->suffix != NULL && suffix == NULL)
{
void Skeleton::generate_paths_cunit_key (FILE * input, FILE * keys)
{
multipath_t prefix (nodes->rule);
- if (nodes->sizeof_permutate (arccount_t (1u), arccount_t (0u)).overflow ())
+ if (nodes->sizeof_permutate (Node::permuts_t (1u), Node::permuts_t (0u)).overflow ())
{
if (nodes->cover<cunit_t, key_t> (prefix, input, keys).overflow ())
{
}
template <typename cunit_t, typename key_t>
- static arccount_t cover_one (FILE * input, FILE * keys, const multipath_t & prefix, const path_t & suffix)
+ static Node::covers_t cover_one (FILE * input, FILE * keys, const multipath_t & prefix, const path_t & suffix)
{
const size_t prefix_len = prefix.len ();
const size_t suffix_len = suffix.len ();
count = std::max (count, prefix[i]->size ());
}
- const arccount_t size = arccount_t (len) * arccount_t (count);
+ const Node::covers_t size = Node::covers_t (len) * Node::covers_t (count);
if (!size.overflow ())
{
// input
namespace re2c
{
-static const uint32_t ARC_LIMIT = 1024 * 1024 * 1024; // ~1Gb
-typedef u32lim_t<ARC_LIMIT> arccount_t;
-
struct Node
{
+ // Types for counting arcs in path permutations and path cover.
+ // Paths are dumped to file as soon as generated and don't eat
+ // heap space. Path permutations grow exponentially and are likely
+ // to exceed limit, so their limit should be low. Path cover grows
+ // linearly and is unlikely to exceed limit, so its limit may be
+ // high.
+ typedef u32lim_t<1024 * 1024 * 32> permuts_t; // ~32Mb
+ typedef u32lim_t<1024 * 1024 * 1024> covers_t; // ~1Gb
+
+ // Type for counting arcs in paths that cause undefined behaviour.
+ // These paths are stored on heap, so the limit should be low.
+ // Most real-world cases have only a few paths. We don't need all
+ // paths anyway, just some examples. But we want short examples.
+ // Some synthetized tests can't find short paths with lower limit.
+ typedef u32lim_t<1024 * 1024 * 64> nakeds_t; // ~64Mb
+
typedef std::map<const State *, Node *> s2n_map;
typedef std::map<Node *, multiarc_t> arcs_t;
typedef std::map<Node *, way_arc_t> arcsets_t;
~Node ();
bool end () const;
void calc_dist ();
- arccount_t sizeof_permutate (arccount_t inarcs, arccount_t len);
+ permuts_t sizeof_permutate (permuts_t inarcs, permuts_t len);
template <typename cunit_t, typename key_t>
void permutate (const multipath_t & prefix, FILE * input, FILE * keys);
template <typename cunit_t, typename key_t>
- arccount_t cover (const multipath_t & prefix, FILE * input, FILE * keys);
- arccount_t naked_ways (const way_t & prefix, std::vector<way_t> & ways);
+ covers_t cover (const multipath_t & prefix, FILE * input, FILE * keys);
+ nakeds_t naked_ways (const way_t & prefix, std::vector<way_t> & ways);
FORBID_COPY (Node);
};