#ifndef BLOCK_H #define BLOCK_H #include #include #include #include #include #include //---------------------------------------------------------------- namespace persistent_data { typedef uint64_t block_address; template class block_manager : private boost::noncopyable { public: typedef boost::shared_ptr ptr; block_manager(std::string const &path); ~block_manager(); typedef unsigned char buffer[BlockSize]; typedef unsigned char const const_buffer[BlockSize]; class block; class block_validator { public: virtual ~block_validator() {} virtual void check(block const &b) const = 0; virtual void prepare(block &b) const = 0; }; struct block { typedef boost::optional maybe_validator; block(block_address location, maybe_validator v = maybe_validator()) : location_(location), validator_(v) { } block_address location_; buffer data_; boost::optional validator_; }; typedef boost::shared_ptr block_ptr; class read_ref { public: read_ref(block_ptr b); virtual ~read_ref() {} block_address get_location() const; const_buffer &data() const; protected: block_ptr block_; }; // Inherited from read_ref, since you can read a block that's write // locked. class write_ref : public read_ref { public: using read_ref::data; buffer &data(); }; // Locking methods read_ref read_lock(block_address location); boost::optional read_try_lock(block_address location); write_ref write_lock(block_address location); write_ref write_lock_zero(block_address location); // Validator variants read_ref read_lock(block_address location, block_validator const &v); boost::optional read_try_lock(block_address location, block_validator const &v); write_ref write_lock(block_address location, block_validator const &v); write_ref write_lock_zero(block_address location, block_validator const &v); // Use this to commit changes void flush(write_ref super_block); private: void read_block(block &b); void write_block(block const &b); void zero_block(block &b); void write_and_release(block *b); int fd_; }; } //---------------------------------------------------------------- #endif