Fix bug in Intervals<T>::update()

When the interval being updated went all the way to the end of the last
interval (UINT64_MAX), `update` would call `mergeLeft` on the `end()` interval.
This would cause `mergeLeft` to dereference an invalid iterator.

Also added a quick return for updating empty intervals, and unit tests to verify
correct handling of empty intervals, which were run both with and without this
optimization.

Also removed some unnecessary asserts that likely called many times. These
asserts could only fail if there was a bug in the `Intervals<T>` implementation,
which should be caught by the unit tests.
This commit is contained in:
Benson Joeris
2019-02-19 10:35:47 -05:00
committed by Baldur Karlsson
parent a7b21ae2d2
commit cb26815570
2 changed files with 34 additions and 10 deletions
+29
View File
@@ -265,6 +265,35 @@ TEST_CASE("Test Intervals type", "[intervals]")
test.update(0, UINT64_MAX, 1, [](uint64_t x, uint64_t y) -> uint64_t { return x + y; });
check_intervals(test, {{0, 1, 5}, {5, 2, 10}, {10, 1, UINT64_MAX}});
};
SECTION("update an empty interval in the interior of an interval")
{
Intervals<uint64_t> test = make_intervals({{0, 0, 5}, {5, 1, 10}, {10, 0, UINT64_MAX}});
test.update(2, 2, 1, [](uint64_t x, uint64_t y) -> uint64_t { return x + y; });
check_intervals(test, {{0, 0, 5}, {5, 1, 10}, {10, 0, UINT64_MAX}});
};
SECTION("update an empty interval on a boundary")
{
Intervals<uint64_t> test = make_intervals({{0, 0, 5}, {5, 1, 10}, {10, 0, UINT64_MAX}});
test.update(5, 5, 1, [](uint64_t x, uint64_t y) -> uint64_t { return x + y; });
check_intervals(test, {{0, 0, 5}, {5, 1, 10}, {10, 0, UINT64_MAX}});
};
SECTION("update an empty interval at 0")
{
Intervals<uint64_t> test = make_intervals({{0, 0, 5}, {5, 1, 10}, {10, 0, UINT64_MAX}});
test.update(0, 0, 1, [](uint64_t x, uint64_t y) -> uint64_t { return x + y; });
check_intervals(test, {{0, 0, 5}, {5, 1, 10}, {10, 0, UINT64_MAX}});
};
SECTION("update an empty interval at UINT64_MAX")
{
Intervals<uint64_t> test = make_intervals({{0, 0, 5}, {5, 1, 10}, {10, 0, UINT64_MAX}});
test.update(UINT64_MAX, UINT64_MAX, 1,
[](uint64_t x, uint64_t y) -> uint64_t { return x + y; });
check_intervals(test, {{0, 0, 5}, {5, 1, 10}, {10, 0, UINT64_MAX}});
};
};
SECTION("mergeIntervals tests")