[run_set] improve run merging

This commit is contained in:
Joe Thornber
2013-07-09 10:36:30 +01:00
parent 31686fbb17
commit 8523314a7f
2 changed files with 39 additions and 2 deletions

View File

@ -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;
} }

View File

@ -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;