]> git.ipfire.org Git - thirdparty/vectorscan.git/commitdiff
depth: make constructor explicit
authorJustin Viiret <justin.viiret@intel.com>
Thu, 30 Mar 2017 05:33:11 +0000 (16:33 +1100)
committerMatthew Barr <matthew.barr@intel.com>
Wed, 26 Apr 2017 05:19:19 +0000 (15:19 +1000)
17 files changed:
src/nfa/castlecompile.cpp
src/nfagraph/ng_anchored_dots.cpp
src/nfagraph/ng_calc_components.cpp
src/nfagraph/ng_expr_info.cpp
src/nfagraph/ng_prefilter.cpp
src/nfagraph/ng_repeat.cpp
src/nfagraph/ng_som_util.cpp
src/nfagraph/ng_width.cpp
src/rose/rose_build_convert.cpp
src/rose/rose_build_impl.h
src/rose/rose_build_misc.cpp
src/rose/rose_graph.h
src/util/depth.h
unit/internal/depth.cpp
unit/internal/nfagraph_repeat.cpp
unit/internal/nfagraph_width.cpp
unit/internal/repeat.cpp

index a7fe1e903c54537eeef5dde2d94c654f9ff5d150..20239f5683902fa9e16d2afccff36bfa32d35aff 100644 (file)
@@ -501,7 +501,7 @@ buildCastle(const CastleProto &proto,
         // possibly means that we've got a repeat that we can't trigger. We do
         // need to cope with it though.
         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) {
index ed9c7f48606da06c546223ffa3788d1f4c3c1173..9a13376d19354255464ce7c4d1d0c42e20b70713 100644 (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
  * modification, are permitted provided that the following conditions are met:
@@ -208,7 +208,7 @@ void reformAnchoredRepeatsComponent(NGHolder &g,
 
     /* get bounds */
     depth min;
-    depth max = 1;
+    depth max(1);
 
     if (selfLoop) {
         // A self-loop indicates that this is a '.+' or '.*'
@@ -229,9 +229,9 @@ void reformAnchoredRepeatsComponent(NGHolder &g,
             }
         }
 
-        min = 0;
+        min = depth(0);
     } else {
-        min = 1;
+        min = depth(1);
     }
 
     *startBegin = min;
@@ -326,8 +326,8 @@ void reformUnanchoredRepeatsComponent(NGHolder &g,
         }
 
         /* get bounds */
-        depth min = 1;
-        depth max = 1;
+        depth min(1);
+        depth max(1);
 
         if (selfLoop) {
             // 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");
                 return;
             }
-            min = 0;
+            min = depth(0);
         }
 
         *startBegin += min;
@@ -502,7 +502,7 @@ void collapseVariableDotRepeat(NGHolder &g, NFAVertex start,
                  startEnd->str().c_str());
 
     if (start == g.start && startEnd->is_infinite()) {
-        *startEnd = dots.size();
+        *startEnd = depth(dots.size());
     } else if (startEnd->is_finite()) {
         *startEnd += dots.size();
     }
index e06893665c3d485e00da0edcbecb9ecab5d2aa85..54221c7b92afadbea8fb039d98489ab934f596cc 100644 (file)
@@ -372,15 +372,16 @@ deque<unique_ptr<NGHolder>> calcComponents(unique_ptr<NGHolder> g,
     }
 
     bool shell_comp = false;
-    splitIntoComponents(std::move(g), comps, MAX_HEAD_SHELL_DEPTH,
-                        MAX_TAIL_SHELL_DEPTH, &shell_comp);
+    splitIntoComponents(std::move(g), comps, depth(MAX_HEAD_SHELL_DEPTH),
+                        depth(MAX_TAIL_SHELL_DEPTH), &shell_comp);
 
     if (shell_comp) {
         DEBUG_PRINTF("re-running on shell comp\n");
         assert(!comps.empty());
         auto sc = std::move(comps.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());
index 1f601c61afa44ffc907241dca7d438b2a77643c2..9417b6743c87c0c996d0575406ede8e8c4a2bba4 100644 (file)
@@ -84,7 +84,7 @@ void checkVertex(const ReportManager &rm, const NGHolder &g, NFAVertex v,
         return;
     }
     if (is_any_start(v, g)) {
-        info.min = 0;
+        info.min = depth(0);
         info.max = max(info.max, depth(0));
         return;
     }
index 012b4e8d888eb18621ec881d659a3d8355d81f02..3cd9d06d88d82ce54ed5e3cc0be634b0fe38641d 100644 (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
  * modification, are permitted provided that the following conditions are met:
@@ -26,7 +26,8 @@
  * POSSIBILITY OF SUCH DAMAGE.
  */
 
-/** \file
+/**
+ * \file
  * \brief Prefilter Reductions.
  *
  * This file contains routines for reducing the size of an NFA graph that we
@@ -92,13 +93,13 @@ struct RegionInfo {
     u32 id;                             //!< region id
     deque<NFAVertex> vertices;          //!< vertices in the region
     CharReach reach;                    //!< union of region reach
-    depth minWidth = 0;                 //!< min width of region subgraph
-    depth maxWidth = depth::infinity(); //!< max width of region subgraph
+    depth minWidth{0};                  //!< min width of region subgraph
+    depth maxWidth{depth::infinity()};  //!< max width of region subgraph
     bool atBoundary = false;            //!< region is next to an accept
 
     // Bigger score is better.
     size_t score() const {
-        // FIXME: charreach should be a signal?
+        // TODO: charreach should be a signal?
         size_t numVertices = vertices.size();
         if (atBoundary) {
             return numVertices - min(PENALTY_BOUNDARY, numVertices);
index 96e3266f76dc5859e51e4a8bb5869d02606c60da..c51618ea6127d6b7714f0e5ab5ef6b575f2013a2 100644 (file)
@@ -105,8 +105,8 @@ typedef boost::filtered_graph<NGHolder, ReachFilter<NGHolder>> RepeatGraph;
 
 struct ReachSubgraph {
     vector<NFAVertex> vertices;
-    depth repeatMin = 0;
-    depth repeatMax = 0;
+    depth repeatMin{0};
+    depth repeatMax{0};
     u32 minPeriod = 1;
     bool is_reset = false;
     enum RepeatType historyType = REPEAT_RING;
@@ -586,8 +586,8 @@ bool processSubgraph(const NGHolder &g, ReachSubgraph &rsi,
                      range.first, range.second);
         return false;
     }
-    rsi.repeatMin = range.first;
-    rsi.repeatMax = range.second;
+    rsi.repeatMin = depth(range.first);
+    rsi.repeatMax = depth(range.second);
 
     // If we've got a self-loop anywhere, we've got inf max.
     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();
                 break;
             }
-            depth td_t = fixed_depth_tops.at(top);
+            depth td_t(fixed_depth_tops.at(top));
             if (td == td_t) {
                 continue;
             } 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.
         if (repeat.bounds.min == depth(1) &&
             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());
         } else {
             DEBUG_PRINTF("not a supported repeat\n");
index c43373415c18522d2feddd2e858bbc95c003066d..78a39119b9a1d6300e5ed66fab29eec075210cb6 100644 (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
  * 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)) {
             // StartDs and virtual starts always have zero depth.
-            d = DepthMinMax(0, 0);
+            d = DepthMinMax(depth(0), depth(0));
         } else {
             u32 new_idx = g[v_new].index;
             d = temp_depths.at(new_idx);
index d596b7b5d8eb8104030d533771ba691a5bcad44c..c2e9eb1a6ab30752bb927b0522531cfc44bc736c 100644 (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
  * 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) {
         acceptDepth = depth::unreachable();
     } else {
-        acceptDepth = -1 * distance.at(NODE_ACCEPT);
+        acceptDepth = depth(-1 * distance.at(NODE_ACCEPT));
     }
     if (colors.at(NODE_ACCEPT_EOD) == boost::white_color) {
         acceptEodDepth = depth::unreachable();
     } else {
-        acceptEodDepth = -1 * distance.at(NODE_ACCEPT_EOD);
+        acceptEodDepth = depth(-1 * distance.at(NODE_ACCEPT_EOD));
     }
 
     depth d;
index 14eec7c796b682c00bdf4d3f626c2b7b49a69e36..89eac225acf54fe21534f80776631fdafcbe971c 100644 (file)
@@ -551,7 +551,7 @@ bool handleMixedPrefixCliche(const NGHolder &h, RoseGraph &g, RoseVertex v,
                && is_subset_of(exits, base_succ)
                && is_subset_of(base_succ, exits_and_repeat_verts)) {
         /* we have a jump edge */
-        ri.repeatMin = 0;
+        ri.repeatMin = depth(0);
     } else {
         return false;
     }
@@ -802,7 +802,7 @@ void convertAnchPrefixToBounds(RoseBuildImpl &tbi) {
 
         DepthMinMax bounds(pr.bounds); // copy
         if (delay_adj > bounds.min) {
-            bounds.min = 0;
+            bounds.min = depth(0);
         } else {
             bounds.min -= delay_adj;
         }
index b4821b2b380d8fa7abf9195f93de0a38114c87e7..93c0f18c5c02d85bdcc4ce98c1d91038ebc6915f 100644 (file)
@@ -425,8 +425,8 @@ struct OutfixInfo {
 
     RevAccInfo rev_info;
     u32 maxBAWidth = 0; //!< max bi-anchored width
-    depth minWidth = depth::infinity();
-    depth maxWidth = 0;
+    depth minWidth{depth::infinity()};
+    depth maxWidth{0};
     u64a maxOffset = 0;
     bool in_sbmatcher = false; //!< handled by small-block matcher.
 
index c9403896e26b31d40356c2a72a2032fa0a71087d..ef650714abed6aacea01cc3a3956272eff4ab265 100644 (file)
@@ -970,7 +970,7 @@ void RoseSuffixInfo::reset(void) {
     rdfa.reset();
     haig.reset();
     tamarama.reset();
-    dfa_min_width = 0;
+    dfa_min_width = depth(0);
     dfa_max_width = depth::infinity();
 }
 
@@ -1181,7 +1181,7 @@ void LeftEngInfo::reset(void) {
     tamarama.reset();
     lag = 0;
     leftfix_report = MO_INVALID_IDX;
-    dfa_min_width = 0;
+    dfa_min_width = depth(0);
     dfa_max_width = depth::infinity();
 }
 
index c3af749fbe7da1626b0342c69d6e89339140976d..b7e092bbd20971cd20f184b375be8b3faa4248f7 100644 (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
  * modification, are permitted provided that the following conditions are met:
@@ -85,7 +85,7 @@ struct LeftEngInfo {
     std::shared_ptr<TamaProto> tamarama;
     u32 lag = 0U;
     ReportID leftfix_report = MO_INVALID_IDX;
-    depth dfa_min_width = 0;
+    depth dfa_min_width{0};
     depth dfa_max_width = depth::infinity();
 
     bool operator==(const LeftEngInfo &other) const {
@@ -125,7 +125,7 @@ struct RoseSuffixInfo {
     std::shared_ptr<raw_som_dfa> haig;
     std::shared_ptr<raw_dfa> rdfa;
     std::shared_ptr<TamaProto> tamarama;
-    depth dfa_min_width = 0;
+    depth dfa_min_width{0};
     depth dfa_max_width = depth::infinity();
 
     bool operator==(const RoseSuffixInfo &b) const;
index 977fd0c30205e217e3a6bcb00d2765c264311560..b1fe2b1bf17f59dcc65371cbc76a8e367661aa0a 100644 (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
  * modification, are permitted provided that the following conditions are met:
@@ -54,9 +54,10 @@ struct DepthOverflowError {};
  */
 class depth {
 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()) {
             DEBUG_PRINTF("depth %u too large to represent!\n", v);
             throw DepthOverflowError();
@@ -196,6 +197,29 @@ public:
         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
     /** \brief Render as a string, useful for debugging. */
     std::string str() const;
@@ -209,7 +233,7 @@ private:
     static constexpr u32 val_infinity = (1u << 31) - 1;
     static constexpr u32 val_unreachable = 1u << 31;
 
-    u32 val;
+    u32 val = val_unreachable;
 };
 
 /**
index a004643b5d7d77d01ea72bf47d78df92436ed95f..ad9ffe38806daedb57a718f8e53abff8fed6940f 100644 (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
  * 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});
 
     // overflow must throw
+    depth max_depth(depth::max_value());
     depth d;
-    ASSERT_THROW(d = depth::max_value() + depth(1), DepthOverflowError);
-    ASSERT_THROW(d = depth::max_value() + 1, DepthOverflowError);
+    ASSERT_THROW(d = max_depth + depth(1), DepthOverflowError);
+    ASSERT_THROW(d = max_depth + 1, DepthOverflowError);
 
     // underflow must throw
     ASSERT_THROW(d = depth(0) + s32{-1}, DepthOverflowError);
@@ -267,11 +268,11 @@ TEST(depth, unordered_set) {
     ue2::unordered_set<depth> depths;
 
     for (const auto &val : finite_values) {
-        depths.insert(val);
+        depths.emplace(val);
     }
 
     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());
index b34d12717fc83c0d57839a2ed54a78fd3847f36e..941873ecec9221f5a9507d2b83855906f742ad63 100644 (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
  * modification, are permitted provided that the following conditions are met:
@@ -66,28 +66,28 @@ struct PureRepeatTest {
 class NFAPureRepeatTest : public TestWithParam<PureRepeatTest> { };
 
 static const PureRepeatTest pureRepeatTests[] = {
-    { "^.*", 0, depth::infinity() },
-    { "^.+", 1, depth::infinity() },
-    { "^.", 1, 1 },
-    { "^..", 2, 2 },
-    { "^.?.", 1, 2 },
-    { "^.{1,2}", 1, 2 },
-    { "^.{1,3}", 1, 3 },
-    { "^.{1,10}", 1, 10 },
-    { "^.{1,200}", 1, 200 },
-    { "^.{200}", 200, 200 },
-    { "^.{0,}", 0, depth::infinity() },
-    { "^.{1,}", 1, depth::infinity() },
-    { "^.{2,}", 2, depth::infinity() },
-    { "^.{10,}", 10, depth::infinity() },
-    { "^.{200,}", 200, depth::infinity() },
-    { "^.{5000,}", 5000, depth::infinity() },
-    { "^.{0,1}", 0, 1 },
-    { "^.{0,2}", 0, 2 },
-    { "^.{0,100}", 0, 100 },
-    { "^.{0,5000}", 0, 5000 },
-    { "^x{10}x{20,30}", 30, 40 },
-    { "^..?..?..?..?..?", 5, 10 }
+    { "^.*", depth(0), depth::infinity() },
+    { "^.+", depth(1), depth::infinity() },
+    { "^.", depth(1), depth(1) },
+    { "^..", depth(2), depth(2) },
+    { "^.?.", depth(1), depth(2) },
+    { "^.{1,2}", depth(1), depth(2) },
+    { "^.{1,3}", depth(1), depth(3) },
+    { "^.{1,10}", depth(1), depth(10) },
+    { "^.{1,200}", depth(1), depth(200) },
+    { "^.{200}", depth(200), depth(200) },
+    { "^.{0,}", depth(0), depth::infinity() },
+    { "^.{1,}", depth(1), depth::infinity() },
+    { "^.{2,}", depth(2), depth::infinity() },
+    { "^.{10,}", depth(10), depth::infinity() },
+    { "^.{200,}", depth(200), depth::infinity() },
+    { "^.{5000,}", depth(5000), depth::infinity() },
+    { "^.{0,1}", depth(0), depth(1) },
+    { "^.{0,2}", depth(0), depth(2) },
+    { "^.{0,100}", depth(0), depth(100) },
+    { "^.{0,5000}", depth(0), depth(5000) },
+    { "^x{10}x{20,30}", depth(30), depth(40) },
+    { "^..?..?..?..?..?", depth(5), depth(10) }
 };
 
 INSTANTIATE_TEST_CASE_P(PureRepeat, NFAPureRepeatTest,
index 5cfb4c87b95557f113187bf68b5321814a8c5bb0..7ccdca37fccd5ebde42b3444389212a1a34a64fb 100644 (file)
@@ -52,26 +52,26 @@ struct WidthTest {
 class NFAWidthTest : public TestWithParam<WidthTest> { };
 
 static const WidthTest widthTests[] = {
-    { "()", 0, 0 },
-    { "a", 1, 1 },
-    { "a?b", 1, 2 },
-    { "foobar", 6, 6 },
-    { "foo(bar)?", 3, 6 },
-    { "(a|ab|abc|abcd)", 1, 4 },
-    { "foo.*bar", 6, depth::infinity() },
-    { "foo(bar)*", 3, depth::infinity() },
-    { "foo(bar)+", 6, depth::infinity() },
-    { "foo(bar){1,3}", 6, 12 },
-    { "(abcd)+", 4, depth::infinity() },
-    { "foo\\z", 3, 3 },
-    { "^foo", 3, 3 },
-    { "^foo|bar.*baz", 3, depth::infinity() },
-    { "^foobar.*|baz", 3, depth::infinity() },
-    { "foo(\\z|bar)", 3, 6 },
-    { "foo(|bar\\z)", 3, 6 },
-    { "foo.{0,15}bar", 6, 21 },
-    { "foo.{0,15}.*bar", 6, depth::infinity() },
-    { "(?smi)^(aa[^a]aa$|a|a+\\Z|a)", 1, depth::infinity() }
+    { "()", depth(0), depth(0) },
+    { "a", depth(1), depth(1) },
+    { "a?b", depth(1), depth(2) },
+    { "foobar", depth(6), depth(6) },
+    { "foo(bar)?", depth(3), depth(6) },
+    { "(a|ab|abc|abcd)", depth(1), depth(4) },
+    { "foo.*bar", depth(6), depth::infinity() },
+    { "foo(bar)*", depth(3), depth::infinity() },
+    { "foo(bar)+", depth(6), depth::infinity() },
+    { "foo(bar){1,3}", depth(6), depth(12) },
+    { "(abcd)+", depth(4), depth::infinity() },
+    { "foo\\z", depth(3), depth(3) },
+    { "^foo", depth(3), depth(3) },
+    { "^foo|bar.*baz", depth(3), depth::infinity() },
+    { "^foobar.*|baz", depth(3), depth::infinity() },
+    { "foo(\\z|bar)", depth(3), depth(6) },
+    { "foo(|bar\\z)", depth(3), depth(6) },
+    { "foo.{0,15}bar", depth(6), depth(21) },
+    { "foo.{0,15}.*bar", depth(6), depth::infinity() },
+    { "(?smi)^(aa[^a]aa$|a|a+\\Z|a)", depth(1), depth::infinity() }
 };
 
 INSTANTIATE_TEST_CASE_P(NFAWidth, NFAWidthTest, ValuesIn(widthTests));
index 7f245e62f030ef082828171d5e7da1d46e075835..546d7d4f882589ff9ea2f5f363797d413ba030aa 100644 (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
  * modification, are permitted provided that the following conditions are met:
@@ -106,96 +106,96 @@ private:
 
 static const RepeatTestInfo repeatTests[] = {
     // Fixed repeats -- ring model
-    { REPEAT_RING, 2, 2 },
-    { REPEAT_RING, 4, 4 },
-    { REPEAT_RING, 10, 10 },
-    { REPEAT_RING, 16, 16 },
-    { REPEAT_RING, 20, 20 },
-    { REPEAT_RING, 30, 30 },
-    { REPEAT_RING, 50, 50 },
-    { REPEAT_RING, 64, 64 },
-    { REPEAT_RING, 65, 65 },
-    { REPEAT_RING, 100, 100 },
-    { REPEAT_RING, 200, 200 },
-    { REPEAT_RING, 1000, 1000 },
-    { REPEAT_RING, 4100, 4100 },
-    { REPEAT_RING, 16000, 16000 },
+    { REPEAT_RING, depth(2), depth(2) },
+    { REPEAT_RING, depth(4), depth(4) },
+    { REPEAT_RING, depth(10), depth(10) },
+    { REPEAT_RING, depth(16), depth(16) },
+    { REPEAT_RING, depth(20), depth(20) },
+    { REPEAT_RING, depth(30), depth(30) },
+    { REPEAT_RING, depth(50), depth(50) },
+    { REPEAT_RING, depth(64), depth(64) },
+    { REPEAT_RING, depth(65), depth(65) },
+    { REPEAT_RING, depth(100), depth(100) },
+    { REPEAT_RING, depth(200), depth(200) },
+    { REPEAT_RING, depth(1000), depth(1000) },
+    { REPEAT_RING, depth(4100), depth(4100) },
+    { REPEAT_RING, depth(16000), depth(16000) },
     // {0, N} repeats -- last model
-    { REPEAT_LAST, 0, 4 },
-    { REPEAT_LAST, 0, 10 },
-    { REPEAT_LAST, 0, 20 },
-    { REPEAT_LAST, 0, 30 },
-    { REPEAT_LAST, 0, 50 },
-    { REPEAT_LAST, 0, 100 },
-    { REPEAT_LAST, 0, 200 },
-    { REPEAT_LAST, 0, 1000 },
-    { REPEAT_LAST, 0, 16000 },
+    { REPEAT_LAST, depth(0), depth(4) },
+    { REPEAT_LAST, depth(0), depth(10) },
+    { REPEAT_LAST, depth(0), depth(20) },
+    { REPEAT_LAST, depth(0), depth(30) },
+    { REPEAT_LAST, depth(0), depth(50) },
+    { REPEAT_LAST, depth(0), depth(100) },
+    { REPEAT_LAST, depth(0), depth(200) },
+    { REPEAT_LAST, depth(0), depth(1000) },
+    { REPEAT_LAST, depth(0), depth(16000) },
     // {0, N} repeats -- ring model (though we use 'last' model in practice)
-    { REPEAT_RING, 0, 2 },
-    { REPEAT_RING, 0, 4 },
-    { REPEAT_RING, 0, 10 },
-    { REPEAT_RING, 0, 20 },
-    { REPEAT_RING, 0, 30 },
-    { REPEAT_RING, 0, 50 },
-    { REPEAT_RING, 0, 64 },
-    { REPEAT_RING, 0, 65 },
-    { REPEAT_RING, 0, 100 },
-    { REPEAT_RING, 0, 200 },
-    { REPEAT_RING, 0, 1000 },
-    { REPEAT_RING, 0, 16000 },
+    { REPEAT_RING, depth(0), depth(2) },
+    { REPEAT_RING, depth(0), depth(4) },
+    { REPEAT_RING, depth(0), depth(10) },
+    { REPEAT_RING, depth(0), depth(20) },
+    { REPEAT_RING, depth(0), depth(30) },
+    { REPEAT_RING, depth(0), depth(50) },
+    { REPEAT_RING, depth(0), depth(64) },
+    { REPEAT_RING, depth(0), depth(65) },
+    { REPEAT_RING, depth(0), depth(100) },
+    { REPEAT_RING, depth(0), depth(200) },
+    { REPEAT_RING, depth(0), depth(1000) },
+    { REPEAT_RING, depth(0), depth(16000) },
     // {N, M} repeats -- ring model
-    { REPEAT_RING, 2, 3 },
-    { REPEAT_RING, 1, 4 },
-    { REPEAT_RING, 5, 10 },
-    { REPEAT_RING, 10, 20 },
-    { REPEAT_RING, 10, 50 },
-    { REPEAT_RING, 50, 60 },
-    { REPEAT_RING, 100, 200 },
-    { REPEAT_RING, 1, 200 },
-    { REPEAT_RING, 10, 16000 },
-    { REPEAT_RING, 10000, 16000 },
+    { REPEAT_RING, depth(2), depth(3) },
+    { REPEAT_RING, depth(1), depth(4) },
+    { REPEAT_RING, depth(5), depth(10) },
+    { REPEAT_RING, depth(10), depth(20) },
+    { REPEAT_RING, depth(10), depth(50) },
+    { REPEAT_RING, depth(50), depth(60) },
+    { REPEAT_RING, depth(100), depth(200) },
+    { REPEAT_RING, depth(1), depth(200) },
+    { REPEAT_RING, depth(10), depth(16000) },
+    { REPEAT_RING, depth(10000), depth(16000) },
     // {N, M} repeats -- range model
-    { REPEAT_RANGE, 1, 4 },
-    { REPEAT_RANGE, 5, 10 },
-    { REPEAT_RANGE, 10, 20 },
-    { REPEAT_RANGE, 10, 50 },
-    { REPEAT_RANGE, 50, 60 },
-    { REPEAT_RANGE, 100, 200 },
-    { REPEAT_RANGE, 1, 200 },
-    { REPEAT_RANGE, 10, 16000 },
-    { REPEAT_RANGE, 10000, 16000 },
+    { REPEAT_RANGE, depth(1), depth(4) },
+    { REPEAT_RANGE, depth(5), depth(10) },
+    { REPEAT_RANGE, depth(10), depth(20) },
+    { REPEAT_RANGE, depth(10), depth(50) },
+    { REPEAT_RANGE, depth(50), depth(60) },
+    { REPEAT_RANGE, depth(100), depth(200) },
+    { REPEAT_RANGE, depth(1), depth(200) },
+    { REPEAT_RANGE, depth(10), depth(16000) },
+    { REPEAT_RANGE, depth(10000), depth(16000) },
     // {N,M} repeats -- small bitmap model
-    { REPEAT_BITMAP, 1, 2 },
-    { REPEAT_BITMAP, 5, 10 },
-    { REPEAT_BITMAP, 10, 20 },
-    { REPEAT_BITMAP, 20, 40 },
-    { REPEAT_BITMAP, 1, 63 },
-    { REPEAT_BITMAP, 50, 63 },
+    { REPEAT_BITMAP, depth(1), depth(2) },
+    { REPEAT_BITMAP, depth(5), depth(10) },
+    { REPEAT_BITMAP, depth(10), depth(20) },
+    { REPEAT_BITMAP, depth(20), depth(40) },
+    { REPEAT_BITMAP, depth(1), depth(63) },
+    { REPEAT_BITMAP, depth(50), depth(63) },
     // {N,M} repeats -- trailer model
-    { REPEAT_TRAILER, 1, 2 },
-    { REPEAT_TRAILER, 8, 8 },
-    { REPEAT_TRAILER, 0, 8 },
-    { REPEAT_TRAILER, 10, 20 },
-    { REPEAT_TRAILER, 1, 32 },
-    { REPEAT_TRAILER, 64, 64 },
-    { REPEAT_TRAILER, 1, 64 },
-    { REPEAT_TRAILER, 1, 100 },
-    { REPEAT_TRAILER, 1, 2000 },
-    { REPEAT_TRAILER, 50, 200 },
-    { REPEAT_TRAILER, 50, 1000 },
-    { REPEAT_TRAILER, 64, 1024 },
+    { REPEAT_TRAILER, depth(1), depth(2) },
+    { REPEAT_TRAILER, depth(8), depth(8) },
+    { REPEAT_TRAILER, depth(0), depth(8) },
+    { REPEAT_TRAILER, depth(10), depth(20) },
+    { REPEAT_TRAILER, depth(1), depth(32) },
+    { REPEAT_TRAILER, depth(64), depth(64) },
+    { REPEAT_TRAILER, depth(1), depth(64) },
+    { REPEAT_TRAILER, depth(1), depth(100) },
+    { REPEAT_TRAILER, depth(1), depth(2000) },
+    { REPEAT_TRAILER, depth(50), depth(200) },
+    { REPEAT_TRAILER, depth(50), depth(1000) },
+    { REPEAT_TRAILER, depth(64), depth(1024) },
     // {N,} repeats -- first model
-    { REPEAT_FIRST, 0, depth::infinity() },
-    { REPEAT_FIRST, 1, depth::infinity() },
-    { REPEAT_FIRST, 4, depth::infinity() },
-    { REPEAT_FIRST, 10, depth::infinity() },
-    { REPEAT_FIRST, 50, depth::infinity() },
-    { REPEAT_FIRST, 100, depth::infinity() },
-    { REPEAT_FIRST, 1000, depth::infinity() },
-    { REPEAT_FIRST, 3000, depth::infinity() },
-    { REPEAT_FIRST, 10000, depth::infinity() },
+    { REPEAT_FIRST, depth(0), depth::infinity() },
+    { REPEAT_FIRST, depth(1), depth::infinity() },
+    { REPEAT_FIRST, depth(4), depth::infinity() },
+    { REPEAT_FIRST, depth(10), depth::infinity() },
+    { REPEAT_FIRST, depth(50), depth::infinity() },
+    { REPEAT_FIRST, depth(100), depth::infinity() },
+    { REPEAT_FIRST, depth(1000), depth::infinity() },
+    { REPEAT_FIRST, depth(3000), depth::infinity() },
+    { REPEAT_FIRST, depth(10000), depth::infinity() },
     // {,} repeats -- always
-    { REPEAT_ALWAYS, 0, depth::infinity() },
+    { REPEAT_ALWAYS, depth(0), depth::infinity() },
 };
 
 INSTANTIATE_TEST_CASE_P(Repeat, RepeatTest, ValuesIn(repeatTests));
@@ -508,55 +508,55 @@ const u32 sparsePeriods[] = {
 static
 const RepeatTestInfo sparseRepeats[] = {
     // Fixed repeats
-    { REPEAT_SPARSE_OPTIMAL_P, 10, 10 },
-    { REPEAT_SPARSE_OPTIMAL_P, 20, 20 },
-    { REPEAT_SPARSE_OPTIMAL_P, 40, 40 },
-    { REPEAT_SPARSE_OPTIMAL_P, 80, 80 },
-    { REPEAT_SPARSE_OPTIMAL_P, 100, 100 },
-    { REPEAT_SPARSE_OPTIMAL_P, 150, 150 },
-    { REPEAT_SPARSE_OPTIMAL_P, 200, 200 },
-    { REPEAT_SPARSE_OPTIMAL_P, 250, 250 },
-    { REPEAT_SPARSE_OPTIMAL_P, 300, 300 },
-    { REPEAT_SPARSE_OPTIMAL_P, 350, 350 },
-    { REPEAT_SPARSE_OPTIMAL_P, 400, 400 },
-    { REPEAT_SPARSE_OPTIMAL_P, 500, 500 },
-    { REPEAT_SPARSE_OPTIMAL_P, 600, 600 },
-    { REPEAT_SPARSE_OPTIMAL_P, 800, 800 },
-    { REPEAT_SPARSE_OPTIMAL_P, 1000, 1000 },
-    { REPEAT_SPARSE_OPTIMAL_P, 1500, 1500 },
-    { REPEAT_SPARSE_OPTIMAL_P, 2000, 2000 },
-    { REPEAT_SPARSE_OPTIMAL_P, 2500, 2500 },
-    { REPEAT_SPARSE_OPTIMAL_P, 3000, 3000 },
-    { REPEAT_SPARSE_OPTIMAL_P, 3500, 3500 },
-    { REPEAT_SPARSE_OPTIMAL_P, 4000, 4000 },
-    { REPEAT_SPARSE_OPTIMAL_P, 4500, 4500 },
-    { REPEAT_SPARSE_OPTIMAL_P, 5000, 5000 },
-    { REPEAT_SPARSE_OPTIMAL_P, 65534, 65534 },
+    { REPEAT_SPARSE_OPTIMAL_P, depth(10), depth(10) },
+    { REPEAT_SPARSE_OPTIMAL_P, depth(20), depth(20) },
+    { REPEAT_SPARSE_OPTIMAL_P, depth(40), depth(40) },
+    { REPEAT_SPARSE_OPTIMAL_P, depth(80), depth(80) },
+    { REPEAT_SPARSE_OPTIMAL_P, depth(100), depth(100) },
+    { REPEAT_SPARSE_OPTIMAL_P, depth(150), depth(150) },
+    { REPEAT_SPARSE_OPTIMAL_P, depth(200), depth(200) },
+    { REPEAT_SPARSE_OPTIMAL_P, depth(250), depth(250) },
+    { REPEAT_SPARSE_OPTIMAL_P, depth(300), depth(300) },
+    { REPEAT_SPARSE_OPTIMAL_P, depth(350), depth(350) },
+    { REPEAT_SPARSE_OPTIMAL_P, depth(400), depth(400) },
+    { REPEAT_SPARSE_OPTIMAL_P, depth(500), depth(500) },
+    { REPEAT_SPARSE_OPTIMAL_P, depth(600), depth(600) },
+    { REPEAT_SPARSE_OPTIMAL_P, depth(800), depth(800) },
+    { REPEAT_SPARSE_OPTIMAL_P, depth(1000), depth(1000) },
+    { REPEAT_SPARSE_OPTIMAL_P, depth(1500), depth(1500) },
+    { REPEAT_SPARSE_OPTIMAL_P, depth(2000), depth(2000) },
+    { REPEAT_SPARSE_OPTIMAL_P, depth(2500), depth(2500) },
+    { REPEAT_SPARSE_OPTIMAL_P, depth(3000), depth(3000) },
+    { REPEAT_SPARSE_OPTIMAL_P, depth(3500), depth(3500) },
+    { REPEAT_SPARSE_OPTIMAL_P, depth(4000), depth(4000) },
+    { REPEAT_SPARSE_OPTIMAL_P, depth(4500), depth(4500) },
+    { REPEAT_SPARSE_OPTIMAL_P, depth(5000), depth(5000) },
+    { REPEAT_SPARSE_OPTIMAL_P, depth(65534), depth(65534) },
     // {N, M} repeats
-    { REPEAT_SPARSE_OPTIMAL_P, 10, 20 },
-    { REPEAT_SPARSE_OPTIMAL_P, 20, 40 },
-    { REPEAT_SPARSE_OPTIMAL_P, 40, 80 },
-    { REPEAT_SPARSE_OPTIMAL_P, 80, 100 },
-    { REPEAT_SPARSE_OPTIMAL_P, 100, 120 },
-    { REPEAT_SPARSE_OPTIMAL_P, 150, 180 },
-    { REPEAT_SPARSE_OPTIMAL_P, 200, 400 },
-    { REPEAT_SPARSE_OPTIMAL_P, 250, 500 },
-    { REPEAT_SPARSE_OPTIMAL_P, 300, 400 },
-    { REPEAT_SPARSE_OPTIMAL_P, 350, 500 },
-    { REPEAT_SPARSE_OPTIMAL_P, 400, 500 },
-    { REPEAT_SPARSE_OPTIMAL_P, 500, 600 },
-    { REPEAT_SPARSE_OPTIMAL_P, 600, 700 },
-    { REPEAT_SPARSE_OPTIMAL_P, 800, 1000 },
-    { REPEAT_SPARSE_OPTIMAL_P, 1000, 1200 },
-    { REPEAT_SPARSE_OPTIMAL_P, 1500, 1800 },
-    { REPEAT_SPARSE_OPTIMAL_P, 2000, 4000 },
-    { REPEAT_SPARSE_OPTIMAL_P, 2500, 3000 },
-    { REPEAT_SPARSE_OPTIMAL_P, 3000, 3500 },
-    { REPEAT_SPARSE_OPTIMAL_P, 3500, 4000 },
-    { REPEAT_SPARSE_OPTIMAL_P, 4000, 8000 },
-    { REPEAT_SPARSE_OPTIMAL_P, 4500, 8000 },
-    { REPEAT_SPARSE_OPTIMAL_P, 5000, 5001 },
-    { REPEAT_SPARSE_OPTIMAL_P, 60000, 65534 }
+    { REPEAT_SPARSE_OPTIMAL_P, depth(10), depth(20) },
+    { REPEAT_SPARSE_OPTIMAL_P, depth(20), depth(40) },
+    { REPEAT_SPARSE_OPTIMAL_P, depth(40), depth(80) },
+    { REPEAT_SPARSE_OPTIMAL_P, depth(80), depth(100) },
+    { REPEAT_SPARSE_OPTIMAL_P, depth(100), depth(120) },
+    { REPEAT_SPARSE_OPTIMAL_P, depth(150), depth(180) },
+    { REPEAT_SPARSE_OPTIMAL_P, depth(200), depth(400) },
+    { REPEAT_SPARSE_OPTIMAL_P, depth(250), depth(500) },
+    { REPEAT_SPARSE_OPTIMAL_P, depth(300), depth(400) },
+    { REPEAT_SPARSE_OPTIMAL_P, depth(350), depth(500) },
+    { REPEAT_SPARSE_OPTIMAL_P, depth(400), depth(500) },
+    { REPEAT_SPARSE_OPTIMAL_P, depth(500), depth(600) },
+    { REPEAT_SPARSE_OPTIMAL_P, depth(600), depth(700) },
+    { REPEAT_SPARSE_OPTIMAL_P, depth(800), depth(1000) },
+    { REPEAT_SPARSE_OPTIMAL_P, depth(1000), depth(1200) },
+    { REPEAT_SPARSE_OPTIMAL_P, depth(1500), depth(1800) },
+    { REPEAT_SPARSE_OPTIMAL_P, depth(2000), depth(4000) },
+    { REPEAT_SPARSE_OPTIMAL_P, depth(2500), depth(3000) },
+    { REPEAT_SPARSE_OPTIMAL_P, depth(3000), depth(3500) },
+    { REPEAT_SPARSE_OPTIMAL_P, depth(3500), depth(4000) },
+    { REPEAT_SPARSE_OPTIMAL_P, depth(4000), depth(8000) },
+    { REPEAT_SPARSE_OPTIMAL_P, depth(4500), depth(8000) },
+    { REPEAT_SPARSE_OPTIMAL_P, depth(5000), depth(5001) },
+    { REPEAT_SPARSE_OPTIMAL_P, depth(60000), depth(65534) }
 };
 
 static