[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).
This commit is contained in:
parent
930cc9d412
commit
a7c96c0e1e
@ -237,7 +237,7 @@ namespace {
|
|||||||
out << "examining mapping array" << end_message();
|
out << "examining mapping array" << end_message();
|
||||||
{
|
{
|
||||||
nested_output::nest _ = out.push();
|
nested_output::nest _ = out.push();
|
||||||
mapping_array ma(tm, mapping_array::ref_counter(), sb.mapping_root, sb.cache_blocks);
|
mapping_array ma(*tm, mapping_array::ref_counter(), sb.mapping_root, sb.cache_blocks);
|
||||||
check_mapping_array(ma, mapping_rep);
|
check_mapping_array(ma, mapping_rep);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -250,7 +250,7 @@ namespace {
|
|||||||
out << "examining hint array" << end_message();
|
out << "examining hint array" << end_message();
|
||||||
{
|
{
|
||||||
nested_output::nest _ = out.push();
|
nested_output::nest _ = out.push();
|
||||||
hint_array ha(tm, sb.policy_hint_size, sb.hint_root, sb.cache_blocks);
|
hint_array ha(*tm, sb.policy_hint_size, sb.hint_root, sb.cache_blocks);
|
||||||
ha.check(hint_rep);
|
ha.check(hint_rep);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -264,7 +264,7 @@ namespace {
|
|||||||
out << "examining discard bitset" << end_message();
|
out << "examining discard bitset" << end_message();
|
||||||
{
|
{
|
||||||
nested_output::nest _ = out.push();
|
nested_output::nest _ = out.push();
|
||||||
persistent_data::bitset discards(tm, sb.discard_root, sb.discard_nr_blocks);
|
persistent_data::bitset discards(*tm, sb.discard_root, sb.discard_nr_blocks);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -38,7 +38,7 @@ namespace {
|
|||||||
xx(4);
|
xx(4);
|
||||||
|
|
||||||
template <uint32_t WIDTH>
|
template <uint32_t WIDTH>
|
||||||
shared_ptr<array_base> mk_array(transaction_manager::ptr tm) {
|
shared_ptr<array_base> mk_array(transaction_manager &tm) {
|
||||||
typedef hint_traits<WIDTH> traits;
|
typedef hint_traits<WIDTH> traits;
|
||||||
typedef array<traits> ha;
|
typedef array<traits> ha;
|
||||||
|
|
||||||
@ -47,7 +47,7 @@ namespace {
|
|||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
shared_ptr<array_base> mk_array(transaction_manager::ptr tm, uint32_t width) {
|
shared_ptr<array_base> mk_array(transaction_manager &tm, uint32_t width) {
|
||||||
switch (width) {
|
switch (width) {
|
||||||
#define xx(n) case n: return mk_array<n>(tm)
|
#define xx(n) case n: return mk_array<n>(tm)
|
||||||
|
|
||||||
@ -76,7 +76,7 @@ namespace {
|
|||||||
//--------------------------------
|
//--------------------------------
|
||||||
|
|
||||||
template <uint32_t WIDTH>
|
template <uint32_t WIDTH>
|
||||||
shared_ptr<array_base> mk_array(transaction_manager::ptr tm, block_address root, unsigned nr_entries) {
|
shared_ptr<array_base> mk_array(transaction_manager &tm, block_address root, unsigned nr_entries) {
|
||||||
typedef hint_traits<WIDTH> traits;
|
typedef hint_traits<WIDTH> traits;
|
||||||
typedef array<traits> ha;
|
typedef array<traits> ha;
|
||||||
|
|
||||||
@ -85,7 +85,7 @@ namespace {
|
|||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
shared_ptr<array_base> mk_array(transaction_manager::ptr tm, uint32_t width, block_address root, unsigned nr_entries) {
|
shared_ptr<array_base> mk_array(transaction_manager &tm, uint32_t width, block_address root, unsigned nr_entries) {
|
||||||
switch (width) {
|
switch (width) {
|
||||||
#define xx(n) case n: return mk_array<n>(tm, root, nr_entries)
|
#define xx(n) case n: return mk_array<n>(tm, root, nr_entries)
|
||||||
all_widths
|
all_widths
|
||||||
@ -230,13 +230,13 @@ missing_hints::visit(damage_visitor &v) const
|
|||||||
|
|
||||||
//----------------------------------------------------------------
|
//----------------------------------------------------------------
|
||||||
|
|
||||||
hint_array::hint_array(tm_ptr tm, unsigned width)
|
hint_array::hint_array(transaction_manager &tm, unsigned width)
|
||||||
: width_(check_width(width)),
|
: width_(check_width(width)),
|
||||||
impl_(mk_array(tm, width))
|
impl_(mk_array(tm, width))
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
hint_array::hint_array(hint_array::tm_ptr tm, unsigned width,
|
hint_array::hint_array(transaction_manager &tm, unsigned width,
|
||||||
block_address root, unsigned nr_entries)
|
block_address root, unsigned nr_entries)
|
||||||
: width_(check_width(width)),
|
: width_(check_width(width)),
|
||||||
impl_(mk_array(tm, width, root, nr_entries))
|
impl_(mk_array(tm, width, root, nr_entries))
|
||||||
|
@ -56,10 +56,9 @@ namespace caching {
|
|||||||
class hint_array {
|
class hint_array {
|
||||||
public:
|
public:
|
||||||
typedef boost::shared_ptr<hint_array> ptr;
|
typedef boost::shared_ptr<hint_array> ptr;
|
||||||
typedef persistent_data::transaction_manager::ptr tm_ptr;
|
|
||||||
|
|
||||||
hint_array(tm_ptr tm, unsigned width);
|
hint_array(transaction_manager &tm, unsigned width);
|
||||||
hint_array(tm_ptr tm, unsigned width, block_address root, unsigned nr_entries);
|
hint_array(transaction_manager &tm, unsigned width, block_address root, unsigned nr_entries);
|
||||||
|
|
||||||
unsigned get_nr_entries() const;
|
unsigned get_nr_entries() const;
|
||||||
|
|
||||||
|
@ -61,7 +61,7 @@ metadata::setup_hint_array(size_t width)
|
|||||||
{
|
{
|
||||||
if (width > 0)
|
if (width > 0)
|
||||||
hints_ = hint_array::ptr(
|
hints_ = hint_array::ptr(
|
||||||
new hint_array(tm_, width));
|
new hint_array(*tm_, width));
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -70,16 +70,16 @@ metadata::create_metadata(block_manager<>::ptr bm)
|
|||||||
tm_ = open_tm(bm);
|
tm_ = open_tm(bm);
|
||||||
|
|
||||||
space_map::ptr core = tm_->get_sm();
|
space_map::ptr core = tm_->get_sm();
|
||||||
metadata_sm_ = create_metadata_sm(tm_, tm_->get_bm()->get_nr_blocks());
|
metadata_sm_ = create_metadata_sm(*tm_, tm_->get_bm()->get_nr_blocks());
|
||||||
copy_space_maps(metadata_sm_, core);
|
copy_space_maps(metadata_sm_, core);
|
||||||
tm_->set_sm(metadata_sm_);
|
tm_->set_sm(metadata_sm_);
|
||||||
|
|
||||||
mappings_ = mapping_array::ptr(new mapping_array(tm_, mapping_array::ref_counter()));
|
mappings_ = mapping_array::ptr(new mapping_array(*tm_, mapping_array::ref_counter()));
|
||||||
|
|
||||||
// We can't instantiate the hint array yet, since we don't know the
|
// We can't instantiate the hint array yet, since we don't know the
|
||||||
// hint width.
|
// hint width.
|
||||||
|
|
||||||
discard_bits_ = persistent_data::bitset::ptr(new persistent_data::bitset(tm_));
|
discard_bits_ = persistent_data::bitset::ptr(new persistent_data::bitset(*tm_));
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -89,19 +89,19 @@ metadata::open_metadata(block_manager<>::ptr bm)
|
|||||||
sb_ = read_superblock(tm_->get_bm());
|
sb_ = read_superblock(tm_->get_bm());
|
||||||
|
|
||||||
mappings_ = mapping_array::ptr(
|
mappings_ = mapping_array::ptr(
|
||||||
new mapping_array(tm_,
|
new mapping_array(*tm_,
|
||||||
mapping_array::ref_counter(),
|
mapping_array::ref_counter(),
|
||||||
sb_.mapping_root,
|
sb_.mapping_root,
|
||||||
sb_.cache_blocks));
|
sb_.cache_blocks));
|
||||||
|
|
||||||
if (sb_.hint_root)
|
if (sb_.hint_root)
|
||||||
hints_ = hint_array::ptr(
|
hints_ = hint_array::ptr(
|
||||||
new hint_array(tm_, sb_.policy_hint_size,
|
new hint_array(*tm_, sb_.policy_hint_size,
|
||||||
sb_.hint_root, sb_.cache_blocks));
|
sb_.hint_root, sb_.cache_blocks));
|
||||||
|
|
||||||
if (sb_.discard_root)
|
if (sb_.discard_root)
|
||||||
discard_bits_ = persistent_data::bitset::ptr(
|
discard_bits_ = persistent_data::bitset::ptr(
|
||||||
new persistent_data::bitset(tm_, sb_.discard_root, sb_.discard_nr_blocks));
|
new persistent_data::bitset(*tm_, sb_.discard_root, sb_.discard_nr_blocks));
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -217,14 +217,14 @@ namespace {
|
|||||||
writeset_tree_reporter wt_rep(out);
|
writeset_tree_reporter wt_rep(out);
|
||||||
{
|
{
|
||||||
era_detail_traits::ref_counter rc(tm);
|
era_detail_traits::ref_counter rc(tm);
|
||||||
writeset_tree wt(tm, sb.writeset_tree_root, rc);
|
writeset_tree wt(*tm, sb.writeset_tree_root, rc);
|
||||||
check_writeset_tree(tm, wt, wt_rep);
|
check_writeset_tree(tm, wt, wt_rep);
|
||||||
}
|
}
|
||||||
|
|
||||||
era_array_reporter ea_rep(out);
|
era_array_reporter ea_rep(out);
|
||||||
{
|
{
|
||||||
uint32_traits::ref_counter rc;
|
uint32_traits::ref_counter rc;
|
||||||
era_array ea(tm, rc, sb.era_array_root, sb.nr_blocks);
|
era_array ea(*tm, rc, sb.era_array_root, sb.nr_blocks);
|
||||||
check_era_array(ea, sb.current_era, ea_rep);
|
check_era_array(ea, sb.current_era, ea_rep);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -51,12 +51,12 @@ metadata::create_metadata(block_manager<>::ptr bm)
|
|||||||
tm_ = open_tm(bm);
|
tm_ = open_tm(bm);
|
||||||
|
|
||||||
space_map::ptr core = tm_->get_sm();
|
space_map::ptr core = tm_->get_sm();
|
||||||
metadata_sm_ = create_metadata_sm(tm_, tm_->get_bm()->get_nr_blocks());
|
metadata_sm_ = create_metadata_sm(*tm_, tm_->get_bm()->get_nr_blocks());
|
||||||
copy_space_maps(metadata_sm_, core);
|
copy_space_maps(metadata_sm_, core);
|
||||||
tm_->set_sm(metadata_sm_);
|
tm_->set_sm(metadata_sm_);
|
||||||
|
|
||||||
writeset_tree_ = writeset_tree::ptr(new writeset_tree(tm_, era_detail_traits::ref_counter(tm_)));
|
writeset_tree_ = writeset_tree::ptr(new writeset_tree(*tm_, era_detail_traits::ref_counter(tm_)));
|
||||||
era_array_ = era_array::ptr(new era_array(tm_,
|
era_array_ = era_array::ptr(new era_array(*tm_,
|
||||||
uint32_traits::ref_counter()));
|
uint32_traits::ref_counter()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -66,11 +66,11 @@ metadata::open_metadata(block_manager<>::ptr bm, block_address loc)
|
|||||||
tm_ = open_tm(bm);
|
tm_ = open_tm(bm);
|
||||||
sb_ = read_superblock(tm_->get_bm(), loc);
|
sb_ = read_superblock(tm_->get_bm(), loc);
|
||||||
|
|
||||||
writeset_tree_ = writeset_tree::ptr(new writeset_tree(tm_,
|
writeset_tree_ = writeset_tree::ptr(new writeset_tree(*tm_,
|
||||||
sb_.writeset_tree_root,
|
sb_.writeset_tree_root,
|
||||||
era_detail_traits::ref_counter(tm_)));
|
era_detail_traits::ref_counter(tm_)));
|
||||||
|
|
||||||
era_array_ = era_array::ptr(new era_array(tm_,
|
era_array_ = era_array::ptr(new era_array(*tm_,
|
||||||
uint32_traits::ref_counter(),
|
uint32_traits::ref_counter(),
|
||||||
sb_.era_array_root,
|
sb_.era_array_root,
|
||||||
sb_.nr_blocks));
|
sb_.nr_blocks));
|
||||||
|
@ -52,7 +52,7 @@ namespace {
|
|||||||
in_writeset_ = true;
|
in_writeset_ = true;
|
||||||
era_ = era;
|
era_ = era;
|
||||||
|
|
||||||
bits_.reset(new bitset(md_.tm_));
|
bits_.reset(new bitset(*md_.tm_));
|
||||||
bits_->grow(nr_bits, false);
|
bits_->grow(nr_bits, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -54,7 +54,7 @@ namespace {
|
|||||||
|
|
||||||
void visit(btree_path const &path, era_detail const &era) {
|
void visit(btree_path const &path, era_detail const &era) {
|
||||||
era_ = path[0];
|
era_ = path[0];
|
||||||
persistent_data::bitset bs(tm_, era.writeset_root, era.nr_bits);
|
persistent_data::bitset bs(*tm_, era.writeset_root, era.nr_bits);
|
||||||
writeset_v_.writeset_begin(era_, era.nr_bits);
|
writeset_v_.writeset_begin(era_, era.nr_bits);
|
||||||
bs.walk_bitset(*this);
|
bs.walk_bitset(*this);
|
||||||
writeset_v_.writeset_end();
|
writeset_v_.writeset_end();
|
||||||
|
@ -172,7 +172,7 @@ namespace persistent_data {
|
|||||||
unsigned visit_array_block(ValueVisitor &vv,
|
unsigned visit_array_block(ValueVisitor &vv,
|
||||||
btree_path const &p,
|
btree_path const &p,
|
||||||
typename block_traits::value_type const &v) const {
|
typename block_traits::value_type const &v) const {
|
||||||
rblock rb(tm_->read_lock(v, validator_), rc_);
|
rblock rb(tm_.read_lock(v, validator_), rc_);
|
||||||
|
|
||||||
for (uint32_t i = 0; i < rb.nr_entries(); i++)
|
for (uint32_t i = 0; i < rb.nr_entries(); i++)
|
||||||
vv.visit(p[0] * rb.max_entries() + i, rb.get(i));
|
vv.visit(p[0] * rb.max_entries() + i, rb.get(i));
|
||||||
@ -207,8 +207,6 @@ namespace persistent_data {
|
|||||||
unsigned entries_per_block_;
|
unsigned entries_per_block_;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef typename persistent_data::transaction_manager::ptr tm_ptr;
|
|
||||||
|
|
||||||
typedef block_manager<>::write_ref write_ref;
|
typedef block_manager<>::write_ref write_ref;
|
||||||
typedef block_manager<>::read_ref read_ref;
|
typedef block_manager<>::read_ref read_ref;
|
||||||
|
|
||||||
@ -219,23 +217,23 @@ namespace persistent_data {
|
|||||||
typedef typename ValueTraits::value_type value_type;
|
typedef typename ValueTraits::value_type value_type;
|
||||||
typedef typename ValueTraits::ref_counter ref_counter;
|
typedef typename ValueTraits::ref_counter ref_counter;
|
||||||
|
|
||||||
array(tm_ptr tm, ref_counter rc)
|
array(transaction_manager &tm, ref_counter rc)
|
||||||
: tm_(tm),
|
: tm_(tm),
|
||||||
entries_per_block_(rblock::calc_max_entries()),
|
entries_per_block_(rblock::calc_max_entries()),
|
||||||
nr_entries_(0),
|
nr_entries_(0),
|
||||||
block_rc_(tm->get_sm(), *this),
|
block_rc_(tm.get_sm(), *this),
|
||||||
block_tree_(tm, block_rc_),
|
block_tree_(tm, block_rc_),
|
||||||
rc_(rc),
|
rc_(rc),
|
||||||
validator_(new array_detail::array_block_validator) {
|
validator_(new array_detail::array_block_validator) {
|
||||||
}
|
}
|
||||||
|
|
||||||
array(tm_ptr tm, ref_counter rc,
|
array(transaction_manager &tm, ref_counter rc,
|
||||||
block_address root,
|
block_address root,
|
||||||
unsigned nr_entries)
|
unsigned nr_entries)
|
||||||
: tm_(tm),
|
: tm_(tm),
|
||||||
entries_per_block_(rblock::calc_max_entries()),
|
entries_per_block_(rblock::calc_max_entries()),
|
||||||
nr_entries_(nr_entries),
|
nr_entries_(nr_entries),
|
||||||
block_rc_(tm->get_sm(), *this),
|
block_rc_(tm.get_sm(), *this),
|
||||||
block_tree_(tm, root, block_rc_),
|
block_tree_(tm, root, block_rc_),
|
||||||
rc_(rc),
|
rc_(rc),
|
||||||
validator_(new array_detail::array_block_validator) {
|
validator_(new array_detail::array_block_validator) {
|
||||||
@ -393,7 +391,7 @@ namespace persistent_data {
|
|||||||
|
|
||||||
wblock new_ablock(unsigned ablock_index) {
|
wblock new_ablock(unsigned ablock_index) {
|
||||||
uint64_t key[1] = {ablock_index};
|
uint64_t key[1] = {ablock_index};
|
||||||
write_ref b = tm_->new_block(validator_);
|
write_ref b = tm_.new_block(validator_);
|
||||||
block_address location = b.get_location();
|
block_address location = b.get_location();
|
||||||
|
|
||||||
wblock wb(b, rc_);
|
wblock wb(b, rc_);
|
||||||
@ -404,13 +402,13 @@ namespace persistent_data {
|
|||||||
|
|
||||||
rblock get_ablock(unsigned ablock_index) const {
|
rblock get_ablock(unsigned ablock_index) const {
|
||||||
block_address addr = lookup_block_address(ablock_index);
|
block_address addr = lookup_block_address(ablock_index);
|
||||||
return rblock(tm_->read_lock(addr, validator_), rc_);
|
return rblock(tm_.read_lock(addr, validator_), rc_);
|
||||||
}
|
}
|
||||||
|
|
||||||
wblock shadow_ablock(unsigned ablock_index) {
|
wblock shadow_ablock(unsigned ablock_index) {
|
||||||
uint64_t key[1] = {ablock_index};
|
uint64_t key[1] = {ablock_index};
|
||||||
block_address addr = lookup_block_address(ablock_index);
|
block_address addr = lookup_block_address(ablock_index);
|
||||||
std::pair<write_ref, bool> p = tm_->shadow(addr, validator_);
|
std::pair<write_ref, bool> p = tm_.shadow(addr, validator_);
|
||||||
wblock wb = wblock(p.first, rc_);
|
wblock wb = wblock(p.first, rc_);
|
||||||
|
|
||||||
if (p.second)
|
if (p.second)
|
||||||
@ -422,11 +420,11 @@ namespace persistent_data {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void dec_ablock_entries(block_address addr) {
|
void dec_ablock_entries(block_address addr) {
|
||||||
rblock b(tm_->read_lock(addr, validator_), rc_);
|
rblock b(tm_.read_lock(addr, validator_), rc_);
|
||||||
b.dec_all_entries();
|
b.dec_all_entries();
|
||||||
}
|
}
|
||||||
|
|
||||||
tm_ptr tm_;
|
transaction_manager &tm_;
|
||||||
unsigned entries_per_block_;
|
unsigned entries_per_block_;
|
||||||
unsigned nr_entries_;
|
unsigned nr_entries_;
|
||||||
block_ref_counter block_rc_;
|
block_ref_counter block_rc_;
|
||||||
|
@ -33,12 +33,12 @@ namespace persistent_data {
|
|||||||
typedef boost::shared_ptr<bitset_impl> ptr;
|
typedef boost::shared_ptr<bitset_impl> ptr;
|
||||||
typedef persistent_data::transaction_manager::ptr tm_ptr;
|
typedef persistent_data::transaction_manager::ptr tm_ptr;
|
||||||
|
|
||||||
bitset_impl(tm_ptr tm)
|
bitset_impl(transaction_manager &tm)
|
||||||
: nr_bits_(0),
|
: nr_bits_(0),
|
||||||
array_(tm, rc_) {
|
array_(tm, rc_) {
|
||||||
}
|
}
|
||||||
|
|
||||||
bitset_impl(tm_ptr tm, block_address root, unsigned nr_bits)
|
bitset_impl(transaction_manager &tm, block_address root, unsigned nr_bits)
|
||||||
: nr_bits_(nr_bits),
|
: nr_bits_(nr_bits),
|
||||||
array_(tm, rc_, root, nr_bits / BITS_PER_ULL) {
|
array_(tm, rc_, root, nr_bits / BITS_PER_ULL) {
|
||||||
}
|
}
|
||||||
@ -203,12 +203,12 @@ namespace persistent_data {
|
|||||||
|
|
||||||
//----------------------------------------------------------------
|
//----------------------------------------------------------------
|
||||||
|
|
||||||
persistent_data::bitset::bitset(tm_ptr tm)
|
persistent_data::bitset::bitset(transaction_manager &tm)
|
||||||
: impl_(new bitset_impl(tm))
|
: impl_(new bitset_impl(tm))
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
persistent_data::bitset::bitset(tm_ptr tm, block_address root, unsigned nr_bits)
|
persistent_data::bitset::bitset(transaction_manager &tm, block_address root, unsigned nr_bits)
|
||||||
: impl_(new bitset_impl(tm, root, nr_bits))
|
: impl_(new bitset_impl(tm, root, nr_bits))
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
@ -49,10 +49,10 @@ namespace persistent_data {
|
|||||||
class bitset {
|
class bitset {
|
||||||
public:
|
public:
|
||||||
typedef boost::shared_ptr<bitset> ptr;
|
typedef boost::shared_ptr<bitset> ptr;
|
||||||
typedef persistent_data::transaction_manager::ptr tm_ptr;
|
|
||||||
|
|
||||||
bitset(tm_ptr tm);
|
bitset(transaction_manager &tm);
|
||||||
bitset(tm_ptr tm, block_address root, unsigned nr_bits);
|
bitset(transaction_manager &tm,
|
||||||
|
block_address root, unsigned nr_bits);
|
||||||
block_address get_root() const;
|
block_address get_root() const;
|
||||||
unsigned get_nr_bits() const;
|
unsigned get_nr_bits() const;
|
||||||
void grow(unsigned new_nr_bits, bool default_value);
|
void grow(unsigned new_nr_bits, bool default_value);
|
||||||
|
@ -34,7 +34,7 @@ namespace {
|
|||||||
|
|
||||||
//----------------------------------------------------------------
|
//----------------------------------------------------------------
|
||||||
|
|
||||||
bloom_filter::bloom_filter(tm_ptr tm,
|
bloom_filter::bloom_filter(transaction_manager &tm,
|
||||||
unsigned nr_bits, unsigned nr_probes)
|
unsigned nr_bits, unsigned nr_probes)
|
||||||
: tm_(tm),
|
: tm_(tm),
|
||||||
bits_(tm),
|
bits_(tm),
|
||||||
@ -45,7 +45,7 @@ bloom_filter::bloom_filter(tm_ptr tm,
|
|||||||
bits_.grow(nr_bits, false);
|
bits_.grow(nr_bits, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
bloom_filter::bloom_filter(tm_ptr tm, block_address root,
|
bloom_filter::bloom_filter(transaction_manager &tm, block_address root,
|
||||||
unsigned nr_bits, unsigned nr_probes)
|
unsigned nr_bits, unsigned nr_probes)
|
||||||
: tm_(tm),
|
: tm_(tm),
|
||||||
bits_(tm, root, nr_bits),
|
bits_(tm, root, nr_bits),
|
||||||
|
@ -12,13 +12,12 @@ namespace persistent_data {
|
|||||||
class bloom_filter {
|
class bloom_filter {
|
||||||
public:
|
public:
|
||||||
typedef boost::shared_ptr<bloom_filter> ptr;
|
typedef boost::shared_ptr<bloom_filter> ptr;
|
||||||
typedef persistent_data::transaction_manager::ptr tm_ptr;
|
|
||||||
|
|
||||||
// nr_bits must be a power of two
|
// nr_bits must be a power of two
|
||||||
bloom_filter(tm_ptr tm,
|
bloom_filter(transaction_manager &tm,
|
||||||
unsigned nr_bits, unsigned nr_probes);
|
unsigned nr_bits, unsigned nr_probes);
|
||||||
|
|
||||||
bloom_filter(tm_ptr tm, block_address root,
|
bloom_filter(transaction_manager &tm, block_address root,
|
||||||
unsigned nr_bits_power, unsigned nr_probes);
|
unsigned nr_bits_power, unsigned nr_probes);
|
||||||
|
|
||||||
block_address get_root() const;
|
block_address get_root() const;
|
||||||
@ -34,7 +33,7 @@ namespace persistent_data {
|
|||||||
|
|
||||||
void fill_probes(block_address b, vector<unsigned> &probes) const;
|
void fill_probes(block_address b, vector<unsigned> &probes) const;
|
||||||
|
|
||||||
tm_ptr tm_;
|
transaction_manager &tm_;
|
||||||
persistent_data::bitset bits_;
|
persistent_data::bitset bits_;
|
||||||
unsigned nr_probes_;
|
unsigned nr_probes_;
|
||||||
uint64_t mask_;
|
uint64_t mask_;
|
||||||
|
@ -198,7 +198,7 @@ namespace persistent_data {
|
|||||||
|
|
||||||
class ro_spine : private boost::noncopyable {
|
class ro_spine : private boost::noncopyable {
|
||||||
public:
|
public:
|
||||||
ro_spine(transaction_manager::ptr tm,
|
ro_spine(transaction_manager &tm,
|
||||||
bcache::validator::ptr v)
|
bcache::validator::ptr v)
|
||||||
: tm_(tm),
|
: tm_(tm),
|
||||||
validator_(v) {
|
validator_(v) {
|
||||||
@ -212,7 +212,7 @@ namespace persistent_data {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
transaction_manager::ptr tm_;
|
transaction_manager &tm_;
|
||||||
bcache::validator::ptr validator_;
|
bcache::validator::ptr validator_;
|
||||||
std::list<block_manager<>::read_ref> spine_;
|
std::list<block_manager<>::read_ref> spine_;
|
||||||
};
|
};
|
||||||
@ -223,7 +223,7 @@ namespace persistent_data {
|
|||||||
typedef transaction_manager::write_ref write_ref;
|
typedef transaction_manager::write_ref write_ref;
|
||||||
typedef boost::optional<block_address> maybe_block;
|
typedef boost::optional<block_address> maybe_block;
|
||||||
|
|
||||||
shadow_spine(transaction_manager::ptr tm,
|
shadow_spine(transaction_manager &tm,
|
||||||
bcache::validator::ptr v)
|
bcache::validator::ptr v)
|
||||||
|
|
||||||
: tm_(tm),
|
: tm_(tm),
|
||||||
@ -276,7 +276,7 @@ namespace persistent_data {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
transaction_manager::ptr tm_;
|
transaction_manager &tm_;
|
||||||
bcache::validator::ptr validator_;
|
bcache::validator::ptr validator_;
|
||||||
std::list<block_manager<>::write_ref> spine_;
|
std::list<block_manager<>::write_ref> spine_;
|
||||||
maybe_block root_;
|
maybe_block root_;
|
||||||
@ -335,10 +335,10 @@ namespace persistent_data {
|
|||||||
typedef typename btree_detail::node_ref<ValueTraits> leaf_node;
|
typedef typename btree_detail::node_ref<ValueTraits> leaf_node;
|
||||||
typedef typename btree_detail::node_ref<block_traits> internal_node;
|
typedef typename btree_detail::node_ref<block_traits> internal_node;
|
||||||
|
|
||||||
btree(typename persistent_data::transaction_manager::ptr tm,
|
btree(transaction_manager &tm,
|
||||||
typename ValueTraits::ref_counter rc);
|
typename ValueTraits::ref_counter rc);
|
||||||
|
|
||||||
btree(typename transaction_manager::ptr tm,
|
btree(transaction_manager &tm,
|
||||||
block_address root,
|
block_address root,
|
||||||
typename ValueTraits::ref_counter rc);
|
typename ValueTraits::ref_counter rc);
|
||||||
|
|
||||||
@ -434,7 +434,7 @@ namespace persistent_data {
|
|||||||
void inc_children(btree_detail::shadow_spine &spine,
|
void inc_children(btree_detail::shadow_spine &spine,
|
||||||
RefCounter &leaf_rc);
|
RefCounter &leaf_rc);
|
||||||
|
|
||||||
typename persistent_data::transaction_manager::ptr tm_;
|
transaction_manager &tm_;
|
||||||
bool destroy_;
|
bool destroy_;
|
||||||
block_address root_;
|
block_address root_;
|
||||||
block_ref_counter internal_rc_;
|
block_ref_counter internal_rc_;
|
||||||
|
@ -64,7 +64,7 @@ namespace persistent_data {
|
|||||||
inline void
|
inline void
|
||||||
ro_spine::step(block_address b)
|
ro_spine::step(block_address b)
|
||||||
{
|
{
|
||||||
spine_.push_back(tm_->read_lock(b, validator_));
|
spine_.push_back(tm_.read_lock(b, validator_));
|
||||||
if (spine_.size() > 2)
|
if (spine_.size() > 2)
|
||||||
spine_.pop_front();
|
spine_.pop_front();
|
||||||
}
|
}
|
||||||
@ -72,11 +72,11 @@ namespace persistent_data {
|
|||||||
inline bool
|
inline bool
|
||||||
shadow_spine::step(block_address b)
|
shadow_spine::step(block_address b)
|
||||||
{
|
{
|
||||||
pair<write_ref, bool> p = tm_->shadow(b, validator_);
|
pair<write_ref, bool> p = tm_.shadow(b, validator_);
|
||||||
try {
|
try {
|
||||||
step(p.first);
|
step(p.first);
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
tm_->get_sm()->dec(p.first.get_location());
|
tm_.get_sm()->dec(p.first.get_location());
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
return p.second;
|
return p.second;
|
||||||
@ -392,17 +392,17 @@ namespace persistent_data {
|
|||||||
|
|
||||||
template <unsigned Levels, typename ValueTraits>
|
template <unsigned Levels, typename ValueTraits>
|
||||||
btree<Levels, ValueTraits>::
|
btree<Levels, ValueTraits>::
|
||||||
btree(typename transaction_manager::ptr tm,
|
btree(transaction_manager &tm,
|
||||||
typename ValueTraits::ref_counter rc)
|
typename ValueTraits::ref_counter rc)
|
||||||
: tm_(tm),
|
: tm_(tm),
|
||||||
destroy_(false),
|
destroy_(false),
|
||||||
internal_rc_(tm->get_sm()),
|
internal_rc_(tm.get_sm()),
|
||||||
rc_(rc),
|
rc_(rc),
|
||||||
validator_(new btree_node_validator)
|
validator_(new btree_node_validator)
|
||||||
{
|
{
|
||||||
using namespace btree_detail;
|
using namespace btree_detail;
|
||||||
|
|
||||||
write_ref root = tm_->new_block(validator_);
|
write_ref root = tm_.new_block(validator_);
|
||||||
|
|
||||||
if (Levels > 1) {
|
if (Levels > 1) {
|
||||||
internal_node n = to_node<block_traits>(root);
|
internal_node n = to_node<block_traits>(root);
|
||||||
@ -424,13 +424,13 @@ namespace persistent_data {
|
|||||||
|
|
||||||
template <unsigned Levels, typename ValueTraits>
|
template <unsigned Levels, typename ValueTraits>
|
||||||
btree<Levels, ValueTraits>::
|
btree<Levels, ValueTraits>::
|
||||||
btree(typename transaction_manager::ptr tm,
|
btree(transaction_manager &tm,
|
||||||
block_address root,
|
block_address root,
|
||||||
typename ValueTraits::ref_counter rc)
|
typename ValueTraits::ref_counter rc)
|
||||||
: tm_(tm),
|
: tm_(tm),
|
||||||
destroy_(false),
|
destroy_(false),
|
||||||
root_(root),
|
root_(root),
|
||||||
internal_rc_(tm->get_sm()),
|
internal_rc_(tm.get_sm()),
|
||||||
rc_(rc),
|
rc_(rc),
|
||||||
validator_(new btree_node_validator)
|
validator_(new btree_node_validator)
|
||||||
{
|
{
|
||||||
@ -559,7 +559,7 @@ namespace persistent_data {
|
|||||||
typename btree<Levels, ValueTraits>::ptr
|
typename btree<Levels, ValueTraits>::ptr
|
||||||
btree<Levels, ValueTraits>::clone() const
|
btree<Levels, ValueTraits>::clone() const
|
||||||
{
|
{
|
||||||
tm_->get_sm()->inc(root_);
|
tm_.get_sm()->inc(root_);
|
||||||
return ptr(new btree<Levels, ValueTraits>(tm_, root_, rc_));
|
return ptr(new btree<Levels, ValueTraits>(tm_, root_, rc_));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -635,13 +635,13 @@ namespace persistent_data {
|
|||||||
node_type type;
|
node_type type;
|
||||||
unsigned nr_left, nr_right;
|
unsigned nr_left, nr_right;
|
||||||
|
|
||||||
write_ref left = tm_->new_block(validator_);
|
write_ref left = tm_.new_block(validator_);
|
||||||
node_ref<ValueTraits> l = to_node<ValueTraits>(left);
|
node_ref<ValueTraits> l = to_node<ValueTraits>(left);
|
||||||
l.set_nr_entries(0);
|
l.set_nr_entries(0);
|
||||||
l.set_max_entries();
|
l.set_max_entries();
|
||||||
l.set_value_size(sizeof(typename ValueTraits::disk_type));
|
l.set_value_size(sizeof(typename ValueTraits::disk_type));
|
||||||
|
|
||||||
write_ref right = tm_->new_block(validator_);
|
write_ref right = tm_.new_block(validator_);
|
||||||
node_ref<ValueTraits> r = to_node<ValueTraits>(right);
|
node_ref<ValueTraits> r = to_node<ValueTraits>(right);
|
||||||
r.set_nr_entries(0);
|
r.set_nr_entries(0);
|
||||||
r.set_max_entries();
|
r.set_max_entries();
|
||||||
@ -695,7 +695,7 @@ namespace persistent_data {
|
|||||||
node_ref<ValueTraits> l = spine.template get_node<ValueTraits>();
|
node_ref<ValueTraits> l = spine.template get_node<ValueTraits>();
|
||||||
block_address left = spine.get_block();
|
block_address left = spine.get_block();
|
||||||
|
|
||||||
write_ref right = tm_->new_block(validator_);
|
write_ref right = tm_.new_block(validator_);
|
||||||
node_ref<ValueTraits> r = to_node<ValueTraits>(right);
|
node_ref<ValueTraits> r = to_node<ValueTraits>(right);
|
||||||
|
|
||||||
unsigned nr_left = l.get_nr_entries() / 2;
|
unsigned nr_left = l.get_nr_entries() / 2;
|
||||||
@ -822,14 +822,14 @@ namespace persistent_data {
|
|||||||
{
|
{
|
||||||
using namespace btree_detail;
|
using namespace btree_detail;
|
||||||
|
|
||||||
read_ref blk = tm_->read_lock(b, validator_);
|
read_ref blk = tm_.read_lock(b, validator_);
|
||||||
internal_node o = to_node<block_traits>(blk);
|
internal_node o = to_node<block_traits>(blk);
|
||||||
|
|
||||||
// FIXME: use a switch statement
|
// FIXME: use a switch statement
|
||||||
if (o.get_type() == INTERNAL) {
|
if (o.get_type() == INTERNAL) {
|
||||||
if (v.visit_internal(loc, o)) {
|
if (v.visit_internal(loc, o)) {
|
||||||
for (unsigned i = 0; i < o.get_nr_entries(); i++)
|
for (unsigned i = 0; i < o.get_nr_entries(); i++)
|
||||||
tm_->prefetch(o.value_at(i));
|
tm_.prefetch(o.value_at(i));
|
||||||
|
|
||||||
for (unsigned i = 0; i < o.get_nr_entries(); i++) {
|
for (unsigned i = 0; i < o.get_nr_entries(); i++) {
|
||||||
node_location loc2(loc);
|
node_location loc2(loc);
|
||||||
|
@ -98,7 +98,7 @@ namespace {
|
|||||||
typedef transaction_manager::read_ref read_ref;
|
typedef transaction_manager::read_ref read_ref;
|
||||||
typedef transaction_manager::write_ref write_ref;
|
typedef transaction_manager::write_ref write_ref;
|
||||||
|
|
||||||
bitmap(transaction_manager::ptr tm,
|
bitmap(transaction_manager &tm,
|
||||||
index_entry const &ie,
|
index_entry const &ie,
|
||||||
bcache::validator::ptr v)
|
bcache::validator::ptr v)
|
||||||
: tm_(tm),
|
: tm_(tm),
|
||||||
@ -107,7 +107,7 @@ namespace {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ref_t lookup(unsigned b) const {
|
ref_t lookup(unsigned b) const {
|
||||||
read_ref rr = tm_->read_lock(ie_.blocknr_, validator_);
|
read_ref rr = tm_.read_lock(ie_.blocknr_, validator_);
|
||||||
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);
|
||||||
@ -117,7 +117,7 @@ namespace {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void insert(unsigned b, ref_t n) {
|
void insert(unsigned b, ref_t n) {
|
||||||
write_ref wr = tm_->shadow(ie_.blocknr_, validator_).first;
|
write_ref wr = tm_.shadow(ie_.blocknr_, validator_).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)
|
||||||
@ -158,7 +158,7 @@ namespace {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void iterate(block_address offset, block_address hi, space_map::iterator &it) const {
|
void iterate(block_address offset, block_address hi, space_map::iterator &it) const {
|
||||||
read_ref rr = tm_->read_lock(ie_.blocknr_, validator_);
|
read_ref rr = tm_.read_lock(ie_.blocknr_, validator_);
|
||||||
void const *bits = bitmap_data(rr);
|
void const *bits = bitmap_data(rr);
|
||||||
|
|
||||||
for (unsigned b = 0; b < hi; b++) {
|
for (unsigned b = 0; b < hi; b++) {
|
||||||
@ -181,7 +181,7 @@ namespace {
|
|||||||
return h + 1;
|
return h + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
transaction_manager::ptr tm_;
|
transaction_manager &tm_;
|
||||||
bcache::validator::ptr validator_;
|
bcache::validator::ptr validator_;
|
||||||
|
|
||||||
index_entry ie_;
|
index_entry ie_;
|
||||||
@ -241,7 +241,7 @@ namespace {
|
|||||||
typedef transaction_manager::write_ref write_ref;
|
typedef transaction_manager::write_ref write_ref;
|
||||||
|
|
||||||
sm_disk(index_store::ptr indexes,
|
sm_disk(index_store::ptr indexes,
|
||||||
transaction_manager::ptr tm)
|
transaction_manager &tm)
|
||||||
: tm_(tm),
|
: tm_(tm),
|
||||||
bitmap_validator_(new bitmap_block_validator),
|
bitmap_validator_(new bitmap_block_validator),
|
||||||
indexes_(indexes),
|
indexes_(indexes),
|
||||||
@ -251,7 +251,7 @@ namespace {
|
|||||||
}
|
}
|
||||||
|
|
||||||
sm_disk(index_store::ptr indexes,
|
sm_disk(index_store::ptr indexes,
|
||||||
transaction_manager::ptr tm,
|
transaction_manager &tm,
|
||||||
sm_root const &root)
|
sm_root const &root)
|
||||||
: tm_(tm),
|
: tm_(tm),
|
||||||
bitmap_validator_(new bitmap_block_validator),
|
bitmap_validator_(new bitmap_block_validator),
|
||||||
@ -354,7 +354,7 @@ namespace {
|
|||||||
|
|
||||||
indexes_->resize(bitmap_count);
|
indexes_->resize(bitmap_count);
|
||||||
for (block_address i = old_bitmap_count; i < bitmap_count; i++) {
|
for (block_address i = old_bitmap_count; i < bitmap_count; i++) {
|
||||||
write_ref wr = tm_->new_block(bitmap_validator_);
|
write_ref wr = tm_.new_block(bitmap_validator_);
|
||||||
|
|
||||||
index_entry ie;
|
index_entry ie;
|
||||||
ie.blocknr_ = wr.get_location();
|
ie.blocknr_ = wr.get_location();
|
||||||
@ -437,7 +437,7 @@ namespace {
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
transaction_manager::ptr get_tm() const {
|
transaction_manager &get_tm() const {
|
||||||
return tm_;
|
return tm_;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -501,7 +501,7 @@ namespace {
|
|||||||
ref_counts_.remove(key);
|
ref_counts_.remove(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
transaction_manager::ptr tm_;
|
transaction_manager &tm_;
|
||||||
bcache::validator::ptr bitmap_validator_;
|
bcache::validator::ptr bitmap_validator_;
|
||||||
index_store::ptr indexes_;
|
index_store::ptr indexes_;
|
||||||
block_address nr_blocks_;
|
block_address nr_blocks_;
|
||||||
@ -544,12 +544,12 @@ namespace {
|
|||||||
public:
|
public:
|
||||||
typedef boost::shared_ptr<btree_index_store> ptr;
|
typedef boost::shared_ptr<btree_index_store> ptr;
|
||||||
|
|
||||||
btree_index_store(transaction_manager::ptr tm)
|
btree_index_store(transaction_manager &tm)
|
||||||
: tm_(tm),
|
: tm_(tm),
|
||||||
bitmaps_(tm, index_entry_traits::ref_counter()) {
|
bitmaps_(tm, index_entry_traits::ref_counter()) {
|
||||||
}
|
}
|
||||||
|
|
||||||
btree_index_store(transaction_manager::ptr tm,
|
btree_index_store(transaction_manager &tm,
|
||||||
block_address root)
|
block_address root)
|
||||||
: tm_(tm),
|
: tm_(tm),
|
||||||
bitmaps_(tm, root, index_entry_traits::ref_counter()) {
|
bitmaps_(tm, root, index_entry_traits::ref_counter()) {
|
||||||
@ -592,7 +592,7 @@ namespace {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
transaction_manager::ptr tm_;
|
transaction_manager &tm_;
|
||||||
btree<1, index_entry_traits> bitmaps_;
|
btree<1, index_entry_traits> bitmaps_;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -600,13 +600,13 @@ namespace {
|
|||||||
public:
|
public:
|
||||||
typedef boost::shared_ptr<metadata_index_store> ptr;
|
typedef boost::shared_ptr<metadata_index_store> ptr;
|
||||||
|
|
||||||
metadata_index_store(transaction_manager::ptr tm)
|
metadata_index_store(transaction_manager &tm)
|
||||||
: tm_(tm) {
|
: tm_(tm) {
|
||||||
block_manager<>::write_ref wr = tm_->new_block(index_validator());
|
block_manager<>::write_ref wr = tm_.new_block(index_validator());
|
||||||
bitmap_root_ = wr.get_location();
|
bitmap_root_ = wr.get_location();
|
||||||
}
|
}
|
||||||
|
|
||||||
metadata_index_store(transaction_manager::ptr tm, block_address root, block_address nr_indexes)
|
metadata_index_store(transaction_manager &tm, block_address root, block_address nr_indexes)
|
||||||
: tm_(tm),
|
: tm_(tm),
|
||||||
bitmap_root_(root) {
|
bitmap_root_(root) {
|
||||||
resize(nr_indexes);
|
resize(nr_indexes);
|
||||||
@ -627,7 +627,7 @@ namespace {
|
|||||||
|
|
||||||
virtual void commit_ies() {
|
virtual void commit_ies() {
|
||||||
std::pair<block_manager<>::write_ref, bool> p =
|
std::pair<block_manager<>::write_ref, bool> p =
|
||||||
tm_->shadow(bitmap_root_, index_validator());
|
tm_.shadow(bitmap_root_, index_validator());
|
||||||
|
|
||||||
bitmap_root_ = p.first.get_location();
|
bitmap_root_ = p.first.get_location();
|
||||||
metadata_index *mdi = reinterpret_cast<metadata_index *>(p.first.data());
|
metadata_index *mdi = reinterpret_cast<metadata_index *>(p.first.data());
|
||||||
@ -661,14 +661,14 @@ namespace {
|
|||||||
private:
|
private:
|
||||||
void load_ies() {
|
void load_ies() {
|
||||||
block_manager<>::read_ref rr =
|
block_manager<>::read_ref rr =
|
||||||
tm_->read_lock(bitmap_root_, index_validator());
|
tm_.read_lock(bitmap_root_, index_validator());
|
||||||
|
|
||||||
metadata_index const *mdi = reinterpret_cast<metadata_index const *>(rr.data());
|
metadata_index const *mdi = reinterpret_cast<metadata_index const *>(rr.data());
|
||||||
for (unsigned i = 0; i < entries_.size(); i++)
|
for (unsigned i = 0; i < entries_.size(); i++)
|
||||||
index_entry_traits::unpack(*(mdi->index + i), entries_[i]);
|
index_entry_traits::unpack(*(mdi->index + i), entries_[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
transaction_manager::ptr tm_;
|
transaction_manager &tm_;
|
||||||
block_address bitmap_root_;
|
block_address bitmap_root_;
|
||||||
std::vector<index_entry> entries_;
|
std::vector<index_entry> entries_;
|
||||||
};
|
};
|
||||||
@ -677,7 +677,7 @@ namespace {
|
|||||||
//----------------------------------------------------------------
|
//----------------------------------------------------------------
|
||||||
|
|
||||||
checked_space_map::ptr
|
checked_space_map::ptr
|
||||||
persistent_data::create_disk_sm(transaction_manager::ptr tm,
|
persistent_data::create_disk_sm(transaction_manager &tm,
|
||||||
block_address nr_blocks)
|
block_address nr_blocks)
|
||||||
{
|
{
|
||||||
index_store::ptr store(new btree_index_store(tm));
|
index_store::ptr store(new btree_index_store(tm));
|
||||||
@ -688,7 +688,7 @@ persistent_data::create_disk_sm(transaction_manager::ptr tm,
|
|||||||
}
|
}
|
||||||
|
|
||||||
checked_space_map::ptr
|
checked_space_map::ptr
|
||||||
persistent_data::open_disk_sm(transaction_manager::ptr tm, void *root)
|
persistent_data::open_disk_sm(transaction_manager &tm, void *root)
|
||||||
{
|
{
|
||||||
sm_root_disk d;
|
sm_root_disk d;
|
||||||
sm_root v;
|
sm_root v;
|
||||||
@ -700,7 +700,7 @@ persistent_data::open_disk_sm(transaction_manager::ptr tm, void *root)
|
|||||||
}
|
}
|
||||||
|
|
||||||
checked_space_map::ptr
|
checked_space_map::ptr
|
||||||
persistent_data::create_metadata_sm(transaction_manager::ptr tm, block_address nr_blocks)
|
persistent_data::create_metadata_sm(transaction_manager &tm, block_address nr_blocks)
|
||||||
{
|
{
|
||||||
index_store::ptr store(new metadata_index_store(tm));
|
index_store::ptr store(new metadata_index_store(tm));
|
||||||
checked_space_map::ptr sm(new sm_disk(store, tm));
|
checked_space_map::ptr sm(new sm_disk(store, tm));
|
||||||
@ -711,7 +711,7 @@ persistent_data::create_metadata_sm(transaction_manager::ptr tm, block_address n
|
|||||||
}
|
}
|
||||||
|
|
||||||
checked_space_map::ptr
|
checked_space_map::ptr
|
||||||
persistent_data::open_metadata_sm(transaction_manager::ptr tm, void *root)
|
persistent_data::open_metadata_sm(transaction_manager &tm, void *root)
|
||||||
{
|
{
|
||||||
sm_root_disk d;
|
sm_root_disk d;
|
||||||
sm_root v;
|
sm_root v;
|
||||||
|
@ -26,16 +26,16 @@
|
|||||||
|
|
||||||
namespace persistent_data {
|
namespace persistent_data {
|
||||||
checked_space_map::ptr
|
checked_space_map::ptr
|
||||||
create_disk_sm(transaction_manager::ptr tm, block_address nr_blocks);
|
create_disk_sm(transaction_manager &tm, block_address nr_blocks);
|
||||||
|
|
||||||
checked_space_map::ptr
|
checked_space_map::ptr
|
||||||
open_disk_sm(transaction_manager::ptr tm, void *root);
|
open_disk_sm(transaction_manager &tm, void *root);
|
||||||
|
|
||||||
checked_space_map::ptr
|
checked_space_map::ptr
|
||||||
create_metadata_sm(transaction_manager::ptr tm, block_address nr_blocks);
|
create_metadata_sm(transaction_manager &tm, block_address nr_blocks);
|
||||||
|
|
||||||
checked_space_map::ptr
|
checked_space_map::ptr
|
||||||
open_metadata_sm(transaction_manager::ptr tm, void *root);
|
open_metadata_sm(transaction_manager &tm, void *root);
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------
|
//----------------------------------------------------------------
|
||||||
|
@ -71,36 +71,36 @@ metadata::metadata(std::string const &dev_path, open_type ot,
|
|||||||
if (sb_.version_ != 1)
|
if (sb_.version_ != 1)
|
||||||
throw runtime_error("unknown metadata version");
|
throw runtime_error("unknown metadata version");
|
||||||
|
|
||||||
metadata_sm_ = open_metadata_sm(tm_, &sb_.metadata_space_map_root_);
|
metadata_sm_ = open_metadata_sm(*tm_, &sb_.metadata_space_map_root_);
|
||||||
tm_->set_sm(metadata_sm_);
|
tm_->set_sm(metadata_sm_);
|
||||||
|
|
||||||
data_sm_ = open_disk_sm(tm_, static_cast<void *>(&sb_.data_space_map_root_));
|
data_sm_ = open_disk_sm(*tm_, static_cast<void *>(&sb_.data_space_map_root_));
|
||||||
|
|
||||||
details_ = device_tree::ptr(
|
details_ = device_tree::ptr(
|
||||||
new device_tree(tm_, sb_.device_details_root_,
|
new device_tree(*tm_, sb_.device_details_root_,
|
||||||
device_tree_detail::device_details_traits::ref_counter()));
|
device_tree_detail::device_details_traits::ref_counter()));
|
||||||
|
|
||||||
mappings_top_level_ = dev_tree::ptr(
|
mappings_top_level_ = dev_tree::ptr(
|
||||||
new dev_tree(tm_, sb_.data_mapping_root_,
|
new dev_tree(*tm_, sb_.data_mapping_root_,
|
||||||
mapping_tree_detail::mtree_ref_counter(tm_)));
|
mapping_tree_detail::mtree_ref_counter(tm_)));
|
||||||
|
|
||||||
mappings_ = mapping_tree::ptr(
|
mappings_ = mapping_tree::ptr(
|
||||||
new mapping_tree(tm_, sb_.data_mapping_root_,
|
new mapping_tree(*tm_, sb_.data_mapping_root_,
|
||||||
mapping_tree_detail::block_time_ref_counter(data_sm_)));
|
mapping_tree_detail::block_time_ref_counter(data_sm_)));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CREATE:
|
case CREATE:
|
||||||
tm_ = open_tm(open_bm(dev_path, block_manager<>::READ_WRITE));
|
tm_ = open_tm(open_bm(dev_path, block_manager<>::READ_WRITE));
|
||||||
space_map::ptr core = tm_->get_sm();
|
space_map::ptr core = tm_->get_sm();
|
||||||
metadata_sm_ = create_metadata_sm(tm_, tm_->get_bm()->get_nr_blocks());
|
metadata_sm_ = create_metadata_sm(*tm_, tm_->get_bm()->get_nr_blocks());
|
||||||
copy_space_maps(metadata_sm_, core);
|
copy_space_maps(metadata_sm_, core);
|
||||||
tm_->set_sm(metadata_sm_);
|
tm_->set_sm(metadata_sm_);
|
||||||
|
|
||||||
data_sm_ = create_disk_sm(tm_, nr_data_blocks);
|
data_sm_ = create_disk_sm(*tm_, nr_data_blocks);
|
||||||
details_ = device_tree::ptr(new device_tree(tm_, device_tree_detail::device_details_traits::ref_counter()));
|
details_ = device_tree::ptr(new device_tree(*tm_, device_tree_detail::device_details_traits::ref_counter()));
|
||||||
mappings_ = mapping_tree::ptr(new mapping_tree(tm_,
|
mappings_ = mapping_tree::ptr(new mapping_tree(*tm_,
|
||||||
mapping_tree_detail::block_time_ref_counter(data_sm_)));
|
mapping_tree_detail::block_time_ref_counter(data_sm_)));
|
||||||
mappings_top_level_ = dev_tree::ptr(new dev_tree(tm_, mappings_->get_root(),
|
mappings_top_level_ = dev_tree::ptr(new dev_tree(*tm_, mappings_->get_root(),
|
||||||
mapping_tree_detail::mtree_ref_counter(tm_)));
|
mapping_tree_detail::mtree_ref_counter(tm_)));
|
||||||
|
|
||||||
::memset(&sb_, 0, sizeof(sb_));
|
::memset(&sb_, 0, sizeof(sb_));
|
||||||
@ -125,11 +125,11 @@ metadata::metadata(std::string const &dev_path, block_address metadata_snap)
|
|||||||
//metadata_sm_ = open_metadata_sm(tm_, &sb_.metadata_space_map_root_);
|
//metadata_sm_ = open_metadata_sm(tm_, &sb_.metadata_space_map_root_);
|
||||||
//tm_->set_sm(metadata_sm_);
|
//tm_->set_sm(metadata_sm_);
|
||||||
|
|
||||||
data_sm_ = open_disk_sm(tm_, static_cast<void *>(&sb_.data_space_map_root_));
|
data_sm_ = open_disk_sm(*tm_, static_cast<void *>(&sb_.data_space_map_root_));
|
||||||
details_ = device_tree::ptr(new device_tree(tm_, sb_.device_details_root_, device_tree_detail::device_details_traits::ref_counter()));
|
details_ = device_tree::ptr(new device_tree(*tm_, sb_.device_details_root_, device_tree_detail::device_details_traits::ref_counter()));
|
||||||
mappings_top_level_ = dev_tree::ptr(new dev_tree(tm_, sb_.data_mapping_root_,
|
mappings_top_level_ = dev_tree::ptr(new dev_tree(*tm_, sb_.data_mapping_root_,
|
||||||
mapping_tree_detail::mtree_ref_counter(tm_)));
|
mapping_tree_detail::mtree_ref_counter(tm_)));
|
||||||
mappings_ = mapping_tree::ptr(new mapping_tree(tm_, sb_.data_mapping_root_,
|
mappings_ = mapping_tree::ptr(new mapping_tree(*tm_, sb_.data_mapping_root_,
|
||||||
mapping_tree_detail::block_time_ref_counter(data_sm_)));
|
mapping_tree_detail::block_time_ref_counter(data_sm_)));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -146,29 +146,29 @@ metadata::metadata(block_manager<>::ptr bm, open_type ot,
|
|||||||
if (sb_.version_ != 1)
|
if (sb_.version_ != 1)
|
||||||
throw runtime_error("unknown metadata version");
|
throw runtime_error("unknown metadata version");
|
||||||
|
|
||||||
metadata_sm_ = open_metadata_sm(tm_, &sb_.metadata_space_map_root_);
|
metadata_sm_ = open_metadata_sm(*tm_, &sb_.metadata_space_map_root_);
|
||||||
tm_->set_sm(metadata_sm_);
|
tm_->set_sm(metadata_sm_);
|
||||||
|
|
||||||
data_sm_ = open_disk_sm(tm_, static_cast<void *>(&sb_.data_space_map_root_));
|
data_sm_ = open_disk_sm(*tm_, static_cast<void *>(&sb_.data_space_map_root_));
|
||||||
details_ = device_tree::ptr(new device_tree(tm_, sb_.device_details_root_, device_tree_detail::device_details_traits::ref_counter()));
|
details_ = device_tree::ptr(new device_tree(*tm_, sb_.device_details_root_, device_tree_detail::device_details_traits::ref_counter()));
|
||||||
mappings_top_level_ = dev_tree::ptr(new dev_tree(tm_, sb_.data_mapping_root_,
|
mappings_top_level_ = dev_tree::ptr(new dev_tree(*tm_, sb_.data_mapping_root_,
|
||||||
mapping_tree_detail::mtree_ref_counter(tm_)));
|
mapping_tree_detail::mtree_ref_counter(tm_)));
|
||||||
mappings_ = mapping_tree::ptr(new mapping_tree(tm_, sb_.data_mapping_root_,
|
mappings_ = mapping_tree::ptr(new mapping_tree(*tm_, sb_.data_mapping_root_,
|
||||||
mapping_tree_detail::block_time_ref_counter(data_sm_)));
|
mapping_tree_detail::block_time_ref_counter(data_sm_)));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CREATE:
|
case CREATE:
|
||||||
tm_ = open_tm(bm);
|
tm_ = open_tm(bm);
|
||||||
space_map::ptr core = tm_->get_sm();
|
space_map::ptr core = tm_->get_sm();
|
||||||
metadata_sm_ = create_metadata_sm(tm_, tm_->get_bm()->get_nr_blocks());
|
metadata_sm_ = create_metadata_sm(*tm_, tm_->get_bm()->get_nr_blocks());
|
||||||
copy_space_maps(metadata_sm_, core);
|
copy_space_maps(metadata_sm_, core);
|
||||||
tm_->set_sm(metadata_sm_);
|
tm_->set_sm(metadata_sm_);
|
||||||
|
|
||||||
data_sm_ = create_disk_sm(tm_, nr_data_blocks);
|
data_sm_ = create_disk_sm(*tm_, nr_data_blocks);
|
||||||
details_ = device_tree::ptr(new device_tree(tm_, device_tree_detail::device_details_traits::ref_counter()));
|
details_ = device_tree::ptr(new device_tree(*tm_, device_tree_detail::device_details_traits::ref_counter()));
|
||||||
mappings_ = mapping_tree::ptr(new mapping_tree(tm_,
|
mappings_ = mapping_tree::ptr(new mapping_tree(*tm_,
|
||||||
mapping_tree_detail::block_time_ref_counter(data_sm_)));
|
mapping_tree_detail::block_time_ref_counter(data_sm_)));
|
||||||
mappings_top_level_ = dev_tree::ptr(new dev_tree(tm_, mappings_->get_root(),
|
mappings_top_level_ = dev_tree::ptr(new dev_tree(*tm_, mappings_->get_root(),
|
||||||
mapping_tree_detail::mtree_ref_counter(tm_)));
|
mapping_tree_detail::mtree_ref_counter(tm_)));
|
||||||
|
|
||||||
::memset(&sb_, 0, sizeof(sb_));
|
::memset(&sb_, 0, sizeof(sb_));
|
||||||
|
@ -200,7 +200,7 @@ namespace {
|
|||||||
private:
|
private:
|
||||||
void emit_mappings(block_address subtree_root) {
|
void emit_mappings(block_address subtree_root) {
|
||||||
mapping_emitter me(e_);
|
mapping_emitter me(e_);
|
||||||
single_mapping_tree tree(md_->tm_, subtree_root,
|
single_mapping_tree tree(*md_->tm_, subtree_root,
|
||||||
mapping_tree_detail::block_time_ref_counter(md_->data_sm_));
|
mapping_tree_detail::block_time_ref_counter(md_->data_sm_));
|
||||||
walk_mapping_tree(tree, static_cast<mapping_tree_detail::mapping_visitor &>(me), *damage_policy_);
|
walk_mapping_tree(tree, static_cast<mapping_tree_detail::mapping_visitor &>(me), *damage_policy_);
|
||||||
}
|
}
|
||||||
|
@ -134,7 +134,7 @@ namespace {
|
|||||||
private:
|
private:
|
||||||
single_mapping_tree::ptr new_mapping_tree() {
|
single_mapping_tree::ptr new_mapping_tree() {
|
||||||
return single_mapping_tree::ptr(
|
return single_mapping_tree::ptr(
|
||||||
new single_mapping_tree(md_->tm_,
|
new single_mapping_tree(*md_->tm_,
|
||||||
mapping_tree_detail::block_time_ref_counter(md_->data_sm_)));
|
mapping_tree_detail::block_time_ref_counter(md_->data_sm_)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -194,7 +194,7 @@ namespace {
|
|||||||
out << "examining devices tree" << end_message();
|
out << "examining devices tree" << end_message();
|
||||||
{
|
{
|
||||||
nested_output::nest _ = out.push();
|
nested_output::nest _ = out.push();
|
||||||
device_tree dtree(tm, sb.device_details_root_,
|
device_tree dtree(*tm, sb.device_details_root_,
|
||||||
device_tree_detail::device_details_traits::ref_counter());
|
device_tree_detail::device_details_traits::ref_counter());
|
||||||
check_device_tree(dtree, dev_rep);
|
check_device_tree(dtree, dev_rep);
|
||||||
}
|
}
|
||||||
@ -204,7 +204,7 @@ namespace {
|
|||||||
out << "examining top level of mapping tree" << end_message();
|
out << "examining top level of mapping tree" << end_message();
|
||||||
{
|
{
|
||||||
nested_output::nest _ = out.push();
|
nested_output::nest _ = out.push();
|
||||||
dev_tree dtree(tm, sb.data_mapping_root_,
|
dev_tree dtree(*tm, sb.data_mapping_root_,
|
||||||
mapping_tree_detail::mtree_traits::ref_counter(tm));
|
mapping_tree_detail::mtree_traits::ref_counter(tm));
|
||||||
check_mapping_tree(dtree, mapping_rep);
|
check_mapping_tree(dtree, mapping_rep);
|
||||||
}
|
}
|
||||||
@ -213,7 +213,7 @@ namespace {
|
|||||||
out << "examining mapping tree" << end_message();
|
out << "examining mapping tree" << end_message();
|
||||||
{
|
{
|
||||||
nested_output::nest _ = out.push();
|
nested_output::nest _ = out.push();
|
||||||
mapping_tree mtree(tm, sb.data_mapping_root_,
|
mapping_tree mtree(*tm, sb.data_mapping_root_,
|
||||||
mapping_tree_detail::block_traits::ref_counter(tm->get_sm()));
|
mapping_tree_detail::block_traits::ref_counter(tm->get_sm()));
|
||||||
check_mapping_tree(mtree, mapping_rep);
|
check_mapping_tree(mtree, mapping_rep);
|
||||||
}
|
}
|
||||||
|
@ -450,7 +450,7 @@ namespace {
|
|||||||
|
|
||||||
superblock_detail::superblock sb = read_superblock(bm);
|
superblock_detail::superblock sb = read_superblock(bm);
|
||||||
|
|
||||||
dev_tree dtree(tm, sb.data_mapping_root_,
|
dev_tree dtree(*tm, sb.data_mapping_root_,
|
||||||
mapping_tree_detail::mtree_traits::ref_counter(tm));
|
mapping_tree_detail::mtree_traits::ref_counter(tm));
|
||||||
|
|
||||||
dev_tree::key k = {*fs.snap1};
|
dev_tree::key k = {*fs.snap1};
|
||||||
@ -462,7 +462,7 @@ namespace {
|
|||||||
app.die(out.str());
|
app.die(out.str());
|
||||||
}
|
}
|
||||||
|
|
||||||
single_mapping_tree snap1(tm, *snap1_root, mapping_tree_detail::block_traits::ref_counter(tm->get_sm()));
|
single_mapping_tree snap1(*tm, *snap1_root, mapping_tree_detail::block_traits::ref_counter(tm->get_sm()));
|
||||||
|
|
||||||
k[0] = *fs.snap2;
|
k[0] = *fs.snap2;
|
||||||
boost::optional<uint64_t> snap2_root = dtree.lookup(k);
|
boost::optional<uint64_t> snap2_root = dtree.lookup(k);
|
||||||
@ -473,7 +473,7 @@ namespace {
|
|||||||
app.die(out.str());
|
app.die(out.str());
|
||||||
}
|
}
|
||||||
|
|
||||||
single_mapping_tree snap2(tm, *snap2_root, mapping_tree_detail::block_traits::ref_counter(tm->get_sm()));
|
single_mapping_tree snap2(*tm, *snap2_root, mapping_tree_detail::block_traits::ref_counter(tm->get_sm()));
|
||||||
btree_visit_values(snap1, mr1, damage_v);
|
btree_visit_values(snap1, mr1, damage_v);
|
||||||
btree_visit_values(snap2, mr2, damage_v);
|
btree_visit_values(snap2, mr2, damage_v);
|
||||||
}
|
}
|
||||||
|
@ -122,7 +122,7 @@ thin_pool::create_thin(thin_dev_t dev)
|
|||||||
if (device_exists(dev))
|
if (device_exists(dev))
|
||||||
throw std::runtime_error("Device already exists");
|
throw std::runtime_error("Device already exists");
|
||||||
|
|
||||||
single_mapping_tree::ptr new_tree(new single_mapping_tree(md_->tm_,
|
single_mapping_tree::ptr new_tree(new single_mapping_tree(*md_->tm_,
|
||||||
mapping_tree_detail::block_time_ref_counter(md_->data_sm_)));
|
mapping_tree_detail::block_time_ref_counter(md_->data_sm_)));
|
||||||
md_->mappings_top_level_->insert(key, new_tree->get_root());
|
md_->mappings_top_level_->insert(key, new_tree->get_root());
|
||||||
md_->mappings_->set_root(md_->mappings_top_level_->get_root()); // FIXME: ugly
|
md_->mappings_->set_root(md_->mappings_top_level_->get_root()); // FIXME: ugly
|
||||||
@ -140,7 +140,7 @@ thin_pool::create_snap(thin_dev_t dev, thin_dev_t origin)
|
|||||||
if (!mtree_root)
|
if (!mtree_root)
|
||||||
throw std::runtime_error("unknown origin");
|
throw std::runtime_error("unknown origin");
|
||||||
|
|
||||||
single_mapping_tree otree(md_->tm_, *mtree_root,
|
single_mapping_tree otree(*md_->tm_, *mtree_root,
|
||||||
mapping_tree_detail::block_time_ref_counter(md_->data_sm_));
|
mapping_tree_detail::block_time_ref_counter(md_->data_sm_));
|
||||||
|
|
||||||
single_mapping_tree::ptr clone(otree.clone());
|
single_mapping_tree::ptr clone(otree.clone());
|
||||||
|
@ -75,7 +75,7 @@ namespace {
|
|||||||
transaction_manager::ptr tm = open_tm(bm);
|
transaction_manager::ptr tm = open_tm(bm);
|
||||||
|
|
||||||
superblock_detail::superblock sb = read_superblock(bm);
|
superblock_detail::superblock sb = read_superblock(bm);
|
||||||
mapping_tree mtree(tm, sb.data_mapping_root_,
|
mapping_tree mtree(*tm, sb.data_mapping_root_,
|
||||||
mapping_tree_detail::block_traits::ref_counter(tm->get_sm()));
|
mapping_tree_detail::block_traits::ref_counter(tm->get_sm()));
|
||||||
|
|
||||||
btree_visit_values(mtree, rv, dv);
|
btree_visit_values(mtree, rv, dv);
|
||||||
|
@ -37,7 +37,9 @@ namespace {
|
|||||||
class ArrayTests : public Test {
|
class ArrayTests : public Test {
|
||||||
public:
|
public:
|
||||||
ArrayTests()
|
ArrayTests()
|
||||||
: tm_(create_tm()) {
|
: bm_(new block_manager<>("./test.data", NR_BLOCKS, 4, block_manager<>::READ_WRITE)),
|
||||||
|
sm_(new core_map(NR_BLOCKS)),
|
||||||
|
tm_(bm_, sm_) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -76,15 +78,9 @@ namespace {
|
|||||||
array64::ptr a_;
|
array64::ptr a_;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static transaction_manager::ptr
|
block_manager<>::ptr bm_;
|
||||||
create_tm() {
|
space_map::ptr sm_;
|
||||||
block_manager<>::ptr bm(new block_manager<>("./test.data", NR_BLOCKS, 4, block_manager<>::READ_WRITE));
|
transaction_manager tm_;
|
||||||
space_map::ptr sm(new core_map(NR_BLOCKS));
|
|
||||||
transaction_manager::ptr tm(new transaction_manager(bm, sm));
|
|
||||||
return tm;
|
|
||||||
}
|
|
||||||
|
|
||||||
transaction_manager::ptr tm_;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class value_visitor {
|
class value_visitor {
|
||||||
|
@ -32,34 +32,40 @@ using namespace testing;
|
|||||||
namespace {
|
namespace {
|
||||||
block_address const NR_BLOCKS = 102400;
|
block_address const NR_BLOCKS = 102400;
|
||||||
|
|
||||||
transaction_manager::ptr
|
class BitsetTests : public Test {
|
||||||
create_tm() {
|
public:
|
||||||
block_manager<>::ptr bm(new block_manager<>("./test.data", NR_BLOCKS, 4, block_manager<>::READ_WRITE));
|
BitsetTests()
|
||||||
space_map::ptr sm(new core_map(NR_BLOCKS));
|
: bm_(new block_manager<>("./test.data", NR_BLOCKS, 4, block_manager<>::READ_WRITE)),
|
||||||
transaction_manager::ptr tm(new transaction_manager(bm, sm));
|
sm_(new core_map(NR_BLOCKS)),
|
||||||
return tm;
|
tm_(bm_, sm_) {
|
||||||
}
|
}
|
||||||
|
|
||||||
bitset::ptr
|
bitset::ptr
|
||||||
create_bitset() {
|
create_bitset() {
|
||||||
return bitset::ptr(new bitset(create_tm()));
|
return bitset::ptr(new bitset(tm_));
|
||||||
}
|
}
|
||||||
|
|
||||||
bitset::ptr
|
bitset::ptr
|
||||||
open_bitset(block_address root, unsigned count) {
|
open_bitset(block_address root, unsigned count) {
|
||||||
return bitset::ptr(new bitset(create_tm(), root, count));
|
return bitset::ptr(new bitset(tm_, root, count));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
block_manager<>::ptr bm_;
|
||||||
|
space_map::ptr sm_;
|
||||||
|
transaction_manager tm_;
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------
|
//----------------------------------------------------------------
|
||||||
|
|
||||||
TEST(BitsetTests, create_empty_bitset)
|
TEST_F(BitsetTests, create_empty_bitset)
|
||||||
{
|
{
|
||||||
bitset::ptr bs = create_bitset();
|
bitset::ptr bs = create_bitset();
|
||||||
ASSERT_THROW(bs->get(0), runtime_error);
|
ASSERT_THROW(bs->get(0), runtime_error);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(BitsetTests, grow_default_false)
|
TEST_F(BitsetTests, grow_default_false)
|
||||||
{
|
{
|
||||||
unsigned const COUNT = 100000;
|
unsigned const COUNT = 100000;
|
||||||
|
|
||||||
@ -70,7 +76,7 @@ TEST(BitsetTests, grow_default_false)
|
|||||||
ASSERT_FALSE(bs->get(i));
|
ASSERT_FALSE(bs->get(i));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(BitsetTests, grow_default_true)
|
TEST_F(BitsetTests, grow_default_true)
|
||||||
{
|
{
|
||||||
unsigned const COUNT = 100000;
|
unsigned const COUNT = 100000;
|
||||||
|
|
||||||
@ -81,7 +87,7 @@ TEST(BitsetTests, grow_default_true)
|
|||||||
ASSERT_TRUE(bs->get(i));
|
ASSERT_TRUE(bs->get(i));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(BitsetTests, grow_throws_if_actualy_asked_to_shrink)
|
TEST_F(BitsetTests, grow_throws_if_actualy_asked_to_shrink)
|
||||||
{
|
{
|
||||||
unsigned const COUNT = 100000;
|
unsigned const COUNT = 100000;
|
||||||
|
|
||||||
@ -90,7 +96,7 @@ TEST(BitsetTests, grow_throws_if_actualy_asked_to_shrink)
|
|||||||
ASSERT_THROW(bs->grow(COUNT / 2, false), runtime_error);
|
ASSERT_THROW(bs->grow(COUNT / 2, false), runtime_error);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(BitsetTests, multiple_grow_calls)
|
TEST_F(BitsetTests, multiple_grow_calls)
|
||||||
{
|
{
|
||||||
unsigned const COUNT = 100000;
|
unsigned const COUNT = 100000;
|
||||||
unsigned const STEP = 37;
|
unsigned const STEP = 37;
|
||||||
@ -121,7 +127,7 @@ TEST(BitsetTests, multiple_grow_calls)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(BitsetTests, set_out_of_bounds_throws)
|
TEST_F(BitsetTests, set_out_of_bounds_throws)
|
||||||
{
|
{
|
||||||
unsigned const COUNT = 100000;
|
unsigned const COUNT = 100000;
|
||||||
bitset::ptr bs = create_bitset();
|
bitset::ptr bs = create_bitset();
|
||||||
@ -131,7 +137,7 @@ TEST(BitsetTests, set_out_of_bounds_throws)
|
|||||||
ASSERT_THROW(bs->set(COUNT, true), runtime_error);
|
ASSERT_THROW(bs->set(COUNT, true), runtime_error);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(BitsetTests, set_works)
|
TEST_F(BitsetTests, set_works)
|
||||||
{
|
{
|
||||||
unsigned const COUNT = 100000;
|
unsigned const COUNT = 100000;
|
||||||
bitset::ptr bs = create_bitset();
|
bitset::ptr bs = create_bitset();
|
||||||
@ -144,7 +150,7 @@ TEST(BitsetTests, set_works)
|
|||||||
ASSERT_THAT(bs->get(i), Eq(i % 7 ? true : false));
|
ASSERT_THAT(bs->get(i), Eq(i % 7 ? true : false));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(BitsetTests, reopen_works)
|
TEST_F(BitsetTests, reopen_works)
|
||||||
{
|
{
|
||||||
unsigned const COUNT = 100000;
|
unsigned const COUNT = 100000;
|
||||||
block_address root;
|
block_address root;
|
||||||
|
@ -31,7 +31,7 @@ namespace {
|
|||||||
BloomFilterTests()
|
BloomFilterTests()
|
||||||
: bm_(create_bm<BLOCK_SIZE>(NR_BLOCKS)),
|
: bm_(create_bm<BLOCK_SIZE>(NR_BLOCKS)),
|
||||||
sm_(setup_core_map()),
|
sm_(setup_core_map()),
|
||||||
tm_(new transaction_manager(bm_, sm_)) {
|
tm_(bm_, sm_) {
|
||||||
}
|
}
|
||||||
|
|
||||||
set<block_address> generate_random_blocks(unsigned count,
|
set<block_address> generate_random_blocks(unsigned count,
|
||||||
@ -73,7 +73,7 @@ namespace {
|
|||||||
with_temp_directory dir_;
|
with_temp_directory dir_;
|
||||||
block_manager<>::ptr bm_;
|
block_manager<>::ptr bm_;
|
||||||
space_map::ptr sm_;
|
space_map::ptr sm_;
|
||||||
transaction_manager::ptr tm_;
|
transaction_manager tm_;
|
||||||
|
|
||||||
boost::random::mt19937 rng_;
|
boost::random::mt19937 rng_;
|
||||||
};
|
};
|
||||||
|
@ -25,7 +25,7 @@ namespace {
|
|||||||
BTreeCounterTests()
|
BTreeCounterTests()
|
||||||
: bm_(create_bm<BLOCK_SIZE>(NR_BLOCKS)),
|
: bm_(create_bm<BLOCK_SIZE>(NR_BLOCKS)),
|
||||||
sm_(setup_core_map()),
|
sm_(setup_core_map()),
|
||||||
tm_(new transaction_manager(bm_, sm_)) {
|
tm_(bm_, sm_) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void check_nr_metadata_blocks_is_ge(unsigned n) {
|
void check_nr_metadata_blocks_is_ge(unsigned n) {
|
||||||
@ -38,7 +38,7 @@ namespace {
|
|||||||
with_temp_directory dir_;
|
with_temp_directory dir_;
|
||||||
block_manager<>::ptr bm_;
|
block_manager<>::ptr bm_;
|
||||||
space_map::ptr sm_;
|
space_map::ptr sm_;
|
||||||
transaction_manager::ptr tm_;
|
transaction_manager tm_;
|
||||||
uint64_traits::ref_counter rc_;
|
uint64_traits::ref_counter rc_;
|
||||||
|
|
||||||
btree<1, uint64_traits>::ptr tree_;
|
btree<1, uint64_traits>::ptr tree_;
|
||||||
|
@ -281,7 +281,7 @@ namespace {
|
|||||||
DamageTests()
|
DamageTests()
|
||||||
: bm_(create_bm<BLOCK_SIZE>(NR_BLOCKS)),
|
: bm_(create_bm<BLOCK_SIZE>(NR_BLOCKS)),
|
||||||
sm_(setup_core_map()),
|
sm_(setup_core_map()),
|
||||||
tm_(new transaction_manager(bm_, sm_)) {
|
tm_(bm_, sm_) {
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual ~DamageTests() {}
|
virtual ~DamageTests() {}
|
||||||
@ -315,7 +315,7 @@ namespace {
|
|||||||
with_temp_directory dir_;
|
with_temp_directory dir_;
|
||||||
block_manager<>::ptr bm_;
|
block_manager<>::ptr bm_;
|
||||||
space_map::ptr sm_;
|
space_map::ptr sm_;
|
||||||
transaction_manager::ptr tm_;
|
transaction_manager tm_;
|
||||||
thing_traits::ref_counter rc_;
|
thing_traits::ref_counter rc_;
|
||||||
|
|
||||||
boost::optional<btree_layout> layout_;
|
boost::optional<btree_layout> layout_;
|
||||||
|
@ -31,21 +31,28 @@ using namespace testing;
|
|||||||
namespace {
|
namespace {
|
||||||
block_address const NR_BLOCKS = 102400;
|
block_address const NR_BLOCKS = 102400;
|
||||||
|
|
||||||
transaction_manager::ptr
|
class BtreeTests : public Test {
|
||||||
create_tm() {
|
public:
|
||||||
block_manager<>::ptr bm(new block_manager<>("./test.data", NR_BLOCKS, 4, block_manager<>::READ_WRITE));
|
BtreeTests()
|
||||||
space_map::ptr sm(new core_map(NR_BLOCKS));
|
: bm_(new block_manager<>("./test.data", NR_BLOCKS, 4, block_manager<>::READ_WRITE)),
|
||||||
transaction_manager::ptr tm(new transaction_manager(bm, sm));
|
sm_(new core_map(NR_BLOCKS)),
|
||||||
return tm;
|
tm_(bm_, sm_) {
|
||||||
}
|
}
|
||||||
|
|
||||||
btree<1, uint64_traits>::ptr
|
btree<1, uint64_traits>::ptr
|
||||||
create_btree() {
|
create_btree() {
|
||||||
uint64_traits::ref_counter rc;
|
uint64_traits::ref_counter rc;
|
||||||
|
|
||||||
|
return btree<1, uint64_traits>::ptr(
|
||||||
|
new btree<1, uint64_traits>(tm_, rc));
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
block_manager<>::ptr bm_;
|
||||||
|
space_map::ptr sm_;
|
||||||
|
transaction_manager tm_;
|
||||||
|
};
|
||||||
|
|
||||||
return btree<1, uint64_traits>::ptr(
|
|
||||||
new btree<1, uint64_traits>(create_tm(), rc));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Checks that a btree is well formed.
|
// Checks that a btree is well formed.
|
||||||
//
|
//
|
||||||
@ -99,7 +106,7 @@ namespace {
|
|||||||
|
|
||||||
//----------------------------------------------------------------
|
//----------------------------------------------------------------
|
||||||
|
|
||||||
TEST(BtreeTests, empty_btree_contains_nothing)
|
TEST_F(BtreeTests, empty_btree_contains_nothing)
|
||||||
{
|
{
|
||||||
btree<1, uint64_traits>::ptr tree = create_btree();
|
btree<1, uint64_traits>::ptr tree = create_btree();
|
||||||
check_constraints(tree);
|
check_constraints(tree);
|
||||||
@ -110,7 +117,7 @@ TEST(BtreeTests, empty_btree_contains_nothing)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(BtreeTests, insert_works)
|
TEST_F(BtreeTests, insert_works)
|
||||||
{
|
{
|
||||||
unsigned const COUNT = 100000;
|
unsigned const COUNT = 100000;
|
||||||
|
|
||||||
@ -129,7 +136,7 @@ TEST(BtreeTests, insert_works)
|
|||||||
check_constraints(tree);
|
check_constraints(tree);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(BtreeTests, insert_does_not_insert_imaginary_values)
|
TEST_F(BtreeTests, insert_does_not_insert_imaginary_values)
|
||||||
{
|
{
|
||||||
btree<1, uint64_traits>::ptr tree = create_btree();
|
btree<1, uint64_traits>::ptr tree = create_btree();
|
||||||
uint64_t key[1] = {0};
|
uint64_t key[1] = {0};
|
||||||
@ -156,7 +163,7 @@ TEST(BtreeTests, insert_does_not_insert_imaginary_values)
|
|||||||
check_constraints(tree);
|
check_constraints(tree);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(BtreeTests, clone)
|
TEST_F(BtreeTests, clone)
|
||||||
{
|
{
|
||||||
typedef btree<1, uint64_traits> tree64;
|
typedef btree<1, uint64_traits> tree64;
|
||||||
|
|
||||||
|
@ -33,278 +33,258 @@ namespace {
|
|||||||
block_address const SUPERBLOCK = 0;
|
block_address const SUPERBLOCK = 0;
|
||||||
block_address const MAX_LOCKS = 8;
|
block_address const MAX_LOCKS = 8;
|
||||||
|
|
||||||
transaction_manager::ptr
|
class SpaceMapTests : public Test {
|
||||||
create_tm() {
|
public:
|
||||||
block_manager<>::ptr bm(
|
SpaceMapTests()
|
||||||
new block_manager<>("./test.data", NR_BLOCKS, MAX_LOCKS, block_manager<>::READ_WRITE));
|
: bm_(new block_manager<>("./test.data", NR_BLOCKS, MAX_LOCKS, block_manager<>::READ_WRITE)),
|
||||||
space_map::ptr sm(new core_map(NR_BLOCKS));
|
sm_(new core_map(NR_BLOCKS)),
|
||||||
transaction_manager::ptr tm(
|
tm_(bm_, sm_) {
|
||||||
new transaction_manager(bm, sm));
|
|
||||||
return tm;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct sm_core_creator {
|
|
||||||
static space_map::ptr
|
|
||||||
create() {
|
|
||||||
return space_map::ptr(new persistent_data::core_map(NR_BLOCKS));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct sm_careful_alloc_creator {
|
|
||||||
static space_map::ptr
|
|
||||||
create() {
|
|
||||||
return create_careful_alloc_sm(
|
|
||||||
checked_space_map::ptr(
|
|
||||||
new core_map(NR_BLOCKS)));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct sm_recursive_creator {
|
|
||||||
static checked_space_map::ptr
|
|
||||||
create() {
|
|
||||||
return create_recursive_sm(
|
|
||||||
checked_space_map::ptr(
|
|
||||||
new core_map(NR_BLOCKS)));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct sm_disk_creator {
|
|
||||||
static persistent_space_map::ptr
|
|
||||||
create() {
|
|
||||||
transaction_manager::ptr tm = create_tm();
|
|
||||||
return persistent_data::create_disk_sm(tm, NR_BLOCKS);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static persistent_space_map::ptr
|
struct sm_core_creator {
|
||||||
open(void *root) {
|
static space_map::ptr
|
||||||
transaction_manager::ptr tm = create_tm();
|
create(transaction_manager &tm) {
|
||||||
return persistent_data::open_disk_sm(tm, root);
|
return space_map::ptr(new persistent_data::core_map(NR_BLOCKS));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct sm_metadata_creator {
|
struct sm_careful_alloc_creator {
|
||||||
static persistent_space_map::ptr
|
static space_map::ptr
|
||||||
create() {
|
create(transaction_manager &tm) {
|
||||||
transaction_manager::ptr tm = create_tm();
|
return create_careful_alloc_sm(
|
||||||
return persistent_data::create_metadata_sm(tm, NR_BLOCKS);
|
checked_space_map::ptr(
|
||||||
|
new core_map(NR_BLOCKS)));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct sm_recursive_creator {
|
||||||
|
static checked_space_map::ptr
|
||||||
|
create(transaction_manager &tm) {
|
||||||
|
return create_recursive_sm(
|
||||||
|
checked_space_map::ptr(
|
||||||
|
new core_map(NR_BLOCKS)));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct sm_disk_creator {
|
||||||
|
static persistent_space_map::ptr
|
||||||
|
create(transaction_manager &tm) {
|
||||||
|
return persistent_data::create_disk_sm(tm, NR_BLOCKS);
|
||||||
|
}
|
||||||
|
|
||||||
|
static persistent_space_map::ptr
|
||||||
|
open(transaction_manager &tm, void *root) {
|
||||||
|
return persistent_data::open_disk_sm(tm, root);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct sm_metadata_creator {
|
||||||
|
static persistent_space_map::ptr
|
||||||
|
create(transaction_manager &tm) {
|
||||||
|
return persistent_data::create_metadata_sm(tm, NR_BLOCKS);
|
||||||
|
}
|
||||||
|
|
||||||
|
static persistent_space_map::ptr
|
||||||
|
open(transaction_manager &tm, void *root) {
|
||||||
|
return persistent_data::open_metadata_sm(tm, root);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
//--------------------------------
|
||||||
|
|
||||||
|
void test_get_nr_blocks(space_map::ptr sm) {
|
||||||
|
ASSERT_THAT(sm->get_nr_blocks(), Eq(NR_BLOCKS));
|
||||||
}
|
}
|
||||||
|
|
||||||
static persistent_space_map::ptr
|
void test_get_nr_free(space_map::ptr sm) {
|
||||||
open(void *root) {
|
ASSERT_THAT(sm->get_nr_free(), Eq(NR_BLOCKS));
|
||||||
transaction_manager::ptr tm = create_tm();
|
|
||||||
return persistent_data::open_metadata_sm(tm, root);
|
for (unsigned i = 0; i < NR_BLOCKS; i++) {
|
||||||
|
boost::optional<block_address> mb = sm->new_block();
|
||||||
|
ASSERT_TRUE(mb);
|
||||||
|
ASSERT_THAT(sm->get_nr_free(), Eq(NR_BLOCKS - i - 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
for (unsigned i = 0; i < NR_BLOCKS; i++) {
|
||||||
|
sm->dec(i);
|
||||||
|
ASSERT_THAT(sm->get_nr_free(), Eq(i + 1));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
|
||||||
|
|
||||||
//--------------------------------
|
void test_runs_out_of_space(space_map::ptr sm) {
|
||||||
|
boost::optional<block_address> mb;
|
||||||
|
|
||||||
void test_get_nr_blocks(space_map::ptr sm)
|
for (unsigned i = 0; i < NR_BLOCKS; i++)
|
||||||
{
|
mb = sm->new_block();
|
||||||
ASSERT_THAT(sm->get_nr_blocks(), Eq(NR_BLOCKS));
|
|
||||||
}
|
|
||||||
|
|
||||||
void test_get_nr_free(space_map::ptr sm)
|
mb = sm->new_block();
|
||||||
{
|
ASSERT_FALSE(mb);
|
||||||
ASSERT_THAT(sm->get_nr_free(), Eq(NR_BLOCKS));
|
}
|
||||||
|
|
||||||
for (unsigned i = 0; i < NR_BLOCKS; i++) {
|
void test_inc_and_dec(space_map::ptr sm) {
|
||||||
|
block_address b = 63;
|
||||||
|
|
||||||
|
for (unsigned i = 0; i < 50; i++) {
|
||||||
|
ASSERT_THAT(sm->get_count(b), Eq(i));
|
||||||
|
sm->inc(b);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (unsigned i = 50; i > 0; i--) {
|
||||||
|
ASSERT_THAT(sm->get_count(b), Eq(i));
|
||||||
|
sm->dec(b);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_not_allocated_twice(space_map::ptr sm) {
|
||||||
boost::optional<block_address> mb = sm->new_block();
|
boost::optional<block_address> mb = sm->new_block();
|
||||||
ASSERT_TRUE(mb);
|
ASSERT_TRUE(mb);
|
||||||
ASSERT_THAT(sm->get_nr_free(), Eq(NR_BLOCKS - i - 1));
|
|
||||||
|
for (;;) {
|
||||||
|
boost::optional<block_address> b = sm->new_block();
|
||||||
|
if (!b)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (b)
|
||||||
|
ASSERT_TRUE(*b != *mb);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (unsigned i = 0; i < NR_BLOCKS; i++) {
|
void test_set_count(space_map::ptr sm) {
|
||||||
sm->dec(i);
|
sm->set_count(43, 5);
|
||||||
ASSERT_THAT(sm->get_nr_free(), Eq(i + 1));
|
ASSERT_THAT(sm->get_count(43), Eq(5u));
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void test_runs_out_of_space(space_map::ptr sm)
|
|
||||||
{
|
|
||||||
boost::optional<block_address> mb;
|
|
||||||
|
|
||||||
for (unsigned i = 0; i < NR_BLOCKS; i++)
|
|
||||||
mb = sm->new_block();
|
|
||||||
|
|
||||||
mb = sm->new_block();
|
|
||||||
ASSERT_FALSE(mb);
|
|
||||||
}
|
|
||||||
|
|
||||||
void test_inc_and_dec(space_map::ptr sm)
|
|
||||||
{
|
|
||||||
block_address b = 63;
|
|
||||||
|
|
||||||
for (unsigned i = 0; i < 50; i++) {
|
|
||||||
ASSERT_THAT(sm->get_count(b), Eq(i));
|
|
||||||
sm->inc(b);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (unsigned i = 50; i > 0; i--) {
|
void test_set_affects_nr_allocated(space_map::ptr sm) {
|
||||||
ASSERT_THAT(sm->get_count(b), Eq(i));
|
for (unsigned i = 0; i < NR_BLOCKS; i++) {
|
||||||
sm->dec(b);
|
sm->set_count(i, 1);
|
||||||
}
|
ASSERT_THAT(sm->get_nr_free(), Eq(NR_BLOCKS - i - 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
void test_not_allocated_twice(space_map::ptr sm)
|
for (unsigned i = 0; i < NR_BLOCKS; i++) {
|
||||||
{
|
sm->set_count(i, 0);
|
||||||
boost::optional<block_address> mb = sm->new_block();
|
ASSERT_THAT(sm->get_nr_free(), Eq(i + 1));
|
||||||
ASSERT_TRUE(mb);
|
}
|
||||||
|
|
||||||
for (;;) {
|
|
||||||
boost::optional<block_address> b = sm->new_block();
|
|
||||||
if (!b)
|
|
||||||
break;
|
|
||||||
|
|
||||||
if (b)
|
|
||||||
ASSERT_TRUE(*b != *mb);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void test_set_count(space_map::ptr sm)
|
|
||||||
{
|
|
||||||
sm->set_count(43, 5);
|
|
||||||
ASSERT_THAT(sm->get_count(43), Eq(5u));
|
|
||||||
}
|
|
||||||
|
|
||||||
void test_set_affects_nr_allocated(space_map::ptr sm)
|
|
||||||
{
|
|
||||||
for (unsigned i = 0; i < NR_BLOCKS; i++) {
|
|
||||||
sm->set_count(i, 1);
|
|
||||||
ASSERT_THAT(sm->get_nr_free(), Eq(NR_BLOCKS - i - 1));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (unsigned i = 0; i < NR_BLOCKS; i++) {
|
// Ref counts below 3 gets stored as bitmaps, above 3 they go into
|
||||||
sm->set_count(i, 0);
|
// a btree with uint32_t values. Worth checking this thoroughly,
|
||||||
ASSERT_THAT(sm->get_nr_free(), Eq(i + 1));
|
// especially for the metadata format which may have complications
|
||||||
}
|
// due to recursion.
|
||||||
}
|
void test_high_ref_counts(space_map::ptr sm) {
|
||||||
|
srand(1234);
|
||||||
// Ref counts below 3 gets stored as bitmaps, above 3 they go into
|
for (unsigned i = 0; i < NR_BLOCKS; i++)
|
||||||
// a btree with uint32_t values. Worth checking this thoroughly,
|
sm->set_count(i, rand() % 6789);
|
||||||
// especially for the metadata format which may have complications
|
|
||||||
// due to recursion.
|
|
||||||
void test_high_ref_counts(space_map::ptr sm)
|
|
||||||
{
|
|
||||||
srand(1234);
|
|
||||||
for (unsigned i = 0; i < NR_BLOCKS; i++)
|
|
||||||
sm->set_count(i, rand() % 6789);
|
|
||||||
sm->commit();
|
|
||||||
|
|
||||||
for (unsigned i = 0; i < NR_BLOCKS; i++) {
|
|
||||||
sm->inc(i);
|
|
||||||
sm->inc(i);
|
|
||||||
if (i % 1000)
|
|
||||||
sm->commit();
|
|
||||||
}
|
|
||||||
sm->commit();
|
|
||||||
|
|
||||||
srand(1234);
|
|
||||||
for (unsigned i = 0; i < NR_BLOCKS; i++)
|
|
||||||
ASSERT_THAT(sm->get_count(i), Eq((rand() % 6789u) + 2u));
|
|
||||||
|
|
||||||
for (unsigned i = 0; i < NR_BLOCKS; i++)
|
|
||||||
sm->dec(i);
|
|
||||||
|
|
||||||
srand(1234);
|
|
||||||
for (unsigned i = 0; i < NR_BLOCKS; i++)
|
|
||||||
ASSERT_THAT(sm->get_count(i), Eq((rand() % 6789u) + 1u));
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename SMCreator>
|
|
||||||
void test_sm_reopen()
|
|
||||||
{
|
|
||||||
unsigned char buffer[128];
|
|
||||||
|
|
||||||
{
|
|
||||||
persistent_space_map::ptr sm = SMCreator::create();
|
|
||||||
for (unsigned i = 0, step = 1; i < NR_BLOCKS; i += step, step++)
|
|
||||||
sm->inc(i);
|
|
||||||
sm->commit();
|
sm->commit();
|
||||||
|
|
||||||
ASSERT_THAT(sm->root_size(), Le(sizeof(buffer)));
|
for (unsigned i = 0; i < NR_BLOCKS; i++) {
|
||||||
sm->copy_root(buffer, sizeof(buffer));
|
sm->inc(i);
|
||||||
|
sm->inc(i);
|
||||||
|
if (i % 1000)
|
||||||
|
sm->commit();
|
||||||
|
}
|
||||||
|
sm->commit();
|
||||||
|
|
||||||
|
srand(1234);
|
||||||
|
for (unsigned i = 0; i < NR_BLOCKS; i++)
|
||||||
|
ASSERT_THAT(sm->get_count(i), Eq((rand() % 6789u) + 2u));
|
||||||
|
|
||||||
|
for (unsigned i = 0; i < NR_BLOCKS; i++)
|
||||||
|
sm->dec(i);
|
||||||
|
|
||||||
|
srand(1234);
|
||||||
|
for (unsigned i = 0; i < NR_BLOCKS; i++)
|
||||||
|
ASSERT_THAT(sm->get_count(i), Eq((rand() % 6789u) + 1u));
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
template <typename SMCreator>
|
||||||
persistent_space_map::ptr sm = SMCreator::open(buffer);
|
void test_sm_reopen() {
|
||||||
|
unsigned char buffer[128];
|
||||||
|
|
||||||
for (unsigned i = 0, step = 1; i < NR_BLOCKS; i += step, step++)
|
{
|
||||||
ASSERT_THAT(sm->get_count(i), Eq(1u));
|
persistent_space_map::ptr sm = SMCreator::create(tm_);
|
||||||
|
for (unsigned i = 0, step = 1; i < NR_BLOCKS; i += step, step++)
|
||||||
|
sm->inc(i);
|
||||||
|
sm->commit();
|
||||||
|
|
||||||
|
ASSERT_THAT(sm->root_size(), Le(sizeof(buffer)));
|
||||||
|
sm->copy_root(buffer, sizeof(buffer));
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
persistent_space_map::ptr sm = SMCreator::open(tm_, buffer);
|
||||||
|
|
||||||
|
for (unsigned i = 0, step = 1; i < NR_BLOCKS; i += step, step++)
|
||||||
|
ASSERT_THAT(sm->get_count(i), Eq(1u));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
typedef void (*sm_test)(space_map::ptr);
|
template <typename SMCreator>
|
||||||
|
void do_tests() {
|
||||||
template <typename SMCreator, unsigned NTests>
|
test_get_nr_blocks(SMCreator::create(tm_));
|
||||||
void do_tests(sm_test (&tests)[NTests])
|
test_get_nr_free(SMCreator::create(tm_));
|
||||||
{
|
test_runs_out_of_space(SMCreator::create(tm_));
|
||||||
for (unsigned t = 0; t < NTests; t++) {
|
test_inc_and_dec(SMCreator::create(tm_));
|
||||||
space_map::ptr sm = SMCreator::create();
|
test_not_allocated_twice(SMCreator::create(tm_));
|
||||||
tests[t](sm);
|
test_set_count(SMCreator::create(tm_));
|
||||||
|
test_set_affects_nr_allocated(SMCreator::create(tm_));
|
||||||
|
test_high_ref_counts(SMCreator::create(tm_));
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
sm_test space_map_tests[] = {
|
void
|
||||||
test_get_nr_blocks,
|
copy_space_maps(space_map::ptr lhs, space_map::ptr rhs) {
|
||||||
test_get_nr_free,
|
for (block_address b = 0; b < rhs->get_nr_blocks(); b++) {
|
||||||
test_runs_out_of_space,
|
uint32_t count = rhs->get_count(b);
|
||||||
test_inc_and_dec,
|
if (count > 0)
|
||||||
test_not_allocated_twice,
|
lhs->set_count(b, rhs->get_count(b));
|
||||||
test_set_count,
|
}
|
||||||
test_set_affects_nr_allocated,
|
}
|
||||||
test_high_ref_counts
|
|
||||||
|
block_manager<>::ptr bm_;
|
||||||
|
space_map::ptr sm_;
|
||||||
|
transaction_manager tm_;
|
||||||
};
|
};
|
||||||
|
|
||||||
void
|
|
||||||
copy_space_maps(space_map::ptr lhs, space_map::ptr rhs) {
|
|
||||||
for (block_address b = 0; b < rhs->get_nr_blocks(); b++) {
|
|
||||||
uint32_t count = rhs->get_count(b);
|
|
||||||
if (count > 0)
|
|
||||||
lhs->set_count(b, rhs->get_count(b));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------
|
//----------------------------------------------------------------
|
||||||
|
|
||||||
TEST(SpaceMapTests, test_sm_core)
|
TEST_F(SpaceMapTests, test_sm_core)
|
||||||
{
|
{
|
||||||
do_tests<sm_core_creator>(space_map_tests);
|
do_tests<sm_core_creator>();
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(SpaceMapTests, test_sm_careful_alloc)
|
TEST_F(SpaceMapTests, test_sm_careful_alloc)
|
||||||
{
|
{
|
||||||
do_tests<sm_careful_alloc_creator>(space_map_tests);
|
do_tests<sm_careful_alloc_creator>();
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(SpaceMapTests, test_sm_recursive)
|
TEST_F(SpaceMapTests, test_sm_recursive)
|
||||||
{
|
{
|
||||||
do_tests<sm_recursive_creator>(space_map_tests);
|
do_tests<sm_recursive_creator>();
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(SpaceMapTests, test_sm_disk)
|
TEST_F(SpaceMapTests, test_sm_disk)
|
||||||
{
|
{
|
||||||
do_tests<sm_disk_creator>(space_map_tests);
|
do_tests<sm_disk_creator>();
|
||||||
test_sm_reopen<sm_disk_creator>();
|
test_sm_reopen<sm_disk_creator>();
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(SpaceMapTests, test_sm_metadata)
|
TEST_F(SpaceMapTests, test_sm_metadata)
|
||||||
{
|
{
|
||||||
do_tests<sm_metadata_creator>(space_map_tests);
|
do_tests<sm_metadata_creator>();
|
||||||
test_sm_reopen<sm_metadata_creator>();
|
test_sm_reopen<sm_metadata_creator>();
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(SpaceMapTests, test_metadata_and_disk)
|
TEST_F(SpaceMapTests, test_metadata_and_disk)
|
||||||
{
|
{
|
||||||
block_manager<>::ptr bm(
|
block_manager<>::ptr bm(
|
||||||
new block_manager<>("./test.data", NR_BLOCKS, MAX_LOCKS, block_manager<>::READ_WRITE));
|
new block_manager<>("./test.data", NR_BLOCKS, MAX_LOCKS, block_manager<>::READ_WRITE));
|
||||||
space_map::ptr core_sm(new core_map(NR_BLOCKS));
|
space_map::ptr core_sm(new core_map(NR_BLOCKS));
|
||||||
transaction_manager::ptr tm(new transaction_manager(bm, core_sm));
|
transaction_manager::ptr tm(new transaction_manager(bm, core_sm));
|
||||||
persistent_space_map::ptr metadata_sm = persistent_data::create_metadata_sm(tm, NR_BLOCKS);
|
persistent_space_map::ptr metadata_sm = persistent_data::create_metadata_sm(*tm, NR_BLOCKS);
|
||||||
copy_space_maps(metadata_sm, core_sm);
|
copy_space_maps(metadata_sm, core_sm);
|
||||||
tm->set_sm(metadata_sm);
|
tm->set_sm(metadata_sm);
|
||||||
|
|
||||||
persistent_space_map::ptr data_sm_ = create_disk_sm(tm, NR_BLOCKS * 2);
|
persistent_space_map::ptr data_sm_ = create_disk_sm(*tm, NR_BLOCKS * 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------
|
//----------------------------------------------------------------
|
||||||
|
Loading…
Reference in New Issue
Block a user