[run_set] improve run merging
This commit is contained in:
@ -12,6 +12,10 @@ namespace base {
|
|||||||
template <typename T>
|
template <typename T>
|
||||||
class run_set {
|
class run_set {
|
||||||
public:
|
public:
|
||||||
|
void clear() {
|
||||||
|
runs_.clear();
|
||||||
|
}
|
||||||
|
|
||||||
void add(T const &b) {
|
void add(T const &b) {
|
||||||
add(run<T>(b, b + 1));
|
add(run<T>(b, b + 1));
|
||||||
}
|
}
|
||||||
@ -28,14 +32,14 @@ namespace base {
|
|||||||
const_iterator it = runs_.cbegin();
|
const_iterator it = runs_.cbegin();
|
||||||
|
|
||||||
// Skip all blocks that end before r
|
// Skip all blocks that end before r
|
||||||
while (it != runs_.end() && it->end_ <= r.begin_)
|
while (it != runs_.end() && it->end_ < r.begin_)
|
||||||
++it;
|
++it;
|
||||||
|
|
||||||
// work out which runs overlap
|
// work out which runs overlap
|
||||||
if (it != runs_.end()) {
|
if (it != runs_.end()) {
|
||||||
r.begin_ = min_maybe(it->begin_, r.begin_);
|
r.begin_ = min_maybe(it->begin_, r.begin_);
|
||||||
const_iterator first = it;
|
const_iterator first = it;
|
||||||
while (it != runs_.end() && it->begin_ < r.end_) {
|
while (it != runs_.end() && it->begin_ <= r.end_) {
|
||||||
r.end_ = max_maybe(it->end_, r.end_);
|
r.end_ = max_maybe(it->end_, r.end_);
|
||||||
++it;
|
++it;
|
||||||
}
|
}
|
||||||
|
@ -48,6 +48,39 @@ TEST_F(RunSetTests, add_single_blocks)
|
|||||||
rs.add(9u);
|
rs.add(9u);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_F(RunSetTests, add_adjacent_single)
|
||||||
|
{
|
||||||
|
run_set<unsigned> rs;
|
||||||
|
|
||||||
|
rs.add(3);
|
||||||
|
rs.add(4);
|
||||||
|
|
||||||
|
ASSERT_THAT(*rs.begin(), EqRun(3, 5));
|
||||||
|
ASSERT_THAT(++rs.begin(), Eq(rs.end()));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(RunSetTests, add_adjacent_single_other_way_round)
|
||||||
|
{
|
||||||
|
run_set<unsigned> rs;
|
||||||
|
|
||||||
|
rs.add(4);
|
||||||
|
rs.add(3);
|
||||||
|
|
||||||
|
ASSERT_THAT(*rs.begin(), EqRun(3, 5));
|
||||||
|
ASSERT_THAT(++rs.begin(), Eq(rs.end()));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(RunSetTests, many_single_blocks)
|
||||||
|
{
|
||||||
|
run_set<unsigned> rs;
|
||||||
|
|
||||||
|
for (unsigned i = 1; i < 100000; i++)
|
||||||
|
rs.add(i);
|
||||||
|
|
||||||
|
ASSERT_THAT(*rs.begin(), EqRun(1, 100000));
|
||||||
|
ASSERT_THAT(++rs.begin(), Eq(rs.end()));
|
||||||
|
}
|
||||||
|
|
||||||
TEST_F(RunSetTests, add_runs)
|
TEST_F(RunSetTests, add_runs)
|
||||||
{
|
{
|
||||||
run_set<unsigned> rs;
|
run_set<unsigned> rs;
|
||||||
|
Reference in New Issue
Block a user