// Copyright (C) 20011 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 // . #ifndef SPACE_MAP_H #define SPACE_MAP_H #include "block.h" #include "block_counter.h" #include #include //---------------------------------------------------------------- namespace persistent_data { typedef uint32_t ref_t; class space_map { public: typedef boost::shared_ptr ptr; virtual ~space_map() {}; virtual block_address get_nr_blocks() const = 0; virtual block_address get_nr_free() const = 0; virtual ref_t get_count(block_address b) const = 0; virtual void set_count(block_address b, ref_t c) = 0; virtual void commit() = 0; virtual void inc(block_address b) = 0; virtual void dec(block_address b) = 0; // FIXME: change these to return an optional, failure is // not that rare if we're restricting the area that's // searched. typedef boost::optional maybe_block; virtual maybe_block new_block() = 0; virtual maybe_block new_block(block_address begin, block_address end) = 0; virtual bool count_possibly_greater_than_one(block_address b) const = 0; virtual void extend(block_address extra_blocks) = 0; struct iterator { virtual ~iterator() {} virtual void operator() (block_address b, ref_t c) = 0; }; virtual void iterate(iterator &it) const { throw std::runtime_error("not implemented"); } }; class persistent_space_map : public space_map { public: typedef boost::shared_ptr ptr; virtual size_t root_size() const = 0; virtual void copy_root(void *dest, size_t len) const = 0; }; class checked_space_map : public persistent_space_map { public: typedef boost::shared_ptr ptr; virtual void check(block_counter &counter) const { throw std::runtime_error("not implemented"); } virtual ptr clone() const = 0; }; class sm_adjust { public: sm_adjust(space_map::ptr sm, block_address b, int delta) : sm_(sm), b_(b), delta_(delta) { adjust_count(delta_); } ~sm_adjust() { adjust_count(-delta_); } void release() { delta_ = 0; } private: void adjust_count(int delta) { if (delta == 1) sm_->inc(b_); else if (delta == -1) sm_->dec(b_); else sm_->set_count(b_, sm_->get_count(b_) + delta); } space_map::ptr sm_; block_address b_; int delta_; }; class sm_decrementer { public: sm_decrementer(space_map::ptr sm, block_address b); ~sm_decrementer(); void dont_bother(); private: space_map::ptr sm_; block_address b_; bool released_; }; } //---------------------------------------------------------------- #endif