#include "era/restore_emitter.h" #include "era/superblock.h" using namespace era; using namespace persistent_data; //---------------------------------------------------------------- namespace { class restorer : public emitter { public: restorer(metadata &md) : md_(md), in_superblock_(false), in_writeset_(false), in_era_array_(false) { } virtual void begin_superblock(std::string const &uuid, uint32_t data_block_size, pd::block_address nr_blocks, uint32_t current_era) { superblock &sb = md_.sb_; memcpy(sb.uuid, reinterpret_cast<__u8 const *>(uuid.c_str()), min(sizeof(sb.uuid), uuid.length())); sb.data_block_size = data_block_size; sb.nr_blocks = nr_blocks; sb.current_era = current_era; md_.era_array_->grow(nr_blocks, 0); in_superblock_ = true; } virtual void end_superblock() { if (!in_superblock_) throw runtime_error("xml missing superblock"); md_.commit(); } virtual void begin_writeset(uint32_t era, uint32_t nr_bits) { if (!in_superblock_) throw runtime_error("missing superblock"); if (in_writeset_) throw runtime_error("attempt to begin writeset when already in one"); in_writeset_ = true; era_ = era; bits_.reset(new persistent_data::bitset(*md_.tm_)); bits_->grow(nr_bits, false); } virtual void writeset_bit(uint32_t bit, bool value) { bits_->set(bit, value); } virtual void end_writeset() { in_writeset_ = false; bits_->flush(); era_detail e; e.nr_bits = bits_->get_nr_bits(); e.writeset_root = bits_->get_root(); uint64_t key[1] = {era_}; md_.writeset_tree_->insert(key, e); } virtual void begin_era_array() { if (!in_superblock_) throw runtime_error("missing superblock"); in_era_array_ = true; } virtual void era(pd::block_address block, uint32_t era) { if (!in_era_array_) throw runtime_error("missing era array"); md_.era_array_->set(block, era); } virtual void end_era_array() { in_era_array_ = false; } private: metadata &md_; bool in_superblock_; bool in_writeset_; uint32_t era_; pd::bitset::ptr bits_; bool in_era_array_; }; } //---------------------------------------------------------------- emitter::ptr era::create_restore_emitter(metadata &md) { return emitter::ptr(new restorer(md)); } //----------------------------------------------------------------