depth: make constructor explicit

This commit is contained in:
Justin Viiret 2017-03-30 16:33:11 +11:00 committed by Matthew Barr
parent 37cb93e60f
commit cf82924a39
17 changed files with 248 additions and 221 deletions

View File

@ -501,7 +501,7 @@ buildCastle(const CastleProto &proto,
// possibly means that we've got a repeat that we can't trigger. We do // possibly means that we've got a repeat that we can't trigger. We do
// need to cope with it though. // need to cope with it though.
if (contains(triggers, top)) { if (contains(triggers, top)) {
min_period = minPeriod(triggers.at(top), cr, &is_reset); min_period = depth(minPeriod(triggers.at(top), cr, &is_reset));
} }
if (min_period > pr.bounds.max) { if (min_period > pr.bounds.max) {

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2015-2016, Intel Corporation * Copyright (c) 2015-2017, Intel Corporation
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
@ -208,7 +208,7 @@ void reformAnchoredRepeatsComponent(NGHolder &g,
/* get bounds */ /* get bounds */
depth min; depth min;
depth max = 1; depth max(1);
if (selfLoop) { if (selfLoop) {
// A self-loop indicates that this is a '.+' or '.*' // A self-loop indicates that this is a '.+' or '.*'
@ -229,9 +229,9 @@ void reformAnchoredRepeatsComponent(NGHolder &g,
} }
} }
min = 0; min = depth(0);
} else { } else {
min = 1; min = depth(1);
} }
*startBegin = min; *startBegin = min;
@ -326,8 +326,8 @@ void reformUnanchoredRepeatsComponent(NGHolder &g,
} }
/* get bounds */ /* get bounds */
depth min = 1; depth min(1);
depth max = 1; depth max(1);
if (selfLoop) { if (selfLoop) {
// A self-loop indicates that this is a '.+' or '.*' // A self-loop indicates that this is a '.+' or '.*'
@ -349,7 +349,7 @@ void reformUnanchoredRepeatsComponent(NGHolder &g,
DEBUG_PRINTF("min greater than one, skipping\n"); DEBUG_PRINTF("min greater than one, skipping\n");
return; return;
} }
min = 0; min = depth(0);
} }
*startBegin += min; *startBegin += min;
@ -502,7 +502,7 @@ void collapseVariableDotRepeat(NGHolder &g, NFAVertex start,
startEnd->str().c_str()); startEnd->str().c_str());
if (start == g.start && startEnd->is_infinite()) { if (start == g.start && startEnd->is_infinite()) {
*startEnd = dots.size(); *startEnd = depth(dots.size());
} else if (startEnd->is_finite()) { } else if (startEnd->is_finite()) {
*startEnd += dots.size(); *startEnd += dots.size();
} }

View File

@ -372,15 +372,16 @@ deque<unique_ptr<NGHolder>> calcComponents(unique_ptr<NGHolder> g,
} }
bool shell_comp = false; bool shell_comp = false;
splitIntoComponents(std::move(g), comps, MAX_HEAD_SHELL_DEPTH, splitIntoComponents(std::move(g), comps, depth(MAX_HEAD_SHELL_DEPTH),
MAX_TAIL_SHELL_DEPTH, &shell_comp); depth(MAX_TAIL_SHELL_DEPTH), &shell_comp);
if (shell_comp) { if (shell_comp) {
DEBUG_PRINTF("re-running on shell comp\n"); DEBUG_PRINTF("re-running on shell comp\n");
assert(!comps.empty()); assert(!comps.empty());
auto sc = std::move(comps.back()); auto sc = std::move(comps.back());
comps.pop_back(); comps.pop_back();
splitIntoComponents(std::move(sc), comps, 0, 0, &shell_comp); splitIntoComponents(std::move(sc), comps, depth(0), depth(0),
&shell_comp);
} }
DEBUG_PRINTF("finished; split into %zu components\n", comps.size()); DEBUG_PRINTF("finished; split into %zu components\n", comps.size());

View File

