64 lines
1.4 KiB
C++
64 lines
1.4 KiB
C++
#ifndef SPAN_ITERATOR_H
|
|
#define SPAN_ITERATOR_H
|
|
|
|
#include "base/run_set.h"
|
|
#include "persistent-data/space_map.h"
|
|
|
|
#include <set>
|
|
|
|
//----------------------------------------------------------------
|
|
|
|
namespace persistent_data {
|
|
class subtracting_span_iterator : public space_map::span_iterator {
|
|
public:
|
|
typedef base::run_set<block_address> block_set;
|
|
typedef space_map::span span;
|
|
|
|
subtracting_span_iterator(block_address max,
|
|
span_iterator &sub_it,
|
|
block_set const &forbidden_blocks)
|
|
: max_(max) {
|
|
for (maybe_span ms = sub_it.first(); ms; ms = sub_it.next())
|
|
runs_.add(ms->first, ms->second);
|
|
|
|
block_set bs(forbidden_blocks);
|
|
runs_.negate();
|
|
runs_.merge(bs);
|
|
runs_.negate();
|
|
}
|
|
|
|
virtual maybe_span first() {
|
|
current_ = runs_.begin();
|
|
return get_current();
|
|
}
|
|
|
|
virtual maybe_span next() {
|
|
if (current_ != runs_.end())
|
|
++current_;
|
|
|
|
return get_current();
|
|
}
|
|
|
|
private:
|
|
maybe_span get_current() {
|
|
return (current_ == runs_.end()) ?
|
|
maybe_span() :
|
|
maybe_span(std::make_pair(maybe_default(current_->begin_, 0ULL),
|
|
maybe_default(current_->end_, max_)));
|
|
}
|
|
|
|
typedef boost::optional<block_address> maybe;
|
|
static block_address maybe_default(maybe const &m, block_address default_) {
|
|
return m ? *m : default_;
|
|
}
|
|
|
|
block_address max_;
|
|
block_set runs_;
|
|
block_set::const_iterator current_;
|
|
};
|
|
}
|
|
|
|
//----------------------------------------------------------------
|
|
|
|
#endif
|