thin-provisioning-tools/era/restore_emitter.cc
Joe Thornber a7c96c0e1e [everything] Fix circular shared pointer references.
We had a cycle from transaction_manager <-> space_map, and also from
the ref_counters back up to the tm.

This prevented objects being destroyed when various programs exited.

From now on we'll try and only use a shared ptr if ownership is
implied.  Otherwise a reference will be used (eg, for up pointers).
2014-08-26 11:14:49 +01:00

117 lines
2.4 KiB
C++

#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<size_t>(sizeof(sb.uuid), uuid.length()));
sb.data_block_size = data_block_size;
sb.nr_blocks = nr_blocks;
sb.current_era = current_era;
nr_blocks = nr_blocks;
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 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_;
uint32_t nr_blocks_;
};
}
//----------------------------------------------------------------
emitter::ptr
era::create_restore_emitter(metadata &md)
{
return emitter::ptr(new restorer(md));
}
//----------------------------------------------------------------