d8a208cbc8
new_block() is now a concrete method implemented using the virtual find_free() and inc() methods. recursive space map is better at giving correct reference counts.
103 lines
2.0 KiB
C++
103 lines
2.0 KiB
C++
#ifndef SPAN_ITERATOR_H
|
|
#define SPAN_ITERATOR_H
|
|
|
|
#include "persistent-data/space_map.h"
|
|
|
|
#include <set>
|
|
|
|
//----------------------------------------------------------------
|
|
|
|
namespace persistent_data {
|
|
// FIXME: rewrite with tests using the run_list stuff.
|
|
class subtracting_span_iterator : public space_map::span_iterator {
|
|
public:
|
|
typedef set<block_address> block_set;
|
|
typedef space_map::span span;
|
|
|
|
subtracting_span_iterator(span_iterator &sub_it,
|
|
block_set const &forbidden_blocks)
|
|
: sub_it_(sub_it),
|
|
forbidden_blocks_(forbidden_blocks),
|
|
current_begin_() {
|
|
}
|
|
|
|
virtual maybe_span first() {
|
|
current_span_ = sub_it_.first();
|
|
|
|
if (current_span_)
|
|
current_begin_ = current_span_->first;
|
|
|
|
return next();
|
|
}
|
|
|
|
virtual maybe_span next() {
|
|
maybe_span r;
|
|
|
|
while (more_spans()) {
|
|
r = next_();
|
|
if (r)
|
|
break;
|
|
}
|
|
|
|
return r;
|
|
}
|
|
|
|
private:
|
|
bool more_spans() const {
|
|
return current_span_;
|
|
}
|
|
|
|
bool span_consumed() const {
|
|
return current_begin_ == current_span_->second;
|
|
}
|
|
|
|
bool forbidden_block(block_address b) const {
|
|
return forbidden_blocks_.count(b) > 0;
|
|
}
|
|
|
|
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_;
|
|
};
|
|
}
|
|
|
|
//----------------------------------------------------------------
|
|
|
|
#endif
|