@ -84,7 +84,7 @@ void checkVertex(const ReportManager &rm, const NGHolder &g, NFAVertex v,
return; return;
} }
if (is_any_start(v, g)) { if (is_any_start(v, g)) {
info.min = 0; info.min = depth(0);
info.max = max(info.max, depth(0)); info.max = max(info.max, depth(0));
return; return;
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2015-2016, Intel Corporation * Copyright (c) 2015-2017, Intel Corporation
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
@ -26,7 +26,8 @@
* POSSIBILITY OF SUCH DAMAGE. * POSSIBILITY OF SUCH DAMAGE.
*/ */
/** \file /**
* \file
* \brief Prefilter Reductions. * \brief Prefilter Reductions.
* *
* This file contains routines for reducing the size of an NFA graph that we * This file contains routines for reducing the size of an NFA graph that we
@ -92,13 +93,13 @@ struct RegionInfo {
u32 id; //!< region id u32 id; //!< region id
deque<NFAVertex> vertices; //!< vertices in the region deque<NFAVertex> vertices; //!< vertices in the region
CharReach reach; //!< union of region reach CharReach reach; //!< union of region reach
depth minWidth = 0; //!< min width of region subgraph depth minWidth{0}; //!< min width of region subgraph
depth maxWidth = depth::infinity(); //!< max width of region subgraph depth maxWidth{depth::infinity()}; //!< max width of region subgraph
bool atBoundary = false; //!< region is next to an accept bool atBoundary = false; //!< region is next to an accept
// Bigger score is better. // Bigger score is better.
size_t score() const { size_t score() const {
// FIXME: charreach should be a signal? // TODO: charreach should be a signal?
size_t numVertices = vertices.size(); size_t numVertices = vertices.size();
if (atBoundary) { if (atBoundary) {
return numVertices - min(PENALTY_BOUNDARY, numVertices); return numVertices - min(PENALTY_BOUNDARY, numVertices);

View File

@ -105,8 +105,8 @@ typedef boost::filtered_graph<NGHolder, ReachFilter<NGHolder>> RepeatGraph;
struct ReachSubgraph { struct ReachSubgraph {
vector<NFAVertex> vertices; vector<NFAVertex> vertices;
depth repeatMin = 0; depth repeatMin{0};
depth repeatMax = 0; depth repeatMax{0};
u32 minPeriod = 1; u32 minPeriod = 1;
bool is_reset = false; bool is_reset = false;
enum RepeatType historyType = REPEAT_RING; enum RepeatType historyType = REPEAT_RING;
@ -586,8 +586,8 @@ bool processSubgraph(const NGHolder &g, ReachSubgraph &rsi,
range.first, range.second); range.first, range.second);
return false; return false;
} }
rsi.repeatMin = range.first; rsi.repeatMin = depth(range.first);
rsi.repeatMax = range.second; rsi.repeatMax = depth(range.second);
// If we've got a self-loop anywhere, we've got inf max. // If we've got a self-loop anywhere, we've got inf max.
if (anySelfLoop(g, rsi.vertices.begin(), rsi.vertices.end())) { if (anySelfLoop(g, rsi.vertices.begin(), rsi.vertices.end())) {
@ -2106,7 +2106,7 @@ void populateFixedTopInfo(const map<u32, u32> &fixed_depth_tops,
td = depth::infinity(); td = depth::infinity();
break; break;
} }
depth td_t = fixed_depth_tops.at(top); depth td_t(fixed_depth_tops.at(top));
if (td == td_t) { if (td == td_t) {
continue; continue;
} else if (td == depth::infinity()) { } else if (td == depth::infinity()) {
@ -2479,7 +2479,7 @@ bool isPureRepeat(const NGHolder &g, PureRepeat &repeat) {
// have the same report set as the vertices in the repeat. // have the same report set as the vertices in the repeat.
if (repeat.bounds.min == depth(1) && if (repeat.bounds.min == depth(1) &&
g[g.start].reports == g[v].reports) { g[g.start].reports == g[v].reports) {
repeat.bounds.min = 0; repeat.bounds.min = depth(0);
DEBUG_PRINTF("graph is %s repeat\n", repeat.bounds.str().c_str()); DEBUG_PRINTF("graph is %s repeat\n", repeat.bounds.str().c_str());
} else { } else {
DEBUG_PRINTF("not a supported repeat\n"); DEBUG_PRINTF("not a supported repeat\n");

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2015-2016, Intel Corporation * Copyright (c) 2015-2017, Intel Corporation
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
@ -94,7 +94,7 @@ vector<DepthMinMax> getDistancesFromSOM(const NGHolder &g_orig) {
if (v_orig == g_orig.startDs || is_virtual_start(v_orig, g_orig)) { if (v_orig == g_orig.startDs || is_virtual_start(v_orig, g_orig)) {
// StartDs and virtual starts always have zero depth. // StartDs and virtual starts always have zero depth.
d = DepthMinMax(0, 0); d = DepthMinMax(depth(0), depth(0));
} else { } else {
u32 new_idx = g[v_new].index; u32 new_idx = g[v_new].index;
d = temp_depths.at(new_idx); d = temp_depths.at(new_idx);

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2015-2016, Intel Corporation * Copyright (c) 2015-2017, Intel Corporation
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
@ -157,12 +157,12 @@ depth findMaxWidth(const NGHolder &h, const SpecialEdgeFilter &filter,
if (colors.at(NODE_ACCEPT) == boost::white_color) { if (colors.at(NODE_ACCEPT) == boost::white_color) {
acceptDepth = depth::unreachable(); acceptDepth = depth::unreachable();
} else { } else {
acceptDepth = -1 * distance.at(NODE_ACCEPT); acceptDepth = depth(-1 * distance.at(NODE_ACCEPT));
} }
if (colors.at(NODE_ACCEPT_EOD) == boost::white_color) { if (colors.at(NODE_ACCEPT_EOD) == boost::white_color) {
acceptEodDepth = depth::unreachable(); acceptEodDepth = depth::unreachable();
} else { } else {
acceptEodDepth = -1 * distance.at(NODE_ACCEPT_EOD); acceptEodDepth = depth(-1 * distance.at(NODE_ACCEPT_EOD));
} }
depth d; depth d;

View File

@ -551,7 +551,7 @@ bool handleMixedPrefixCliche(const NGHolder &h, RoseGraph &g, RoseVertex v,
&& is_subset_of(exits, base_succ) && is_subset_of(exits, base_succ)
&& is_subset_of(base_succ, exits_and_repeat_verts)) { && is_subset_of(base_succ, exits_and_repeat_verts)) {
/* we have a jump edge */ /* we have a jump edge */
ri.repeatMin = 0; ri.repeatMin = depth(0);
} else { } else {
return false; return false;
} }
@ -802,7 +802,7 @@ void convertAnchPrefixToBounds(RoseBuildImpl &tbi) {
DepthMinMax bounds(pr.bounds); // copy DepthMinMax bounds(pr.bounds); // copy
if (delay_adj > bounds.min) { if (delay_adj > bounds.min) {
bounds.min = 0; bounds.min = depth(0);
} else { } else {
bounds.min -= delay_adj; bounds.min -= delay_adj;
} }

View File

@ -425,8 +425,8 @@ struct OutfixInfo {
RevAccInfo rev_info; RevAccInfo rev_info;
u32 maxBAWidth = 0; //!< max bi-anchored width u32 maxBAWidth = 0; //!< max bi-anchored width
depth minWidth = depth::infinity(); depth minWidth{depth::infinity()};
depth maxWidth = 0; depth maxWidth{0};
u64a maxOffset = 0; u64a maxOffset = 0;
bool in_sbmatcher = false; //!< handled by small-block matcher. bool in_sbmatcher = false; //!< handled by small-block matcher.

View File

@ -970,7 +970,7 @@ void RoseSuffixInfo::reset(void) {
rdfa.reset(); rdfa.reset();
haig.reset(); haig.reset();
tamarama.reset(); tamarama.reset();
dfa_min_width = 0; dfa_min_width = depth(0);
dfa_max_width = depth::infinity(); dfa_max_width = depth::infinity();
} }
@ -1181,7 +1181,7 @@ void LeftEngInfo::reset(void) {
tamarama.reset(); tamarama.reset();
lag = 0; lag = 0;
leftfix_report = MO_INVALID_IDX; leftfix_report = MO_INVALID_IDX;
dfa_min_width = 0; dfa_min_width = depth(0);
dfa_max_width = depth::infinity(); dfa_max_width = depth::infinity();
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2015-2016, Intel Corporation * Copyright (c) 2015-2017, Intel Corporation
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
@ -85,7 +85,7 @@ struct LeftEngInfo {
std::shared_ptr<TamaProto> tamarama; std::shared_ptr<TamaProto> tamarama;
u32 lag = 0U; u32 lag = 0U;
ReportID leftfix_report = MO_INVALID_IDX; ReportID leftfix_report = MO_INVALID_IDX;
depth dfa_min_width = 0; depth dfa_min_width{0};
depth dfa_max_width = depth::infinity(); depth dfa_max_width = depth::infinity();
bool operator==(const LeftEngInfo &other) const { bool operator==(const LeftEngInfo &other) const {
@ -125,7 +125,7 @@ struct RoseSuffixInfo {
std::shared_ptr<raw_som_dfa> haig; std::shared_ptr<raw_som_dfa> haig;
std::shared_ptr<raw_dfa> rdfa; std::shared_ptr<raw_dfa> rdfa;
std::shared_ptr<TamaProto> tamarama; std::shared_ptr<TamaProto> tamarama;
depth dfa_min_width = 0; depth dfa_min_width{0};
depth dfa_max_width = depth::infinity(); depth dfa_max_width = depth::infinity();
bool operator==(const RoseSuffixInfo &b) const; bool operator==(const RoseSuffixInfo &b) const;

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2015, Intel Corporation * Copyright (c) 2015-2017, Intel Corporation
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
@ -54,9 +54,10 @@ struct DepthOverflowError {};
*/ */
class depth { class depth {
public: public:
depth() : val(val_unreachable) {} /** \brief The default depth is special value "unreachable". */
depth() = default;
depth(u32 v) : val(v) { explicit depth(u32 v) : val(v) {
if (v > max_value()) { if (v > max_value()) {
DEBUG_PRINTF("depth %u too large to represent!\n", v); DEBUG_PRINTF("depth %u too large to represent!\n", v);
throw DepthOverflowError(); throw DepthOverflowError();
@ -196,6 +197,29 @@ public:
return *this; return *this;
} }
depth operator-(s32 d) const {
if (is_unreachable()) {
return unreachable();
}
if (is_infinite()) {
return infinity();
}
s64a rv = val - d;
if (rv < 0 || (u64a)rv >= val_infinity) {
DEBUG_PRINTF("depth %lld too large to represent!\n", rv);
throw DepthOverflowError();
}
return depth((u32)rv);
}
depth operator-=(s32 d) {
depth rv = *this - d;
*this = rv;
return *this;
}
#ifdef DUMP_SUPPORT #ifdef DUMP_SUPPORT
/** \brief Render as a string, useful for debugging. */ /** \brief Render as a string, useful for debugging. */
std::string str() const; std::string str() const;
@ -209,7 +233,7 @@ private:
static constexpr u32 val_infinity = (1u << 31) - 1; static constexpr u32 val_infinity = (1u << 31) - 1;
static constexpr u32 val_unreachable = 1u << 31; static constexpr u32 val_unreachable = 1u << 31;
u32 val; u32 val = val_unreachable;
}; };
/** /**

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2015, Intel Corporation * Copyright (c) 2015-2017, Intel Corporation
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
@ -112,9 +112,10 @@ TEST(depth, add_finite) {
ASSERT_EQ(depth(900), depth(1000) + s32{-100}); ASSERT_EQ(depth(900), depth(1000) + s32{-100});
// overflow must throw // overflow must throw
depth max_depth(depth::max_value());
depth d; depth d;
ASSERT_THROW(d = depth::max_value() + depth(1), DepthOverflowError); ASSERT_THROW(d = max_depth + depth(1), DepthOverflowError);
ASSERT_THROW(d = depth::max_value() + 1, DepthOverflowError); ASSERT_THROW(d = max_depth + 1, DepthOverflowError);
// underflow must throw // underflow must throw
ASSERT_THROW(d = depth(0) + s32{-1}, DepthOverflowError); ASSERT_THROW(d = depth(0) + s32{-1}, DepthOverflowError);
@ -267,11 +268,11 @@ TEST(depth, unordered_set) {
ue2::unordered_set<depth> depths; ue2::unordered_set<depth> depths;
for (const auto &val : finite_values) { for (const auto &val : finite_values) {
depths.insert(val); depths.emplace(val);
} }
for (const auto &val : finite_values) { for (const auto &val : finite_values) {
ASSERT_TRUE(depths.find(val) != depths.end()); ASSERT_TRUE(depths.find(depth(val)) != depths.end());
} }
ASSERT_TRUE(depths.find(depth::infinity()) == depths.end()); ASSERT_TRUE(depths.find(depth::infinity()) == depths.end());

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2015-2016, Intel Corporation * Copyright (c) 2015-2017, Intel Corporation
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
@ -66,28 +66,28 @@ struct PureRepeatTest {
class NFAPureRepeatTest : public TestWithParam<PureRepeatTest> { }; class NFAPureRepeatTest : public TestWithParam<PureRepeatTest> { };
static const PureRepeatTest pureRepeatTests[] = { static const PureRepeatTest pureRepeatTests[] = {
{ "^.*", 0, depth::infinity() }, { "^.*", depth(0), depth::infinity() },
{ "^.+", 1, depth::infinity() }, { "^.+", depth(1), depth::infinity() },
{ "^.", 1, 1 }, { "^.", depth(1), depth(1) },
{ "^..", 2, 2 }, { "^..", depth(2), depth(2) },
{ "^.?.", 1, 2 }, { "^.?.", depth(1), depth(2) },
{ "^.{1,2}", 1, 2 }, { "^.{1,2}", depth(1), depth(2) },
{ "^.{1,3}", 1, 3 }, { "^.{1,3}", depth(1), depth(3) },
{ "^.{1,10}", 1, 10 }, { "^.{1,10}", depth(1), depth(10) },
{ "^.{1,200}", 1, 200 }, { "^.{1,200}", depth(1), depth(200) },
{ "^.{200}", 200, 200 }, { "^.{200}", depth(200), depth(200) },
{ "^.{0,}", 0, depth::infinity() }, { "^.{0,}", depth(0), depth::infinity() },
{ "^.{1,}", 1, depth::infinity() }, { "^.{1,}", depth(1), depth::infinity() },
{ "^.{2,}", 2, depth::infinity() }, { "^.{2,}", depth(2), depth::infinity() },
{ "^.{10,}", 10, depth::infinity() }, { "^.{10,}", depth(10), depth::infinity() },
{ "^.{200,}", 200, depth::infinity() }, { "^.{200,}", depth(200), depth::infinity() },
{ "^.{5000,}", 5000, depth::infinity() }, { "^.{5000,}", depth(5000), depth::infinity() },
{ "^.{0,1}", 0, 1 }, { "^.{0,1}", depth(0), depth(1) },
{ "^.{0,2}", 0, 2 }, { "^.{0,2}", depth(0), depth(2) },
{ "^.{0,100}", 0, 100 }, { "^.{0,100}", depth(0), depth(100) },
{ "^.{0,5000}", 0, 5000 }, { "^.{0,5000}", depth(0), depth(5000) },
{ "^x{10}x{20,30}", 30, 40 }, { "^x{10}x{20,30}", depth(30), depth(40) },
{ "^..?..?..?..?..?", 5, 10 } { "^..?..?..?..?..?", depth(5), depth(10) }
}; };
INSTANTIATE_TEST_CASE_P(PureRepeat, NFAPureRepeatTest, INSTANTIATE_TEST_CASE_P(PureRepeat, NFAPureRepeatTest,

View File

@ -52,26 +52,26 @@ struct WidthTest {
class NFAWidthTest : public TestWithParam<WidthTest> { }; class NFAWidthTest : public TestWithParam<WidthTest> { };
static const WidthTest widthTests[] = { static const WidthTest widthTests[] = {
{ "()", 0, 0 }, { "()", depth(0), depth(0) },
{ "a", 1, 1 }, { "a", depth(1), depth(1) },
{ "a?b", 1, 2 }, { "a?b", depth(1), depth(2) },
{ "foobar", 6, 6 }, { "foobar", depth(6), depth(6) },
{ "foo(bar)?", 3, 6 }, { "foo(bar)?", depth(3), depth(6) },
{ "(a|ab|abc|abcd)", 1, 4 }, { "(a|ab|abc|abcd)", depth(1), depth(4) },
{ "foo.*bar", 6, depth::infinity() }, { "foo.*bar", depth(6), depth::infinity() },
{ "foo(bar)*", 3, depth::infinity() }, { "foo(bar)*", depth(3), depth::infinity() },
{ "foo(bar)+", 6, depth::infinity() }, { "foo(bar)+", depth(6), depth::infinity() },
{ "foo(bar){1,3}", 6, 12 }, { "foo(bar){1,3}", depth(6), depth(12) },
{ "(abcd)+", 4, depth::infinity() }, { "(abcd)+", depth(4), depth::infinity() },
{ "foo\\z", 3, 3 }, { "foo\\z", depth(3), depth(3) },
{ "^foo", 3, 3 }, { "^foo", depth(3), depth(3) },
{ "^foo|bar.*baz", 3, depth::infinity() }, { "^foo|bar.*baz", depth(3), depth::infinity() },
{ "^foobar.*|baz", 3, depth::infinity() }, { "^foobar.*|baz", depth(3), depth::infinity() },
{ "foo(\\z|bar)", 3, 6 }, { "foo(\\z|bar)", depth(3), depth(6) },
{ "foo(|bar\\z)", 3, 6 }, { "foo(|bar\\z)", depth(3), depth(6) },
{ "foo.{0,15}bar", 6, 21 }, { "foo.{0,15}bar", depth(6), depth(21) },
{ "foo.{0,15}.*bar", 6, depth::infinity() }, { "foo.{0,15}.*bar", depth(6), depth::infinity() },
{ "(?smi)^(aa[^a]aa$|a|a+\\Z|a)", 1, depth::infinity() } { "(?smi)^(aa[^a]aa$|a|a+\\Z|a)", depth(1), depth::infinity() }
}; };
INSTANTIATE_TEST_CASE_P(NFAWidth, NFAWidthTest, ValuesIn(widthTests)); INSTANTIATE_TEST_CASE_P(NFAWidth, NFAWidthTest, ValuesIn(widthTests));

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2015, Intel Corporation * Copyright (c) 2015-2017, Intel Corporation
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
@ -106,96 +106,96 @@ private:
static const RepeatTestInfo repeatTests[] = { static const RepeatTestInfo repeatTests[] = {
// Fixed repeats -- ring model // Fixed repeats -- ring model
{ REPEAT_RING, 2, 2 }, { REPEAT_RING, depth(2), depth(2) },
{ REPEAT_RING, 4, 4 }, { REPEAT_RING, depth(4), depth(4) },
{ REPEAT_RING, 10, 10 }, { REPEAT_RING, depth(10), depth(10) },
{ REPEAT_RING, 16, 16 }, { REPEAT_RING, depth(16), depth(16) },
{ REPEAT_RING, 20, 20 }, { REPEAT_RING, depth(20), depth(20) },
{ REPEAT_RING, 30, 30 }, { REPEAT_RING, depth(30), depth(30) },
{ REPEAT_RING, 50, 50 }, { REPEAT_RING, depth(50), depth(50) },
{ REPEAT_RING, 64, 64 }, { REPEAT_RING, depth(64), depth(64) },
{ REPEAT_RING, 65, 65 }, { REPEAT_RING, depth(65), depth(65) },
{ REPEAT_RING, 100, 100 }, { REPEAT_RING, depth(100), depth(100) },
{ REPEAT_RING, 200, 200 }, { REPEAT_RING, depth(200), depth(200) },
{ REPEAT_RING, 1000, 1000 }, { REPEAT_RING, depth(1000), depth(1000) },
{ REPEAT_RING, 4100, 4100 }, { REPEAT_RING, depth(4100), depth(4100) },
{ REPEAT_RING, 16000, 16000 }, { REPEAT_RING, depth(16000), depth(16000) },
// {0, N} repeats -- last model // {0, N} repeats -- last model
{ REPEAT_LAST, 0, 4 }, { REPEAT_LAST, depth(0), depth(4) },
{ REPEAT_LAST, 0, 10 }, { REPEAT_LAST, depth(0), depth(10) },
{ REPEAT_LAST, 0, 20 }, { REPEAT_LAST, depth(0), depth(20) },
{ REPEAT_LAST, 0, 30 }, { REPEAT_LAST, depth(0), depth(30) },
{ REPEAT_LAST, 0, 50 }, { REPEAT_LAST, depth(0), depth(50) },
{ REPEAT_LAST, 0, 100 }, { REPEAT_LAST, depth(0), depth(100) },
{ REPEAT_LAST, 0, 200 }, { REPEAT_LAST, depth(0), depth(200) },
{ REPEAT_LAST, 0, 1000 }, { REPEAT_LAST, depth(0), depth(1000) },
{ REPEAT_LAST, 0, 16000 }, { REPEAT_LAST, depth(0), depth(16000) },
// {0, N} repeats -- ring model (though we use 'last' model in practice) // {0, N} repeats -- ring model (though we use 'last' model in practice)
{ REPEAT_RING, 0, 2 }, { REPEAT_RING, depth(0), depth(2) },
{ REPEAT_RING, 0, 4 }, { REPEAT_RING, depth(0), depth(4) },
{ REPEAT_RING, 0, 10 }, { REPEAT_RING, depth(0), depth(10) },
{ REPEAT_RING, 0, 20 }, { REPEAT_RING, depth(0), depth(20) },
{ REPEAT_RING, 0, 30 }, { REPEAT_RING, depth(0), depth(30) },
{ REPEAT_RING, 0, 50 }, { REPEAT_RING, depth(0), depth(50) },
{ REPEAT_RING, 0, 64 }, { REPEAT_RING, depth(0), depth(64) },
{ REPEAT_RING, 0, 65 }, { REPEAT_RING, depth(0), depth(65) },
{ REPEAT_RING, 0, 100 }, { REPEAT_RING, depth(0), depth(100) },
{ REPEAT_RING, 0, 200 }, { REPEAT_RING, depth(0), depth(200) },
{ REPEAT_RING, 0, 1000 }, { REPEAT_RING, depth(0), depth(1000) },
{ REPEAT_RING, 0, 16000 }, { REPEAT_RING, depth(0), depth(16000) },
// {N, M} repeats -- ring model // {N, M} repeats -- ring model
{ REPEAT_RING, 2, 3 }, { REPEAT_RING, depth(2), depth(3) },
{ REPEAT_RING, 1, 4 }, { REPEAT_RING, depth(1), depth(4) },
{ REPEAT_RING, 5, 10 }, { REPEAT_RING, depth(5), depth(10) },
{ REPEAT_RING, 10, 20 }, { REPEAT_RING, depth(10), depth(20) },
{ REPEAT_RING, 10, 50 }, { REPEAT_RING, depth(10), depth(50) },
{ REPEAT_RING, 50, 60 }, { REPEAT_RING, depth(50), depth(60) },
{ REPEAT_RING, 100, 200 }, { REPEAT_RING, depth(100), depth(200) },
{ REPEAT_RING, 1, 200 }, { REPEAT_RING, depth(1), depth(200) },
{ REPEAT_RING, 10, 16000 }, { REPEAT_RING, depth(10), depth(16000) },
{ REPEAT_RING, 10000, 16000 }, { REPEAT_RING, depth(10000), depth(16000) },
// {N, M} repeats -- range model // {N, M} repeats -- range model
{ REPEAT_RANGE, 1, 4 }, { REPEAT_RANGE, depth(1), depth(4) },
{ REPEAT_RANGE, 5, 10 }, { REPEAT_RANGE, depth(5), depth(10) },
{ REPEAT_RANGE, 10, 20 }, { REPEAT_RANGE, depth(10), depth(20) },
{ REPEAT_RANGE, 10, 50 }, { REPEAT_RANGE, depth(10), depth(50) },
{ REPEAT_RANGE, 50, 60 }, { REPEAT_RANGE, depth(50), depth(60) },
{ REPEAT_RANGE, 100, 200 }, { REPEAT_RANGE, depth(100), depth(200) },
{ REPEAT_RANGE, 1, 200 }, { REPEAT_RANGE, depth(1), depth(200) },
{ REPEAT_RANGE, 10, 16000 }, { REPEAT_RANGE, depth(10), depth(16000) },
{ REPEAT_RANGE, 10000, 16000 }, { REPEAT_RANGE, depth(10000), depth(16000) },
// {N,M} repeats -- small bitmap model // {N,M} repeats -- small bitmap model
{ REPEAT_BITMAP, 1, 2 }, { REPEAT_BITMAP, depth(1), depth(2) },
{ REPEAT_BITMAP, 5, 10 }, { REPEAT_BITMAP, depth(5), depth(10) },
{ REPEAT_BITMAP, 10, 20 }, { REPEAT_BITMAP, depth(10), depth(20) },
{ REPEAT_BITMAP, 20, 40 }, { REPEAT_BITMAP, depth(20), depth(40) },
{ REPEAT_BITMAP, 1, 63 }, { REPEAT_BITMAP, depth(1), depth(63) },
{ REPEAT_BITMAP, 50, 63 }, { REPEAT_BITMAP, depth(50), depth(63) },
// {N,M} repeats -- trailer model // {N,M} repeats -- trailer model
{ REPEAT_TRAILER, 1, 2 }, { REPEAT_TRAILER, depth(1), depth(2) },
{ REPEAT_TRAILER, 8, 8 }, { REPEAT_TRAILER, depth(8), depth(8) },
{ REPEAT_TRAILER, 0, 8 }, { REPEAT_TRAILER, depth(0), depth(8) },
{ REPEAT_TRAILER, 10, 20 }, { REPEAT_TRAILER, depth(10), depth(20) },
{ REPEAT_TRAILER, 1, 32 }, { REPEAT_TRAILER, depth(1), depth(32) },
{ REPEAT_TRAILER, 64, 64 }, { REPEAT_TRAILER, depth(64), depth(64) },
{ REPEAT_TRAILER, 1, 64 }, { REPEAT_TRAILER, depth(1), depth(64) },
{ REPEAT_TRAILER, 1, 100 }, { REPEAT_TRAILER, depth(1), depth(100) },
{ REPEAT_TRAILER, 1, 2000 }, { REPEAT_TRAILER, depth(1), depth(2000) },
{ REPEAT_TRAILER, 50, 200 }, { REPEAT_TRAILER, depth(50), depth(200) },
{ REPEAT_TRAILER, 50, 1000 }, { REPEAT_TRAILER, depth(50), depth(1000) },
{ REPEAT_TRAILER, 64, 1024 }, { REPEAT_TRAILER, depth(64), depth(1024) },
// {N,} repeats -- first model // {N,} repeats -- first model
{ REPEAT_FIRST, 0, depth::infinity() }, { REPEAT_FIRST, depth(0), depth::infinity() },
{ REPEAT_FIRST, 1, depth::infinity() }, { REPEAT_FIRST, depth(1), depth::infinity() },
{ REPEAT_FIRST, 4, depth::infinity() }, { REPEAT_FIRST, depth(4), depth::infinity() },
{ REPEAT_FIRST, 10, depth::infinity() }, { REPEAT_FIRST, depth(10), depth::infinity() },
{ REPEAT_FIRST, 50, depth::infinity() }, { REPEAT_FIRST, depth(50), depth::infinity() },
{ REPEAT_FIRST, 100, depth::infinity() }, { REPEAT_FIRST, depth(100), depth::infinity() },
{ REPEAT_FIRST, 1000, depth::infinity() }, { REPEAT_FIRST, depth(1000), depth::infinity() },
{ REPEAT_FIRST, 3000, depth::infinity() }, { REPEAT_FIRST, depth(3000), depth::infinity() },
{ REPEAT_FIRST, 10000, depth::infinity() }, { REPEAT_FIRST, depth(10000), depth::infinity() },
// {,} repeats -- always // {,} repeats -- always
{ REPEAT_ALWAYS, 0, depth::infinity() }, { REPEAT_ALWAYS, depth(0), depth::infinity() },
}; };
INSTANTIATE_TEST_CASE_P(Repeat, RepeatTest, ValuesIn(repeatTests)); INSTANTIATE_TEST_CASE_P(Repeat, RepeatTest, ValuesIn(repeatTests));
@ -508,55 +508,55 @@ const u32 sparsePeriods[] = {
static static
const RepeatTestInfo sparseRepeats[] = { const RepeatTestInfo sparseRepeats[] = {
// Fixed repeats // Fixed repeats
{ REPEAT_SPARSE_OPTIMAL_P, 10, 10 }, { REPEAT_SPARSE_OPTIMAL_P, depth(10), depth(10) },
{ REPEAT_SPARSE_OPTIMAL_P, 20, 20 }, { REPEAT_SPARSE_OPTIMAL_P, depth(20), depth(20) },
{ REPEAT_SPARSE_OPTIMAL_P, 40, 40 }, { REPEAT_SPARSE_OPTIMAL_P, depth(40), depth(40) },
{ REPEAT_SPARSE_OPTIMAL_P, 80, 80 }, { REPEAT_SPARSE_OPTIMAL_P, depth(80), depth(80) },
{ REPEAT_SPARSE_OPTIMAL_P, 100, 100 }, { REPEAT_SPARSE_OPTIMAL_P, depth(100), depth(100) },
{ REPEAT_SPARSE_OPTIMAL_P, 150, 150 }, { REPEAT_SPARSE_OPTIMAL_P, depth(150), depth(150) },
{ REPEAT_SPARSE_OPTIMAL_P, 200, 200 }, { REPEAT_SPARSE_OPTIMAL_P, depth(200), depth(200) },
{ REPEAT_SPARSE_OPTIMAL_P, 250, 250 }, { REPEAT_SPARSE_OPTIMAL_P, depth(250), depth(250) },
{ REPEAT_SPARSE_OPTIMAL_P, 300, 300 }, { REPEAT_SPARSE_OPTIMAL_P, depth(300), depth(300) },
{ REPEAT_SPARSE_OPTIMAL_P, 350, 350 }, { REPEAT_SPARSE_OPTIMAL_P, depth(350), depth(350) },
{ REPEAT_SPARSE_OPTIMAL_P, 400, 400 }, { REPEAT_SPARSE_OPTIMAL_P, depth(400), depth(400) },
{ REPEAT_SPARSE_OPTIMAL_P, 500, 500 }, { REPEAT_SPARSE_OPTIMAL_P, depth(500), depth(500) },
{ REPEAT_SPARSE_OPTIMAL_P, 600, 600 }, { REPEAT_SPARSE_OPTIMAL_P, depth(600), depth(600) },
{ REPEAT_SPARSE_OPTIMAL_P, 800, 800 }, { REPEAT_SPARSE_OPTIMAL_P, depth(800), depth(800) },
{ REPEAT_SPARSE_OPTIMAL_P, 1000, 1000 }, { REPEAT_SPARSE_OPTIMAL_P, depth(1000), depth(1000) },
{ REPEAT_SPARSE_OPTIMAL_P, 1500, 1500 }, { REPEAT_SPARSE_OPTIMAL_P, depth(1500), depth(1500) },
{ REPEAT_SPARSE_OPTIMAL_P, 2000, 2000 }, { REPEAT_SPARSE_OPTIMAL_P, depth(2000), depth(2000) },
{ REPEAT_SPARSE_OPTIMAL_P, 2500, 2500 }, { REPEAT_SPARSE_OPTIMAL_P, depth(2500), depth(2500) },
{ REPEAT_SPARSE_OPTIMAL_P, 3000, 3000 }, { REPEAT_SPARSE_OPTIMAL_P, depth(3000), depth(3000) },
{ REPEAT_SPARSE_OPTIMAL_P, 3500, 3500 }, { REPEAT_SPARSE_OPTIMAL_P, depth(3500), depth(3500) },
{ REPEAT_SPARSE_OPTIMAL_P, 4000, 4000 }, { REPEAT_SPARSE_OPTIMAL_P, depth(4000), depth(4000) },
{ REPEAT_SPARSE_OPTIMAL_P, 4500, 4500 }, { REPEAT_SPARSE_OPTIMAL_P, depth(4500), depth(4500) },
{ REPEAT_SPARSE_OPTIMAL_P, 5000, 5000 }, { REPEAT_SPARSE_OPTIMAL_P, depth(5000), depth(5000) },
{ REPEAT_SPARSE_OPTIMAL_P, 65534, 65534 }, { REPEAT_SPARSE_OPTIMAL_P, depth(65534), depth(65534) },
// {N, M} repeats // {N, M} repeats
{ REPEAT_SPARSE_OPTIMAL_P, 10, 20 }, { REPEAT_SPARSE_OPTIMAL_P, depth(10), depth(20) },
{ REPEAT_SPARSE_OPTIMAL_P, 20, 40 }, { REPEAT_SPARSE_OPTIMAL_P, depth(20), depth(40) },
{ REPEAT_SPARSE_OPTIMAL_P, 40, 80 }, { REPEAT_SPARSE_OPTIMAL_P, depth(40), depth(80) },
{ REPEAT_SPARSE_OPTIMAL_P, 80, 100 }, { REPEAT_SPARSE_OPTIMAL_P, depth(80), depth(100) },
{ REPEAT_SPARSE_OPTIMAL_P, 100, 120 }, { REPEAT_SPARSE_OPTIMAL_P, depth(100), depth(120) },
{ REPEAT_SPARSE_OPTIMAL_P, 150, 180 }, { REPEAT_SPARSE_OPTIMAL_P, depth(150), depth(180) },
{ REPEAT_SPARSE_OPTIMAL_P, 200, 400 }, { REPEAT_SPARSE_OPTIMAL_P, depth(200), depth(400) },
{ REPEAT_SPARSE_OPTIMAL_P, 250, 500 }, { REPEAT_SPARSE_OPTIMAL_P, depth(250), depth(500) },
{ REPEAT_SPARSE_OPTIMAL_P, 300, 400 }, { REPEAT_SPARSE_OPTIMAL_P, depth(300), depth(400) },
{ REPEAT_SPARSE_OPTIMAL_P, 350, 500 }, { REPEAT_SPARSE_OPTIMAL_P, depth(350), depth(500) },
{ REPEAT_SPARSE_OPTIMAL_P, 400, 500 }, { REPEAT_SPARSE_OPTIMAL_P, depth(400), depth(500) },
{ REPEAT_SPARSE_OPTIMAL_P, 500, 600 }, { REPEAT_SPARSE_OPTIMAL_P, depth(500), depth(600) },
{ REPEAT_SPARSE_OPTIMAL_P, 600, 700 }, { REPEAT_SPARSE_OPTIMAL_P, depth(600), depth(700) },
{ REPEAT_SPARSE_OPTIMAL_P, 800, 1000 }, { REPEAT_SPARSE_OPTIMAL_P, depth(800), depth(1000) },
{ REPEAT_SPARSE_OPTIMAL_P, 1000, 1200 }, { REPEAT_SPARSE_OPTIMAL_P, depth(1000), depth(1200) },
{ REPEAT_SPARSE_OPTIMAL_P, 1500, 1800 }, { REPEAT_SPARSE_OPTIMAL_P, depth(1500), depth(1800) },
{ REPEAT_SPARSE_OPTIMAL_P, 2000, 4000 }, { REPEAT_SPARSE_OPTIMAL_P, depth(2000), depth(4000) },
{ REPEAT_SPARSE_OPTIMAL_P, 2500, 3000 }, { REPEAT_SPARSE_OPTIMAL_P, depth(2500), depth(3000) },
{ REPEAT_SPARSE_OPTIMAL_P, 3000, 3500 }, { REPEAT_SPARSE_OPTIMAL_P, depth(3000), depth(3500) },
{ REPEAT_SPARSE_OPTIMAL_P, 3500, 4000 }, { REPEAT_SPARSE_OPTIMAL_P, depth(3500), depth(4000) },
{ REPEAT_SPARSE_OPTIMAL_P, 4000, 8000 }, { REPEAT_SPARSE_OPTIMAL_P, depth(4000), depth(8000) },
{ REPEAT_SPARSE_OPTIMAL_P, 4500, 8000 }, { REPEAT_SPARSE_OPTIMAL_P, depth(4500), depth(8000) },
{ REPEAT_SPARSE_OPTIMAL_P, 5000, 5001 }, { REPEAT_SPARSE_OPTIMAL_P, depth(5000), depth(5001) },
{ REPEAT_SPARSE_OPTIMAL_P, 60000, 65534 } { REPEAT_SPARSE_OPTIMAL_P, depth(60000), depth(65534) }
}; };
static static