[subtracting_span_iterator] recode using run_set
This commit is contained in:
@ -71,7 +71,7 @@ namespace {
|
|||||||
}
|
}
|
||||||
|
|
||||||
virtual maybe_block find_free(span_iterator &it) {
|
virtual maybe_block find_free(span_iterator &it) {
|
||||||
subtracting_span_iterator filtered_it(it, freed_blocks_);
|
subtracting_span_iterator filtered_it(get_nr_blocks(), it, freed_blocks_);
|
||||||
return sm_->find_free(filtered_it);
|
return sm_->find_free(filtered_it);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -109,11 +109,11 @@ namespace {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void mark_freed(block_address b) {
|
void mark_freed(block_address b) {
|
||||||
freed_blocks_.insert(b);
|
freed_blocks_.add(b, b + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool was_freed(block_address b) const {
|
bool was_freed(block_address b) const {
|
||||||
return freed_blocks_.count(b) > 0;
|
return freed_blocks_.member(b) > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
checked_space_map::ptr sm_;
|
checked_space_map::ptr sm_;
|
||||||
|
@ -129,7 +129,7 @@ namespace {
|
|||||||
find_free(span_iterator &it) {
|
find_free(span_iterator &it) {
|
||||||
recursing_lock lock(*this);
|
recursing_lock lock(*this);
|
||||||
|
|
||||||
subtracting_span_iterator filtered_it(it, allocated_blocks_);
|
subtracting_span_iterator filtered_it(get_nr_blocks(), it, allocated_blocks_);
|
||||||
return sm_->find_free(filtered_it);
|
return sm_->find_free(filtered_it);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -240,7 +240,7 @@ namespace {
|
|||||||
ops_[op.b_].push_back(op);
|
ops_[op.b_].push_back(op);
|
||||||
|
|
||||||
if (op.op_ == block_op::INC || (op.op_ == block_op::SET && op.rc_ > 0))
|
if (op.op_ == block_op::INC || (op.op_ == block_op::SET && op.rc_ > 0))
|
||||||
allocated_blocks_.insert(op.b_);
|
allocated_blocks_.add(op.b_, op.b_ + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void cant_recurse(string const &method) const {
|
void cant_recurse(string const &method) const {
|
||||||
|
@ -2,98 +2,60 @@
|
|||||||
#define SPAN_ITERATOR_H
|
#define SPAN_ITERATOR_H
|
||||||
|
|
||||||
#include "persistent-data/space_map.h"
|
#include "persistent-data/space_map.h"
|
||||||
|
#include "persistent-data/run_set.h"
|
||||||
|
|
||||||
#include <set>
|
#include <set>
|
||||||
|
|
||||||
//----------------------------------------------------------------
|
//----------------------------------------------------------------
|
||||||
|
|
||||||
namespace persistent_data {
|
namespace persistent_data {
|
||||||
// FIXME: rewrite with tests using the run_list stuff.
|
|
||||||
class subtracting_span_iterator : public space_map::span_iterator {
|
class subtracting_span_iterator : public space_map::span_iterator {
|
||||||
public:
|
public:
|
||||||
typedef set<block_address> block_set;
|
typedef typename base::run_set<block_address> block_set;
|
||||||
typedef space_map::span span;
|
typedef space_map::span span;
|
||||||
|
|
||||||
subtracting_span_iterator(span_iterator &sub_it,
|
subtracting_span_iterator(block_address max,
|
||||||
|
span_iterator &sub_it,
|
||||||
block_set const &forbidden_blocks)
|
block_set const &forbidden_blocks)
|
||||||
: sub_it_(sub_it),
|
: max_(max) {
|
||||||
forbidden_blocks_(forbidden_blocks),
|
for (maybe_span ms = sub_it.first(); ms; ms = sub_it.next())
|
||||||
current_begin_() {
|
runs_.add(ms->first, ms->second);
|
||||||
|
|
||||||
|
block_set bs(forbidden_blocks);
|
||||||
|
runs_.negate();
|
||||||
|
runs_.merge(bs);
|
||||||
|
runs_.negate();
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual maybe_span first() {
|
virtual maybe_span first() {
|
||||||
current_span_ = sub_it_.first();
|
current_ = runs_.begin();
|
||||||
|
return get_current();
|
||||||
if (current_span_)
|
|
||||||
current_begin_ = current_span_->first;
|
|
||||||
|
|
||||||
return next();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual maybe_span next() {
|
virtual maybe_span next() {
|
||||||
maybe_span r;
|
if (current_ != runs_.end())
|
||||||
|
++current_;
|
||||||
|
|
||||||
while (more_spans()) {
|
return get_current();
|
||||||
r = next_();
|
|
||||||
if (r)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return r;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool more_spans() const {
|
maybe_span get_current() {
|
||||||
return current_span_;
|
// FIXME: unsafe deref of begin and end
|
||||||
|
return (current_ == runs_.end()) ?
|
||||||
|
maybe_span() :
|
||||||
|
maybe_span(std::make_pair(maybe_default(current_->begin_, 0ULL),
|
||||||
|
maybe_default(current_->end_, max_)));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool span_consumed() const {
|
typedef boost::optional<block_address> maybe;
|
||||||
return current_begin_ == current_span_->second;
|
static block_address maybe_default(maybe const &m, block_address default_) {
|
||||||
|
return m ? *m : default_;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool forbidden_block(block_address b) const {
|
block_address max_;
|
||||||
return forbidden_blocks_.count(b) > 0;
|
block_set runs_;
|
||||||
}
|
block_set::const_iterator current_;
|
||||||
|
|
||||||
void skip_forbidden_blocks() {
|
|
||||||
while (!span_consumed() && forbidden_block(current_begin_))
|
|
||||||
current_begin_++;
|
|
||||||
}
|
|
||||||
|
|
||||||
span get_span() {
|
|
||||||
block_address b = current_begin_;
|
|
||||||
|
|
||||||
while (!span_consumed() && !forbidden_block(current_begin_))
|
|
||||||
current_begin_++;
|
|
||||||
|
|
||||||
return span(b, current_begin_);
|
|
||||||
}
|
|
||||||
|
|
||||||
void get_current_span_from_sub_it() {
|
|
||||||
current_span_ = sub_it_.next();
|
|
||||||
if (current_span_)
|
|
||||||
current_begin_ = current_span_->first;
|
|
||||||
}
|
|
||||||
|
|
||||||
maybe_span next_() {
|
|
||||||
if (span_consumed())
|
|
||||||
get_current_span_from_sub_it();
|
|
||||||
|
|
||||||
if (!more_spans())
|
|
||||||
return maybe_span();
|
|
||||||
|
|
||||||
skip_forbidden_blocks();
|
|
||||||
|
|
||||||
if (!span_consumed())
|
|
||||||
return maybe_span(get_span());
|
|
||||||
else
|
|
||||||
return maybe_span();
|
|
||||||
}
|
|
||||||
|
|
||||||
span_iterator &sub_it_;
|
|
||||||
block_set const &forbidden_blocks_;
|
|
||||||
maybe_span current_span_;
|
|
||||||
block_address current_begin_;
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
#include "gmock/gmock.h"
|
#include "gmock/gmock.h"
|
||||||
|
|
||||||
#include "persistent-data/space-maps/subtracting_span_iterator.h"
|
#include "persistent-data/space-maps/subtracting_span_iterator.h"
|
||||||
|
#include "persistent-data/run_set.h"
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
using namespace persistent_data;
|
using namespace persistent_data;
|
||||||
@ -53,27 +54,42 @@ namespace {
|
|||||||
|
|
||||||
class span_iterator_mock : public space_map::span_iterator {
|
class span_iterator_mock : public space_map::span_iterator {
|
||||||
public:
|
public:
|
||||||
|
span_iterator_mock() {
|
||||||
|
Sequence dummy;
|
||||||
|
|
||||||
|
EXPECT_CALL(*this, first()).
|
||||||
|
InSequence(dummy).
|
||||||
|
WillOnce(Return(maybe_span(span(23, 47))));
|
||||||
|
EXPECT_CALL(*this, next()).
|
||||||
|
InSequence(dummy).
|
||||||
|
WillOnce(Return(maybe_span(span(59, 103))));
|
||||||
|
EXPECT_CALL(*this, next()).
|
||||||
|
InSequence(dummy).
|
||||||
|
WillOnce(Return(maybe_span()));
|
||||||
|
}
|
||||||
|
|
||||||
MOCK_METHOD0(first, maybe_span());
|
MOCK_METHOD0(first, maybe_span());
|
||||||
MOCK_METHOD0(next, maybe_span());
|
MOCK_METHOD0(next, maybe_span());
|
||||||
};
|
};
|
||||||
|
|
||||||
class SpanItTests : public Test {
|
class SpanItTests : public Test {
|
||||||
public:
|
public:
|
||||||
SpanItTests()
|
subtracting_span_iterator run() {
|
||||||
: it(mock_it, forbidden) {
|
span_iterator_mock mock_it;
|
||||||
|
return subtracting_span_iterator(1000, mock_it, forbidden);
|
||||||
EXPECT_CALL(mock_it, first()).
|
|
||||||
Times(1).
|
|
||||||
WillOnce(Return(maybe_span(span(23, 47))));
|
|
||||||
EXPECT_CALL(mock_it, next()).
|
|
||||||
Times(1).
|
|
||||||
WillOnce(Return(maybe_span(span(59, 103))));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
span_iterator_mock mock_it;
|
base::run_set<block_address> forbidden;
|
||||||
set<block_address> forbidden;
|
|
||||||
subtracting_span_iterator it;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
ostream &operator <<(ostream &out, maybe_span const &m) {
|
||||||
|
out << "maybe_span[";
|
||||||
|
if (m)
|
||||||
|
out << m->first << ", " << m->second;
|
||||||
|
out << "]";
|
||||||
|
|
||||||
|
return out;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------
|
//----------------------------------------------------------------
|
||||||
@ -103,14 +119,16 @@ TEST(RegularSpanItTests, regular_span_iterator)
|
|||||||
|
|
||||||
TEST_F(SpanItTests, sub_it_with_no_removed_blocks)
|
TEST_F(SpanItTests, sub_it_with_no_removed_blocks)
|
||||||
{
|
{
|
||||||
|
auto it = run();
|
||||||
ASSERT_THAT(it.first(), Eq(maybe_span(span(23, 47))));
|
ASSERT_THAT(it.first(), Eq(maybe_span(span(23, 47))));
|
||||||
ASSERT_THAT(it.next(), Eq(maybe_span(span(59, 103))));
|
ASSERT_THAT(it.next(), Eq(maybe_span(span(59, 103))));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(SpanItTests, sub_it_with_removed_first_block)
|
TEST_F(SpanItTests, sub_it_with_removed_first_block)
|
||||||
{
|
{
|
||||||
forbidden.insert(23);
|
forbidden.add(23);
|
||||||
|
|
||||||
|
auto it = run();
|
||||||
ASSERT_THAT(it.first(), Eq(maybe_span(span(24, 47))));
|
ASSERT_THAT(it.first(), Eq(maybe_span(span(24, 47))));
|
||||||
ASSERT_THAT(it.next(), Eq(maybe_span(span(59, 103))));
|
ASSERT_THAT(it.next(), Eq(maybe_span(span(59, 103))));
|
||||||
}
|
}
|
||||||
@ -118,16 +136,18 @@ TEST_F(SpanItTests, sub_it_with_removed_first_block)
|
|||||||
TEST_F(SpanItTests, sub_it_with_removed_run_overlapping_front_of_first_block)
|
TEST_F(SpanItTests, sub_it_with_removed_run_overlapping_front_of_first_block)
|
||||||
{
|
{
|
||||||
for (block_address i = 19; i < 26; i++)
|
for (block_address i = 19; i < 26; i++)
|
||||||
forbidden.insert(i);
|
forbidden.add(i);
|
||||||
|
|
||||||
|
auto it = run();
|
||||||
ASSERT_THAT(it.first(), Eq(maybe_span(span(26, 47))));
|
ASSERT_THAT(it.first(), Eq(maybe_span(span(26, 47))));
|
||||||
ASSERT_THAT(it.next(), Eq(maybe_span(span(59, 103))));
|
ASSERT_THAT(it.next(), Eq(maybe_span(span(59, 103))));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(SpanItTests, sub_it_with_removed_mid_block)
|
TEST_F(SpanItTests, sub_it_with_removed_mid_block)
|
||||||
{
|
{
|
||||||
forbidden.insert(40);
|
forbidden.add(40);
|
||||||
|
|
||||||
|
auto it = run();
|
||||||
ASSERT_THAT(it.first(), Eq(maybe_span(span(23, 40))));
|
ASSERT_THAT(it.first(), Eq(maybe_span(span(23, 40))));
|
||||||
ASSERT_THAT(it.next(), Eq(maybe_span(span(41, 47))));
|
ASSERT_THAT(it.next(), Eq(maybe_span(span(41, 47))));
|
||||||
ASSERT_THAT(it.next(), Eq(maybe_span(span(59, 103))));
|
ASSERT_THAT(it.next(), Eq(maybe_span(span(59, 103))));
|
||||||
@ -136,8 +156,9 @@ TEST_F(SpanItTests, sub_it_with_removed_mid_block)
|
|||||||
TEST_F(SpanItTests, sub_it_with_removed_run_mid_block)
|
TEST_F(SpanItTests, sub_it_with_removed_run_mid_block)
|
||||||
{
|
{
|
||||||
for (block_address i = 26; i < 36; i++)
|
for (block_address i = 26; i < 36; i++)
|
||||||
forbidden.insert(i);
|
forbidden.add(i);
|
||||||
|
|
||||||
|
auto it = run();
|
||||||
ASSERT_THAT(it.first(), Eq(maybe_span(span(23, 26))));
|
ASSERT_THAT(it.first(), Eq(maybe_span(span(23, 26))));
|
||||||
ASSERT_THAT(it.next(), Eq(maybe_span(span(36, 47))));
|
ASSERT_THAT(it.next(), Eq(maybe_span(span(36, 47))));
|
||||||
ASSERT_THAT(it.next(), Eq(maybe_span(span(59, 103))));
|
ASSERT_THAT(it.next(), Eq(maybe_span(span(59, 103))));
|
||||||
@ -145,8 +166,9 @@ TEST_F(SpanItTests, sub_it_with_removed_run_mid_block)
|
|||||||
|
|
||||||
TEST_F(SpanItTests, sub_it_with_removed_end_block)
|
TEST_F(SpanItTests, sub_it_with_removed_end_block)
|
||||||
{
|
{
|
||||||
forbidden.insert(46);
|
forbidden.add(46);
|
||||||
|
|
||||||
|
auto it = run();
|
||||||
ASSERT_THAT(it.first(), Eq(maybe_span(span(23, 46))));
|
ASSERT_THAT(it.first(), Eq(maybe_span(span(23, 46))));
|
||||||
ASSERT_THAT(it.next(), Eq(maybe_span(span(59, 103))));
|
ASSERT_THAT(it.next(), Eq(maybe_span(span(59, 103))));
|
||||||
}
|
}
|
||||||
@ -154,8 +176,9 @@ TEST_F(SpanItTests, sub_it_with_removed_end_block)
|
|||||||
TEST_F(SpanItTests, sub_it_with_removed_run_end_block)
|
TEST_F(SpanItTests, sub_it_with_removed_run_end_block)
|
||||||
{
|
{
|
||||||
for (block_address i = 26; i < 50; i++)
|
for (block_address i = 26; i < 50; i++)
|
||||||
forbidden.insert(i);
|
forbidden.add(i);
|
||||||
|
|
||||||
|
auto it = run();
|
||||||
ASSERT_THAT(it.first(), Eq(maybe_span(span(23, 26))));
|
ASSERT_THAT(it.first(), Eq(maybe_span(span(23, 26))));
|
||||||
ASSERT_THAT(it.next(), Eq(maybe_span(span(59, 103))));
|
ASSERT_THAT(it.next(), Eq(maybe_span(span(59, 103))));
|
||||||
}
|
}
|
||||||
@ -163,19 +186,21 @@ TEST_F(SpanItTests, sub_it_with_removed_run_end_block)
|
|||||||
TEST_F(SpanItTests, sub_it_with_removed_run_overlapping_2_blocks)
|
TEST_F(SpanItTests, sub_it_with_removed_run_overlapping_2_blocks)
|
||||||
{
|
{
|
||||||
for (block_address i = 26; i < 70; i++)
|
for (block_address i = 26; i < 70; i++)
|
||||||
forbidden.insert(i);
|
forbidden.add(i);
|
||||||
|
|
||||||
|
auto it = run();
|
||||||
ASSERT_THAT(it.first(), Eq(maybe_span(span(23, 26))));
|
ASSERT_THAT(it.first(), Eq(maybe_span(span(23, 26))));
|
||||||
ASSERT_THAT(it.next(), Eq(maybe_span(span(70, 103))));
|
ASSERT_THAT(it.next(), Eq(maybe_span(span(70, 103))));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(SpanItTests, sub_it_with_removed_intermediate_blocks)
|
TEST_F(SpanItTests, sub_it_with_removed_intermediate_blocks)
|
||||||
{
|
{
|
||||||
forbidden.insert(53);
|
forbidden.add(53);
|
||||||
forbidden.insert(54);
|
forbidden.add(54);
|
||||||
forbidden.insert(57);
|
forbidden.add(57);
|
||||||
forbidden.insert(58);
|
forbidden.add(58);
|
||||||
|
|
||||||
|
auto it = run();
|
||||||
ASSERT_THAT(it.first(), Eq(maybe_span(span(23, 47))));
|
ASSERT_THAT(it.first(), Eq(maybe_span(span(23, 47))));
|
||||||
ASSERT_THAT(it.next(), Eq(maybe_span(span(59, 103))));
|
ASSERT_THAT(it.next(), Eq(maybe_span(span(59, 103))));
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user