// Copyright (C) 2011 Red Hat, Inc. All rights reserved. // // This file is part of the thin-provisioning-tools source. // // thin-provisioning-tools is free software: you can redistribute it // and/or modify it under the terms of the GNU General Public License // as published by the Free Software Foundation, either version 3 of // the License, or (at your option) any later version. // // thin-provisioning-tools is distributed in the hope that it will be // useful, but WITHOUT ANY WARRANTY; without even the implied warranty // of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License along // with thin-provisioning-tools. If not, see // . #include // FIXME: remove #include //---------------------------------------------------------------- namespace { using namespace base; using namespace boost; using namespace std; template bool overlaps_ordered(run const &lhs, run const &rhs) { return rhs.b_ < lhs.e_; } template bool overlaps(run const &lhs, run const &rhs) { if (lhs.b_ <= rhs.b_) return overlaps_ordered(lhs, rhs); else return overlaps_ordered(rhs, lhs); } template boost::optional > merge_ordered_runs_if_overlapping(run const &lhs, run const &rhs) { typedef optional > result; if (lhs.e_ < rhs.e_) return result(run(lhs.b_, rhs.e_)); if (lhs.e_ <= rhs.e_) return result(lhs); return result(); } template boost::optional > merge_if_overlapping(run const &lhs, run const &rhs) { if (lhs.b_ <= rhs.b_) return merge_ordered_runs_if_overlapping(lhs, rhs); else return merge_ordered_runs_if_overlapping(rhs, lhs); } template pair >::const_iterator, typename set >::const_iterator> overlapping_range(set > const &runs, run const &r) { // FIXME: slow, but correct implementation first typedef typename set >::const_iterator cit; for (cit b = runs.begin(); b != runs.end(); ++b) { if (overlaps(*b, r)) { cit e = b; ++e; while (overlaps(*e, r)) ++e; return make_pair(b, e); } } return make_pair(runs.end(), runs.end()); } } //---------------------------------------------------------------- template void run_list::add_run(T const &b, T const &e) { using namespace std; typedef typename set >::const_iterator cit; run r(b, e); pair range = overlapping_range(runs_, r); for (cit it = range.first; it != range.second; ++it) { optional > mr = merge_if_overlapping(r, *it); if (mr) r = *mr; } runs_.erase(range.first, range.second); runs_.insert(r); } template void run_list::sub_run(T const &b, T const &e) { // FIXME: finish } template bool run_list::in_run_(T const &key) const { using namespace std; run r(key, key + 1); typename set >::const_iterator it = runs_.lower_bound(r); if (it != runs_.end() && it->b_ == key) return true; --it; if (it == runs_.end()) return false; return it->b_ <= key && it->e_ > key; } template bool run_list::in_run(T const &key) const { if (invert_) return !in_run_(key); else return in_run_(key); } template void run_list::invert() { invert_ = !invert_; } template void run_list::add(run_list const &rl) { // FIXME: finish } template void run_list::sub(run_list const &rl) { // FIXME: finish } template const_iterator run_list::begin() const { return runs_.begin(); } const_iterator run_list::end() const { return runs_.end(); } //----------------------------------------------------------------