[thin-repair] stop using c++0x features
This commit is contained in:
parent
987a8360c9
commit
04d7b7ce5b
3
Makefile
3
Makefile
@ -15,7 +15,8 @@ TEST_SOURCE=\
|
|||||||
OBJECTS=$(subst .cc,.o,$(SOURCE))
|
OBJECTS=$(subst .cc,.o,$(SOURCE))
|
||||||
TEST_PROGRAMS=$(subst .cc,,$(TEST_SOURCE))
|
TEST_PROGRAMS=$(subst .cc,,$(TEST_SOURCE))
|
||||||
TOP_DIR:=$(PWD)
|
TOP_DIR:=$(PWD)
|
||||||
CPPFLAGS=-Wall -std=c++0x -g -I$(TOP_DIR)
|
CPPFLAGS=-Wall -g -I$(TOP_DIR)
|
||||||
|
#CPPFLAGS=-Wall -std=c++0x -g -I$(TOP_DIR)
|
||||||
LIBS=-lstdc++
|
LIBS=-lstdc++
|
||||||
|
|
||||||
.PHONEY: unit-tests test-programs
|
.PHONEY: unit-tests test-programs
|
||||||
|
3
block.h
3
block.h
@ -181,7 +181,8 @@ namespace persistent_data {
|
|||||||
mutable unsigned superblock_count_;
|
mutable unsigned superblock_count_;
|
||||||
mutable unsigned ordinary_count_;
|
mutable unsigned ordinary_count_;
|
||||||
|
|
||||||
mutable std::map<block_address, std::pair<lock_type, unsigned> > held_locks_;
|
typedef std::map<block_address, std::pair<lock_type, unsigned> > held_map;
|
||||||
|
mutable held_map held_locks_;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
#include "block.h"
|
#include "block.h"
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
@ -352,7 +353,7 @@ template <uint32_t BlockSize>
|
|||||||
void
|
void
|
||||||
block_manager<BlockSize>::register_lock(block_address b, lock_type t) const
|
block_manager<BlockSize>::register_lock(block_address b, lock_type t) const
|
||||||
{
|
{
|
||||||
auto it = held_locks_.find(b);
|
typename held_map::iterator it = held_locks_.find(b);
|
||||||
if (it == held_locks_.end())
|
if (it == held_locks_.end())
|
||||||
held_locks_.insert(make_pair(b, make_pair(t, 1)));
|
held_locks_.insert(make_pair(b, make_pair(t, 1)));
|
||||||
else {
|
else {
|
||||||
@ -370,7 +371,7 @@ template <uint32_t BlockSize>
|
|||||||
void
|
void
|
||||||
block_manager<BlockSize>::unregister_lock(block_address b, lock_type t) const
|
block_manager<BlockSize>::unregister_lock(block_address b, lock_type t) const
|
||||||
{
|
{
|
||||||
auto it = held_locks_.find(b);
|
typename held_map::iterator it = held_locks_.find(b);
|
||||||
if (it == held_locks_.end())
|
if (it == held_locks_.end())
|
||||||
throw std::runtime_error("lock not held");
|
throw std::runtime_error("lock not held");
|
||||||
|
|
||||||
|
22
btree.h
22
btree.h
@ -189,13 +189,16 @@ namespace persistent_data {
|
|||||||
template <uint32_t BlockSize>
|
template <uint32_t BlockSize>
|
||||||
class shadow_spine : private noncopyable {
|
class shadow_spine : private noncopyable {
|
||||||
public:
|
public:
|
||||||
|
typedef typename transaction_manager<BlockSize>::read_ref read_ref;
|
||||||
|
typedef typename transaction_manager<BlockSize>::write_ref write_ref;
|
||||||
|
|
||||||
shadow_spine(typename transaction_manager<BlockSize>::ptr tm)
|
shadow_spine(typename transaction_manager<BlockSize>::ptr tm)
|
||||||
: tm_(tm) {
|
: tm_(tm) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// true if the children of the shadow need incrementing
|
// true if the children of the shadow need incrementing
|
||||||
bool step(block_address b) {
|
bool step(block_address b) {
|
||||||
auto p = tm_->shadow(b);
|
pair<write_ref, bool> p = tm_->shadow(b);
|
||||||
try {
|
try {
|
||||||
step(p.first);
|
step(p.first);
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
@ -261,16 +264,16 @@ namespace persistent_data {
|
|||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
spine.step(block);
|
spine.step(block);
|
||||||
auto leaf = spine.template get_node<ValueTraits>();
|
node_ref<ValueTraits, BlockSize> leaf = spine.template get_node<ValueTraits>();
|
||||||
|
|
||||||
auto mi = leaf.exact_search(key);
|
optional<unsigned> mi = leaf.exact_search(key);
|
||||||
if (!mi)
|
if (!mi)
|
||||||
return optional<leaf_type>();
|
return optional<leaf_type>();
|
||||||
|
|
||||||
if (leaf.get_type() == btree_detail::LEAF)
|
if (leaf.get_type() == btree_detail::LEAF)
|
||||||
return optional<leaf_type>(leaf.value_at(*mi));
|
return optional<leaf_type>(leaf.value_at(*mi));
|
||||||
|
|
||||||
auto internal = spine.template get_node<uint64_traits>();
|
node_ref<uint64_traits, BlockSize> internal = spine.template get_node<uint64_traits>();
|
||||||
block = internal.value_at(*mi);
|
block = internal.value_at(*mi);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -287,6 +290,8 @@ namespace persistent_data {
|
|||||||
typedef boost::optional<std::pair<unsigned, value_type> > maybe_pair;
|
typedef boost::optional<std::pair<unsigned, value_type> > maybe_pair;
|
||||||
typedef typename block_manager<BlockSize>::read_ref read_ref;
|
typedef typename block_manager<BlockSize>::read_ref read_ref;
|
||||||
typedef typename block_manager<BlockSize>::write_ref write_ref;
|
typedef typename block_manager<BlockSize>::write_ref write_ref;
|
||||||
|
typedef typename btree_detail::node_ref<ValueTraits, BlockSize> leaf_node;
|
||||||
|
typedef typename btree_detail::node_ref<uint64_traits, BlockSize> internal_node;
|
||||||
|
|
||||||
btree(typename persistent_data::transaction_manager<BlockSize>::ptr tm,
|
btree(typename persistent_data::transaction_manager<BlockSize>::ptr tm,
|
||||||
typename ValueTraits::ref_counter rc);
|
typename ValueTraits::ref_counter rc);
|
||||||
@ -320,12 +325,9 @@ namespace persistent_data {
|
|||||||
virtual ~visitor() {}
|
virtual ~visitor() {}
|
||||||
typedef boost::shared_ptr<visitor> ptr;
|
typedef boost::shared_ptr<visitor> ptr;
|
||||||
|
|
||||||
virtual void visit_internal(unsigned level, bool is_root,
|
virtual void visit_internal(unsigned level, bool is_root, internal_node const &n) = 0;
|
||||||
btree_detail::node_ref<uint64_traits, BlockSize> const &n) = 0;
|
virtual void visit_internal_leaf(unsigned level, bool is_root, internal_node const &n) = 0;
|
||||||
virtual void visit_internal_leaf(unsigned level, bool is_root,
|
virtual void visit_leaf(unsigned level, bool is_root, leaf_node const &n) = 0;
|
||||||
btree_detail::node_ref<uint64_traits, BlockSize> const &n) = 0;
|
|
||||||
virtual void visit_leaf(unsigned level, bool is_root,
|
|
||||||
btree_detail::node_ref<ValueTraits, BlockSize> const &n) = 0;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// Walks the tree in depth first order
|
// Walks the tree in depth first order
|
||||||
|
55
btree.tcc
55
btree.tcc
@ -277,7 +277,7 @@ btree(typename transaction_manager<BlockSize>::ptr tm,
|
|||||||
|
|
||||||
write_ref root = tm_->new_block();
|
write_ref root = tm_->new_block();
|
||||||
|
|
||||||
auto n = to_node<ValueTraits, BlockSize>(root);
|
leaf_node n = to_node<ValueTraits, BlockSize>(root);
|
||||||
n.set_type(btree_detail::LEAF);
|
n.set_type(btree_detail::LEAF);
|
||||||
n.set_nr_entries(0);
|
n.set_nr_entries(0);
|
||||||
n.set_max_entries();
|
n.set_max_entries();
|
||||||
@ -357,7 +357,7 @@ insert(key const &key,
|
|||||||
for (unsigned level = 0; level < Levels - 1; ++level) {
|
for (unsigned level = 0; level < Levels - 1; ++level) {
|
||||||
bool need_insert = insert_location<uint64_traits>(spine, block, key[level], &index);
|
bool need_insert = insert_location<uint64_traits>(spine, block, key[level], &index);
|
||||||
|
|
||||||
auto n = spine.template get_node<uint64_traits>();
|
internal_node n = spine.template get_node<uint64_traits>();
|
||||||
if (need_insert) {
|
if (need_insert) {
|
||||||
btree<Levels - 1, ValueTraits, BlockSize> new_tree(tm_, rc_);
|
btree<Levels - 1, ValueTraits, BlockSize> new_tree(tm_, rc_);
|
||||||
n.insert_at(index, key[level], new_tree.get_root());
|
n.insert_at(index, key[level], new_tree.get_root());
|
||||||
@ -368,7 +368,7 @@ insert(key const &key,
|
|||||||
|
|
||||||
bool need_insert = insert_location<ValueTraits>(spine, block, key[Levels - 1], &index);
|
bool need_insert = insert_location<ValueTraits>(spine, block, key[Levels - 1], &index);
|
||||||
|
|
||||||
auto n = spine.template get_node<ValueTraits>();
|
leaf_node n = spine.template get_node<ValueTraits>();
|
||||||
if (need_insert)
|
if (need_insert)
|
||||||
n.insert_at(index, key[Levels - 1], value);
|
n.insert_at(index, key[Levels - 1], value);
|
||||||
else
|
else
|
||||||
@ -406,17 +406,17 @@ btree<Levels, ValueTraits, BlockSize>::clone() const
|
|||||||
ro_spine<BlockSize> spine(tm_);
|
ro_spine<BlockSize> spine(tm_);
|
||||||
|
|
||||||
spine.step(root_);
|
spine.step(root_);
|
||||||
auto new_root = tm_->new_block();
|
write_ref new_root = tm_->new_block();
|
||||||
|
|
||||||
auto o = spine.template get_node<uint64_traits>();
|
internal_node o = spine.template get_node<uint64_traits>();
|
||||||
if (o.get_type() == INTERNAL) {
|
if (o.get_type() == INTERNAL) {
|
||||||
auto n = to_node<uint64_traits, BlockSize>(new_root);
|
internal_node n = to_node<uint64_traits, BlockSize>(new_root);
|
||||||
::memcpy(n.raw(), o.raw(), BlockSize);
|
::memcpy(n.raw(), o.raw(), BlockSize);
|
||||||
|
|
||||||
typename uint64_traits::ref_counter rc(internal_rc_);
|
typename uint64_traits::ref_counter rc(internal_rc_);
|
||||||
n.inc_children(rc);
|
n.inc_children(rc);
|
||||||
} else {
|
} else {
|
||||||
auto n = to_node<ValueTraits, BlockSize>(new_root);
|
leaf_node n = to_node<ValueTraits, BlockSize>(new_root);
|
||||||
::memcpy(n.raw(), o.raw(), BlockSize);
|
::memcpy(n.raw(), o.raw(), BlockSize);
|
||||||
|
|
||||||
typename ValueTraits::ref_counter rc(rc_);
|
typename ValueTraits::ref_counter rc(rc_);
|
||||||
@ -447,7 +447,7 @@ split_node(btree_detail::shadow_spine<BlockSize> &spine,
|
|||||||
uint64_t key,
|
uint64_t key,
|
||||||
bool top)
|
bool top)
|
||||||
{
|
{
|
||||||
auto n = spine.template get_node<ValueTraits>();
|
node_ref<ValueTraits, BlockSize> n = spine.template get_node<ValueTraits>();
|
||||||
if (n.get_nr_entries() == n.get_max_entries()) {
|
if (n.get_nr_entries() == n.get_max_entries()) {
|
||||||
if (top)
|
if (top)
|
||||||
split_beneath<ValueTraits>(spine, key);
|
split_beneath<ValueTraits>(spine, key);
|
||||||
@ -468,18 +468,18 @@ split_beneath(btree_detail::shadow_spine<BlockSize> &spine,
|
|||||||
node_type type;
|
node_type type;
|
||||||
unsigned nr_left, nr_right;
|
unsigned nr_left, nr_right;
|
||||||
|
|
||||||
auto left = tm_->new_block();
|
write_ref left = tm_->new_block();
|
||||||
auto l = to_node<ValueTraits, BlockSize>(left);
|
node_ref<ValueTraits, BlockSize> l = to_node<ValueTraits, BlockSize>(left);
|
||||||
l.set_nr_entries(0);
|
l.set_nr_entries(0);
|
||||||
l.set_max_entries();
|
l.set_max_entries();
|
||||||
|
|
||||||
auto right = tm_->new_block();
|
write_ref right = tm_->new_block();
|
||||||
auto r = to_node<ValueTraits, BlockSize>(right);
|
node_ref<ValueTraits, BlockSize> r = to_node<ValueTraits, BlockSize>(right);
|
||||||
r.set_nr_entries(0);
|
r.set_nr_entries(0);
|
||||||
r.set_max_entries();
|
r.set_max_entries();
|
||||||
|
|
||||||
{
|
{
|
||||||
auto p = spine.template get_node<ValueTraits>();
|
node_ref<ValueTraits, BlockSize> p = spine.template get_node<ValueTraits>();
|
||||||
nr_left = p.get_nr_entries() / 2;
|
nr_left = p.get_nr_entries() / 2;
|
||||||
nr_right = p.get_nr_entries() - nr_left;
|
nr_right = p.get_nr_entries() - nr_left;
|
||||||
type = p.get_type();
|
type = p.get_type();
|
||||||
@ -493,10 +493,11 @@ split_beneath(btree_detail::shadow_spine<BlockSize> &spine,
|
|||||||
|
|
||||||
{
|
{
|
||||||
// The parent may have changed value type, so we re-get it.
|
// The parent may have changed value type, so we re-get it.
|
||||||
auto p = spine.template get_node<uint64_traits>();
|
internal_node p = spine.template get_node<uint64_traits>();
|
||||||
p.set_type(btree_detail::INTERNAL);
|
p.set_type(btree_detail::INTERNAL);
|
||||||
p.set_nr_entries(2);
|
p.set_nr_entries(2);
|
||||||
|
|
||||||
|
// FIXME: set the value_size
|
||||||
p.overwrite_at(0, l.key_at(0), left.get_location());
|
p.overwrite_at(0, l.key_at(0), left.get_location());
|
||||||
p.overwrite_at(1, r.key_at(0), right.get_location());
|
p.overwrite_at(1, r.key_at(0), right.get_location());
|
||||||
}
|
}
|
||||||
@ -517,11 +518,11 @@ split_sibling(btree_detail::shadow_spine<BlockSize> &spine,
|
|||||||
{
|
{
|
||||||
using namespace btree_detail;
|
using namespace btree_detail;
|
||||||
|
|
||||||
auto l = spine.template get_node<ValueTraits>();
|
node_ref<ValueTraits, BlockSize> l = spine.template get_node<ValueTraits>();
|
||||||
auto left = spine.get_block();
|
block_address left = spine.get_block();
|
||||||
|
|
||||||
auto right = tm_->new_block();
|
write_ref right = tm_->new_block();
|
||||||
auto r = to_node<ValueTraits, BlockSize>(right);
|
node_ref<ValueTraits, BlockSize> r = to_node<ValueTraits, BlockSize>(right);
|
||||||
|
|
||||||
unsigned nr_left = l.get_nr_entries() / 2;
|
unsigned nr_left = l.get_nr_entries() / 2;
|
||||||
unsigned nr_right = l.get_nr_entries() - nr_left;
|
unsigned nr_right = l.get_nr_entries() - nr_left;
|
||||||
@ -532,7 +533,7 @@ split_sibling(btree_detail::shadow_spine<BlockSize> &spine,
|
|||||||
r.copy_entries(l, nr_left, nr_left + nr_right);
|
r.copy_entries(l, nr_left, nr_left + nr_right);
|
||||||
l.set_nr_entries(nr_left);
|
l.set_nr_entries(nr_left);
|
||||||
|
|
||||||
auto p = spine.get_parent();
|
internal_node p = spine.get_parent();
|
||||||
p.overwrite_at(parent_index, l.key_at(0), left);
|
p.overwrite_at(parent_index, l.key_at(0), left);
|
||||||
p.insert_at(parent_index + 1, r.key_at(0), right.get_location());
|
p.insert_at(parent_index + 1, r.key_at(0), right.get_location());
|
||||||
|
|
||||||
@ -568,11 +569,11 @@ insert_location(btree_detail::shadow_spine<BlockSize> &spine,
|
|||||||
|
|
||||||
// patch up the parent to point to the new shadow
|
// patch up the parent to point to the new shadow
|
||||||
if (spine.has_parent()) {
|
if (spine.has_parent()) {
|
||||||
auto p = spine.get_parent();
|
internal_node p = spine.get_parent();
|
||||||
p.set_value(i, spine.get_block());
|
p.set_value(i, spine.get_block());
|
||||||
}
|
}
|
||||||
|
|
||||||
auto internal = spine.template get_node<uint64_traits>();
|
internal_node internal = spine.template get_node<uint64_traits>();
|
||||||
|
|
||||||
// Split the node if we're full
|
// Split the node if we're full
|
||||||
if (internal.get_type() == INTERNAL)
|
if (internal.get_type() == INTERNAL)
|
||||||
@ -594,7 +595,7 @@ insert_location(btree_detail::shadow_spine<BlockSize> &spine,
|
|||||||
top = false;
|
top = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto leaf = spine.template get_node<ValueTraits>();
|
node_ref<ValueTraits, BlockSize> leaf = spine.template get_node<ValueTraits>();
|
||||||
// FIXME: gross
|
// FIXME: gross
|
||||||
if (i < 0 || leaf.key_at(i) != key)
|
if (i < 0 || leaf.key_at(i) != key)
|
||||||
i++;
|
i++;
|
||||||
@ -626,8 +627,9 @@ walk_tree(typename visitor::ptr visitor,
|
|||||||
{
|
{
|
||||||
using namespace btree_detail;
|
using namespace btree_detail;
|
||||||
|
|
||||||
auto blk = tm_->read_lock(b);
|
try {
|
||||||
auto o = to_node<uint64_traits, BlockSize>(blk);
|
read_ref blk = tm_->read_lock(b);
|
||||||
|
internal_node o = to_node<uint64_traits, BlockSize>(blk);
|
||||||
if (o.get_type() == INTERNAL) {
|
if (o.get_type() == INTERNAL) {
|
||||||
visitor->visit_internal(level, is_root, o);
|
visitor->visit_internal(level, is_root, o);
|
||||||
for (unsigned i = 0; i < o.get_nr_entries(); i++)
|
for (unsigned i = 0; i < o.get_nr_entries(); i++)
|
||||||
@ -639,9 +641,12 @@ walk_tree(typename visitor::ptr visitor,
|
|||||||
walk_tree(visitor, level + 1, true, o.value_at(i));
|
walk_tree(visitor, level + 1, true, o.value_at(i));
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
auto ov = to_node<ValueTraits, BlockSize>(blk);
|
leaf_node ov = to_node<ValueTraits, BlockSize>(blk);
|
||||||
visitor->visit_leaf(level, is_root, ov);
|
visitor->visit_leaf(level, is_root, ov);
|
||||||
}
|
}
|
||||||
|
} catch (...) { // FIXME: we should only catch terminate_walk type exceptions
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------
|
//----------------------------------------------------------------
|
||||||
|
@ -3,10 +3,15 @@
|
|||||||
|
|
||||||
#include "btree.h"
|
#include "btree.h"
|
||||||
|
|
||||||
|
#include "error_set.h"
|
||||||
|
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <set>
|
#include <set>
|
||||||
|
|
||||||
|
using namespace persistent_data;
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
//----------------------------------------------------------------
|
//----------------------------------------------------------------
|
||||||
|
|
||||||
namespace persistent_data {
|
namespace persistent_data {
|
||||||
@ -16,8 +21,10 @@ namespace persistent_data {
|
|||||||
//----------------------------------------------------------------
|
//----------------------------------------------------------------
|
||||||
class block_counter {
|
class block_counter {
|
||||||
public:
|
public:
|
||||||
|
typedef typename std::map<block_address, unsigned> count_map;
|
||||||
|
|
||||||
void inc(block_address b) {
|
void inc(block_address b) {
|
||||||
auto it = counts_.find(b);
|
typename count_map::iterator it = counts_.find(b);
|
||||||
if (it == counts_.end())
|
if (it == counts_.end())
|
||||||
counts_.insert(make_pair(b, 1));
|
counts_.insert(make_pair(b, 1));
|
||||||
#if 0
|
#if 0
|
||||||
@ -27,16 +34,16 @@ namespace persistent_data {
|
|||||||
}
|
}
|
||||||
|
|
||||||
unsigned get_count(block_address b) const {
|
unsigned get_count(block_address b) const {
|
||||||
auto it = counts_.find(b);
|
count_map::const_iterator it = counts_.find(b);
|
||||||
return (it == counts_.end()) ? 0 : it->second;
|
return (it == counts_.end()) ? 0 : it->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::map<block_address, unsigned> const &get_counts() const {
|
count_map const &get_counts() const {
|
||||||
return counts_;
|
return counts_;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::map<block_address, unsigned> counts_;
|
count_map counts_;
|
||||||
};
|
};
|
||||||
|
|
||||||
//----------------------------------------------------------------
|
//----------------------------------------------------------------
|
||||||
@ -63,7 +70,8 @@ namespace persistent_data {
|
|||||||
class btree_validator : public btree<Levels, ValueTraits, BlockSize>::visitor {
|
class btree_validator : public btree<Levels, ValueTraits, BlockSize>::visitor {
|
||||||
public:
|
public:
|
||||||
btree_validator(block_counter &counter)
|
btree_validator(block_counter &counter)
|
||||||
: counter_(counter) {
|
: counter_(counter),
|
||||||
|
errs_(new error_set("btree errors")) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void visit_internal(unsigned level, bool is_root,
|
void visit_internal(unsigned level, bool is_root,
|
||||||
@ -93,12 +101,17 @@ namespace persistent_data {
|
|||||||
check_nr_entries(n, is_root);
|
check_nr_entries(n, is_root);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
boost::optional<error_set::ptr> get_errors() const {
|
||||||
|
return errs_;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void check_duplicate_block(block_address b) {
|
void check_duplicate_block(block_address b) {
|
||||||
if (seen_.count(b)) {
|
if (seen_.count(b)) {
|
||||||
std::ostringstream out;
|
std::ostringstream out;
|
||||||
out << "duplicate block in btree: " << b;
|
out << "duplicate block in btree: " << b;
|
||||||
throw std::runtime_error(out.str());
|
errs_->add_child(out.str());
|
||||||
|
throw runtime_error(out.str());
|
||||||
}
|
}
|
||||||
|
|
||||||
seen_.insert(b);
|
seen_.insert(b);
|
||||||
@ -111,7 +124,8 @@ namespace persistent_data {
|
|||||||
out << "block number mismatch: actually "
|
out << "block number mismatch: actually "
|
||||||
<< n.get_location()
|
<< n.get_location()
|
||||||
<< ", claims " << n.get_block_nr();
|
<< ", claims " << n.get_block_nr();
|
||||||
throw std::runtime_error(out.str());
|
errs_->add_child(out.str());
|
||||||
|
throw runtime_error(out.str());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -121,13 +135,14 @@ namespace persistent_data {
|
|||||||
if (elt_size * n.get_max_entries() + sizeof(node_header) > BlockSize) {
|
if (elt_size * n.get_max_entries() + sizeof(node_header) > BlockSize) {
|
||||||
std::ostringstream out;
|
std::ostringstream out;
|
||||||
out << "max entries too large: " << n.get_max_entries();
|
out << "max entries too large: " << n.get_max_entries();
|
||||||
throw std::runtime_error(out.str());
|
errs_->add_child(out.str());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (n.get_max_entries() % 3) {
|
if (n.get_max_entries() % 3) {
|
||||||
std::ostringstream out;
|
std::ostringstream out;
|
||||||
out << "max entries is not divisible by 3: " << n.get_max_entries();
|
out << "max entries is not divisible by 3: " << n.get_max_entries();
|
||||||
throw std::runtime_error(out.str());
|
errs_->add_child(out.str());
|
||||||
|
throw runtime_error(out.str());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -138,6 +153,7 @@ namespace persistent_data {
|
|||||||
out << "bad nr_entries: "
|
out << "bad nr_entries: "
|
||||||
<< n.get_nr_entries() << " < "
|
<< n.get_nr_entries() << " < "
|
||||||
<< n.get_max_entries();
|
<< n.get_max_entries();
|
||||||
|
errs_->add_child(out.str());
|
||||||
throw std::runtime_error(out.str());
|
throw std::runtime_error(out.str());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -148,12 +164,14 @@ namespace persistent_data {
|
|||||||
<< n.get_nr_entries()
|
<< n.get_nr_entries()
|
||||||
<< ", expected at least "
|
<< ", expected at least "
|
||||||
<< min;
|
<< min;
|
||||||
|
errs_->add_child(out.str());
|
||||||
throw runtime_error(out.str());
|
throw runtime_error(out.str());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
block_counter &counter_;
|
block_counter &counter_;
|
||||||
std::set<block_address> seen_;
|
std::set<block_address> seen_;
|
||||||
|
error_set::ptr errs_;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
25
error_set.cc
25
error_set.cc
@ -3,20 +3,21 @@
|
|||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
using namespace persistent_data;
|
using namespace persistent_data;
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
//----------------------------------------------------------------
|
//----------------------------------------------------------------
|
||||||
|
|
||||||
error_set::error_set(std::string const &err)
|
error_set::error_set(string const &err)
|
||||||
: err_(err) {
|
: err_(err) {
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string const &
|
string const &
|
||||||
error_set::get_description() const
|
error_set::get_description() const
|
||||||
{
|
{
|
||||||
return err_;
|
return err_;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::list<error_set::ptr> const &
|
list<error_set::ptr> const &
|
||||||
error_set::get_children() const
|
error_set::get_children() const
|
||||||
{
|
{
|
||||||
return children_;
|
return children_;
|
||||||
@ -29,7 +30,7 @@ error_set::add_child(error_set::ptr err)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
error_set::add_child(std::string const &err)
|
error_set::add_child(string const &err)
|
||||||
{
|
{
|
||||||
error_set::ptr e(new error_set(err));
|
error_set::ptr e(new error_set(err));
|
||||||
add_child(e);
|
add_child(e);
|
||||||
@ -38,21 +39,21 @@ error_set::add_child(std::string const &err)
|
|||||||
//--------------------------------
|
//--------------------------------
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
void indent_by(std::ostream &out, unsigned indent) {
|
void indent_by(ostream &out, unsigned indent) {
|
||||||
for (unsigned i = 0; i < indent; i++)
|
for (unsigned i = 0; i < indent; i++)
|
||||||
out << ' ';
|
out << ' ';
|
||||||
}
|
}
|
||||||
|
|
||||||
void print_errs(std::ostream &out, error_set::ptr e, unsigned depth, unsigned indent) {
|
void print_errs(ostream &out, error_set::ptr e, unsigned depth, unsigned indent) {
|
||||||
if (depth == 0)
|
if (depth == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
indent_by(out, indent);
|
indent_by(out, indent);
|
||||||
|
|
||||||
out << e->get_description() << std::endl;
|
out << e->get_description() << endl;
|
||||||
if (depth > 1) {
|
if (depth > 1) {
|
||||||
auto children = e->get_children();
|
list<error_set::ptr> const &children = e->get_children();
|
||||||
for (auto it = children.begin(); it != children.end(); ++it)
|
for (list<error_set::ptr>::const_iterator it = children.begin(); it != children.end(); ++it)
|
||||||
print_errs(out, *it, depth - 1, indent + 2);
|
print_errs(out, *it, depth - 1, indent + 2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -65,13 +66,13 @@ error_selector::error_selector(error_set::ptr errs, unsigned depth)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
error_selector::print(std::ostream &out) const
|
error_selector::print(ostream &out) const
|
||||||
{
|
{
|
||||||
print_errs(out, errs_, depth_, 0);
|
print_errs(out, errs_, depth_, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::ostream &
|
ostream &
|
||||||
persistent_data::operator << (std::ostream &out, error_selector const &errs)
|
persistent_data::operator << (ostream &out, error_selector const &errs)
|
||||||
{
|
{
|
||||||
errs.print(out);
|
errs.print(out);
|
||||||
return out;
|
return out;
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
#include <boost/shared_ptr.hpp>
|
#include <boost/shared_ptr.hpp>
|
||||||
#include <list>
|
#include <list>
|
||||||
#include <iosfwd>
|
#include <iosfwd>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
//----------------------------------------------------------------
|
//----------------------------------------------------------------
|
||||||
|
|
||||||
|
35
metadata.cc
35
metadata.cc
@ -35,7 +35,7 @@ namespace {
|
|||||||
|
|
||||||
superblock read_superblock(block_manager<4096>::ptr bm) {
|
superblock read_superblock(block_manager<4096>::ptr bm) {
|
||||||
superblock sb;
|
superblock sb;
|
||||||
auto r = bm->read_lock(SUPERBLOCK_LOCATION);
|
block_manager<4096>::read_ref r = bm->read_lock(SUPERBLOCK_LOCATION);
|
||||||
superblock_disk const *sbd = reinterpret_cast<superblock_disk const *>(&r.data());
|
superblock_disk const *sbd = reinterpret_cast<superblock_disk const *>(&r.data());
|
||||||
superblock_traits::unpack(*sbd, sb);
|
superblock_traits::unpack(*sbd, sb);
|
||||||
return sb;
|
return sb;
|
||||||
@ -70,7 +70,7 @@ namespace {
|
|||||||
data_counter_.inc(n.value_at(i).block_);
|
data_counter_.inc(n.value_at(i).block_);
|
||||||
}
|
}
|
||||||
|
|
||||||
set<uint64_t> get_devices() const {
|
set<uint64_t> const &get_devices() const {
|
||||||
return devices_;
|
return devices_;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -95,7 +95,7 @@ namespace {
|
|||||||
devices_.insert(n.key_at(i));
|
devices_.insert(n.key_at(i));
|
||||||
}
|
}
|
||||||
|
|
||||||
set<uint64_t> get_devices() const {
|
set<uint64_t> const &get_devices() const {
|
||||||
return devices_;
|
return devices_;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -146,7 +146,7 @@ void
|
|||||||
thin::set_snapshot_time(uint32_t time)
|
thin::set_snapshot_time(uint32_t time)
|
||||||
{
|
{
|
||||||
uint64_t key[1] = { dev_ };
|
uint64_t key[1] = { dev_ };
|
||||||
auto mdetail = metadata_->details_.lookup(key);
|
optional<device_details> mdetail = metadata_->details_.lookup(key);
|
||||||
if (!mdetail)
|
if (!mdetail)
|
||||||
throw runtime_error("no such device");
|
throw runtime_error("no such device");
|
||||||
|
|
||||||
@ -158,7 +158,7 @@ block_address
|
|||||||
thin::get_mapped_blocks() const
|
thin::get_mapped_blocks() const
|
||||||
{
|
{
|
||||||
uint64_t key[1] = { dev_ };
|
uint64_t key[1] = { dev_ };
|
||||||
auto mdetail = metadata_->details_.lookup(key);
|
optional<device_details> mdetail = metadata_->details_.lookup(key);
|
||||||
if (!mdetail)
|
if (!mdetail)
|
||||||
throw runtime_error("no such device");
|
throw runtime_error("no such device");
|
||||||
|
|
||||||
@ -169,7 +169,7 @@ void
|
|||||||
thin::set_mapped_blocks(block_address count)
|
thin::set_mapped_blocks(block_address count)
|
||||||
{
|
{
|
||||||
uint64_t key[1] = { dev_ };
|
uint64_t key[1] = { dev_ };
|
||||||
auto mdetail = metadata_->details_.lookup(key);
|
optional<device_details> mdetail = metadata_->details_.lookup(key);
|
||||||
if (!mdetail)
|
if (!mdetail)
|
||||||
throw runtime_error("no such device");
|
throw runtime_error("no such device");
|
||||||
|
|
||||||
@ -207,8 +207,8 @@ metadata::commit()
|
|||||||
sb_.data_mapping_root_ = mappings_.get_root();
|
sb_.data_mapping_root_ = mappings_.get_root();
|
||||||
sb_.device_details_root_ = details_.get_root();
|
sb_.device_details_root_ = details_.get_root();
|
||||||
|
|
||||||
auto superblock = tm_->get_bm()->superblock(SUPERBLOCK_LOCATION);
|
write_ref superblock = tm_->get_bm()->superblock(SUPERBLOCK_LOCATION);
|
||||||
auto disk = reinterpret_cast<superblock_disk *>(superblock.data());
|
superblock_disk *disk = reinterpret_cast<superblock_disk *>(superblock.data());
|
||||||
superblock_traits::pack(sb_, *disk);
|
superblock_traits::pack(sb_, *disk);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -231,7 +231,7 @@ metadata::create_snap(thin_dev_t dev, thin_dev_t origin)
|
|||||||
uint64_t snap_key[1] = {dev};
|
uint64_t snap_key[1] = {dev};
|
||||||
uint64_t origin_key[1] = {origin};
|
uint64_t origin_key[1] = {origin};
|
||||||
|
|
||||||
auto mtree_root = mappings_top_level_.lookup(origin_key);
|
optional<uint64_t> mtree_root = mappings_top_level_.lookup(origin_key);
|
||||||
if (!mtree_root)
|
if (!mtree_root)
|
||||||
throw std::runtime_error("unknown origin");
|
throw std::runtime_error("unknown origin");
|
||||||
|
|
||||||
@ -244,8 +244,8 @@ metadata::create_snap(thin_dev_t dev, thin_dev_t origin)
|
|||||||
|
|
||||||
sb_.time_++;
|
sb_.time_++;
|
||||||
|
|
||||||
auto o = open_thin(origin);
|
thin::ptr o = open_thin(origin);
|
||||||
auto s = open_thin(dev);
|
thin::ptr s = open_thin(dev);
|
||||||
o->set_snapshot_time(sb_.time_);
|
o->set_snapshot_time(sb_.time_);
|
||||||
s->set_snapshot_time(sb_.time_);
|
s->set_snapshot_time(sb_.time_);
|
||||||
s->set_mapped_blocks(o->get_mapped_blocks());
|
s->set_mapped_blocks(o->get_mapped_blocks());
|
||||||
@ -310,7 +310,7 @@ thin::ptr
|
|||||||
metadata::open_thin(thin_dev_t dev)
|
metadata::open_thin(thin_dev_t dev)
|
||||||
{
|
{
|
||||||
uint64_t key[1] = {dev};
|
uint64_t key[1] = {dev};
|
||||||
auto mdetails = details_.lookup(key);
|
optional<device_details> mdetails = details_.lookup(key);
|
||||||
if (!mdetails)
|
if (!mdetails)
|
||||||
throw runtime_error("no such device");
|
throw runtime_error("no such device");
|
||||||
|
|
||||||
@ -336,13 +336,13 @@ metadata::check()
|
|||||||
mapping_validator::ptr mv(new mapping_validator(metadata_counter,
|
mapping_validator::ptr mv(new mapping_validator(metadata_counter,
|
||||||
data_counter));
|
data_counter));
|
||||||
mappings_.visit(mv);
|
mappings_.visit(mv);
|
||||||
auto mapped_devs = mv->get_devices();
|
set<uint64_t> const &mapped_devs = mv->get_devices();
|
||||||
|
|
||||||
details_validator::ptr dv(new details_validator(metadata_counter));
|
details_validator::ptr dv(new details_validator(metadata_counter));
|
||||||
details_.visit(dv);
|
details_.visit(dv);
|
||||||
auto details_devs = dv->get_devices();
|
set<uint64_t> const &details_devs = dv->get_devices();
|
||||||
|
|
||||||
for (auto it = mapped_devs.begin(); it != mapped_devs.end(); ++it)
|
for (set<uint64_t>::const_iterator it = mapped_devs.begin(); it != mapped_devs.end(); ++it)
|
||||||
if (details_devs.count(*it) == 0) {
|
if (details_devs.count(*it) == 0) {
|
||||||
ostringstream out;
|
ostringstream out;
|
||||||
out << "mapping exists for device " << *it
|
out << "mapping exists for device " << *it
|
||||||
@ -356,8 +356,9 @@ metadata::check()
|
|||||||
error_set::ptr data_errors(new error_set("Errors in data reference counts"));
|
error_set::ptr data_errors(new error_set("Errors in data reference counts"));
|
||||||
|
|
||||||
bool bad = false;
|
bool bad = false;
|
||||||
auto data_counts = data_counter.get_counts();
|
block_counter::count_map const &data_counts = data_counter.get_counts();
|
||||||
for (auto it = data_counts.begin(); it != data_counts.end(); ++it) {
|
for (block_counter::count_map::const_iterator it = data_counts.begin();
|
||||||
|
it != data_counts.end(); ++it) {
|
||||||
uint32_t ref_count = data_sm_->get_count(it->first);
|
uint32_t ref_count = data_sm_->get_count(it->first);
|
||||||
if (ref_count != it->second) {
|
if (ref_count != it->second) {
|
||||||
ostringstream out;
|
ostringstream out;
|
||||||
|
@ -146,6 +146,8 @@ namespace thin_provisioning {
|
|||||||
class metadata {
|
class metadata {
|
||||||
public:
|
public:
|
||||||
typedef boost::shared_ptr<metadata> ptr;
|
typedef boost::shared_ptr<metadata> ptr;
|
||||||
|
typedef typename block_manager<MD_BLOCK_SIZE>::read_ref read_ref;
|
||||||
|
typedef typename block_manager<MD_BLOCK_SIZE>::write_ref write_ref;
|
||||||
|
|
||||||
metadata(std::string const &dev_path);
|
metadata(std::string const &dev_path);
|
||||||
~metadata();
|
~metadata();
|
||||||
|
@ -19,6 +19,9 @@ namespace persistent_data {
|
|||||||
template <uint32_t BlockSize>
|
template <uint32_t BlockSize>
|
||||||
class bitmap {
|
class bitmap {
|
||||||
public:
|
public:
|
||||||
|
typedef typename transaction_manager<BlockSize>::read_ref read_ref;
|
||||||
|
typedef typename transaction_manager<BlockSize>::write_ref write_ref;
|
||||||
|
|
||||||
bitmap(typename transaction_manager<BlockSize>::ptr tm,
|
bitmap(typename transaction_manager<BlockSize>::ptr tm,
|
||||||
index_entry const &ie)
|
index_entry const &ie)
|
||||||
: tm_(tm),
|
: tm_(tm),
|
||||||
@ -26,7 +29,7 @@ namespace persistent_data {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ref_t lookup(unsigned b) const {
|
ref_t lookup(unsigned b) const {
|
||||||
auto rr = tm_->read_lock(ie_.blocknr_);
|
read_ref rr = tm_->read_lock(ie_.blocknr_);
|
||||||
void const *bits = bitmap_data(rr);
|
void const *bits = bitmap_data(rr);
|
||||||
ref_t b1 = test_bit_le(bits, b * 2);
|
ref_t b1 = test_bit_le(bits, b * 2);
|
||||||
ref_t b2 = test_bit_le(bits, b * 2 + 1);
|
ref_t b2 = test_bit_le(bits, b * 2 + 1);
|
||||||
@ -36,7 +39,7 @@ namespace persistent_data {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void insert(unsigned b, ref_t n) {
|
void insert(unsigned b, ref_t n) {
|
||||||
auto wr = tm_->shadow(ie_.blocknr_).first;
|
write_ref wr = tm_->shadow(ie_.blocknr_).first;
|
||||||
void *bits = bitmap_data(wr);
|
void *bits = bitmap_data(wr);
|
||||||
bool was_free = !test_bit_le(bits, b * 2) && !test_bit_le(bits, b * 2 + 1);
|
bool was_free = !test_bit_le(bits, b * 2) && !test_bit_le(bits, b * 2 + 1);
|
||||||
if (n == 1 || n == 3)
|
if (n == 1 || n == 3)
|
||||||
@ -113,6 +116,8 @@ namespace persistent_data {
|
|||||||
class sm_disk_base : public persistent_space_map {
|
class sm_disk_base : public persistent_space_map {
|
||||||
public:
|
public:
|
||||||
typedef boost::shared_ptr<sm_disk_base<BlockSize> > ptr;
|
typedef boost::shared_ptr<sm_disk_base<BlockSize> > ptr;
|
||||||
|
typedef typename transaction_manager<BlockSize>::read_ref read_ref;
|
||||||
|
typedef typename transaction_manager<BlockSize>::write_ref write_ref;
|
||||||
|
|
||||||
sm_disk_base(typename transaction_manager<BlockSize>::ptr tm)
|
sm_disk_base(typename transaction_manager<BlockSize>::ptr tm)
|
||||||
: tm_(tm),
|
: tm_(tm),
|
||||||
@ -140,7 +145,7 @@ namespace persistent_data {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ref_t get_count(block_address b) const {
|
ref_t get_count(block_address b) const {
|
||||||
auto count = lookup_bitmap(b);
|
ref_t count = lookup_bitmap(b);
|
||||||
if (count == 3)
|
if (count == 3)
|
||||||
return lookup_ref_count(b);
|
return lookup_ref_count(b);
|
||||||
|
|
||||||
@ -188,7 +193,7 @@ namespace persistent_data {
|
|||||||
// beginning.
|
// beginning.
|
||||||
block_address nr_indexes = div_up<block_address>(nr_blocks_, entries_per_block_);
|
block_address nr_indexes = div_up<block_address>(nr_blocks_, entries_per_block_);
|
||||||
for (block_address index = 0; index < nr_indexes; index++) {
|
for (block_address index = 0; index < nr_indexes; index++) {
|
||||||
auto ie = find_ie(index);
|
index_entry ie = find_ie(index);
|
||||||
|
|
||||||
bitmap<BlockSize> bm(tm_, ie);
|
bitmap<BlockSize> bm(tm_, ie);
|
||||||
block_address b = bm.find_free((index == nr_indexes - 1) ?
|
block_address b = bm.find_free((index == nr_indexes - 1) ?
|
||||||
@ -213,7 +218,7 @@ namespace persistent_data {
|
|||||||
block_address bitmap_count = div_up<block_address>(nr_blocks, entries_per_block_);
|
block_address bitmap_count = div_up<block_address>(nr_blocks, entries_per_block_);
|
||||||
block_address old_bitmap_count = div_up<block_address>(nr_blocks_, entries_per_block_);
|
block_address old_bitmap_count = div_up<block_address>(nr_blocks_, entries_per_block_);
|
||||||
for (block_address i = old_bitmap_count; i < bitmap_count; i++) {
|
for (block_address i = old_bitmap_count; i < bitmap_count; i++) {
|
||||||
auto wr = tm_->new_block();
|
write_ref wr = tm_->new_block();
|
||||||
|
|
||||||
struct index_entry ie;
|
struct index_entry ie;
|
||||||
ie.blocknr_ = wr.get_location();
|
ie.blocknr_ = wr.get_location();
|
||||||
@ -258,7 +263,7 @@ namespace persistent_data {
|
|||||||
if (n > 3)
|
if (n > 3)
|
||||||
throw runtime_error("bitmap can only hold 2 bit values");
|
throw runtime_error("bitmap can only hold 2 bit values");
|
||||||
|
|
||||||
auto ie = find_ie(b);
|
index_entry ie = find_ie(b);
|
||||||
bitmap<BlockSize> bm(tm_, ie);
|
bitmap<BlockSize> bm(tm_, ie);
|
||||||
bm.insert(b % entries_per_block_, n);
|
bm.insert(b % entries_per_block_, n);
|
||||||
save_ie(b, bm.get_ie());
|
save_ie(b, bm.get_ie());
|
||||||
@ -266,7 +271,7 @@ namespace persistent_data {
|
|||||||
|
|
||||||
ref_t lookup_ref_count(block_address b) const {
|
ref_t lookup_ref_count(block_address b) const {
|
||||||
uint64_t key[1] = {b};
|
uint64_t key[1] = {b};
|
||||||
auto mvalue = ref_counts_.lookup(key);
|
optional<ref_t> mvalue = ref_counts_.lookup(key);
|
||||||
if (!mvalue)
|
if (!mvalue)
|
||||||
throw runtime_error("ref count not in tree");
|
throw runtime_error("ref count not in tree");
|
||||||
return *mvalue;
|
return *mvalue;
|
||||||
@ -343,7 +348,7 @@ namespace persistent_data {
|
|||||||
private:
|
private:
|
||||||
index_entry find_ie(block_address b) const {
|
index_entry find_ie(block_address b) const {
|
||||||
uint64_t key[1] = {b / sm_disk_base<BlockSize>::get_entries_per_block()};
|
uint64_t key[1] = {b / sm_disk_base<BlockSize>::get_entries_per_block()};
|
||||||
auto mindex = bitmaps_.lookup(key);
|
optional<index_entry> mindex = bitmaps_.lookup(key);
|
||||||
if (!mindex)
|
if (!mindex)
|
||||||
throw runtime_error("Couldn't lookup bitmap");
|
throw runtime_error("Couldn't lookup bitmap");
|
||||||
|
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
#include "metadata.h"
|
#include "metadata.h"
|
||||||
|
|
||||||
|
using namespace boost;
|
||||||
using namespace persistent_data;
|
using namespace persistent_data;
|
||||||
using namespace std;
|
using namespace std;
|
||||||
using namespace thin_provisioning;
|
using namespace thin_provisioning;
|
||||||
@ -10,7 +11,7 @@ namespace {
|
|||||||
int check(string const &path) {
|
int check(string const &path) {
|
||||||
metadata md(path);
|
metadata md(path);
|
||||||
|
|
||||||
auto maybe_errors = md.check();
|
optional<error_set::ptr> maybe_errors = md.check();
|
||||||
if (maybe_errors) {
|
if (maybe_errors) {
|
||||||
cerr << error_selector(*maybe_errors, 3);
|
cerr << error_selector(*maybe_errors, 3);
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -25,7 +25,7 @@ template <uint32_t BlockSize>
|
|||||||
typename transaction_manager<BlockSize>::write_ref
|
typename transaction_manager<BlockSize>::write_ref
|
||||||
transaction_manager<BlockSize>::begin(block_address superblock)
|
transaction_manager<BlockSize>::begin(block_address superblock)
|
||||||
{
|
{
|
||||||
auto wr = bm_->superblock(superblock);
|
write_ref wr = bm_->superblock(superblock);
|
||||||
wipe_shadow_table();
|
wipe_shadow_table();
|
||||||
return wr;
|
return wr;
|
||||||
}
|
}
|
||||||
@ -35,7 +35,7 @@ typename transaction_manager<BlockSize>::write_ref
|
|||||||
transaction_manager<BlockSize>::begin(block_address superblock,
|
transaction_manager<BlockSize>::begin(block_address superblock,
|
||||||
validator v)
|
validator v)
|
||||||
{
|
{
|
||||||
auto wr = bm_->superblock(superblock, v);
|
write_ref wr = bm_->superblock(superblock, v);
|
||||||
wipe_shadow_table();
|
wipe_shadow_table();
|
||||||
return wr;
|
return wr;
|
||||||
}
|
}
|
||||||
@ -89,8 +89,8 @@ transaction_manager<BlockSize>::shadow(block_address orig)
|
|||||||
!sm_->count_possibly_greater_than_one(orig))
|
!sm_->count_possibly_greater_than_one(orig))
|
||||||
return make_pair(bm_->write_lock(orig), false);
|
return make_pair(bm_->write_lock(orig), false);
|
||||||
|
|
||||||
auto src = bm_->read_lock(orig);
|
read_ref src = bm_->read_lock(orig);
|
||||||
auto dest = bm_->write_lock_zero(sm_->new_block());
|
write_ref dest = bm_->write_lock_zero(sm_->new_block());
|
||||||
::memcpy(dest.data(), src.data(), BlockSize);
|
::memcpy(dest.data(), src.data(), BlockSize);
|
||||||
|
|
||||||
ref_t count = sm_->get_count(orig);
|
ref_t count = sm_->get_count(orig);
|
||||||
@ -110,8 +110,8 @@ transaction_manager<BlockSize>::shadow(block_address orig, validator v)
|
|||||||
sm_->count_possibly_greater_than_one(orig))
|
sm_->count_possibly_greater_than_one(orig))
|
||||||
return make_pair(bm_->write_lock(orig), false);
|
return make_pair(bm_->write_lock(orig), false);
|
||||||
|
|
||||||
auto src = bm_->read_lock(orig, v);
|
read_ref src = bm_->read_lock(orig, v);
|
||||||
auto dest = bm_->write_lock_zero(sm_->new_block(), v);
|
write_ref dest = bm_->write_lock_zero(sm_->new_block(), v);
|
||||||
::memcpy(dest->data_, src->data_, BlockSize);
|
::memcpy(dest->data_, src->data_, BlockSize);
|
||||||
|
|
||||||
ref_t count = sm_->get_count(orig);
|
ref_t count = sm_->get_count(orig);
|
||||||
|
Loading…
Reference in New Issue
Block a user