From 5367631c8c6e8061a218b91852104ea0c993ad94 Mon Sep 17 00:00:00 2001 From: Joe Thornber Date: Fri, 26 Apr 2013 14:15:20 +0100 Subject: [PATCH] [various data structures] Reuse validators rather than always creating a new one. --- persistent-data/data-structures/array.h | 21 ++++++++------- persistent-data/data-structures/btree.h | 16 +++++++++--- persistent-data/data-structures/btree.tcc | 27 +++++++++----------- persistent-data/space-maps/disk.cc | 31 ++++++++++++----------- 4 files changed, 50 insertions(+), 45 deletions(-) diff --git a/persistent-data/data-structures/array.h b/persistent-data/data-structures/array.h index dad961d..f69d627 100644 --- a/persistent-data/data-structures/array.h +++ b/persistent-data/data-structures/array.h @@ -31,6 +31,7 @@ namespace persistent_data { namespace array_detail { uint32_t const ARRAY_CSUM_XOR = 595846735; + // FIXME: this isn't used! struct array_block_validator : public block_manager<>::validator { virtual void check(buffer<> const &b, block_address location) const { array_block_disk const *data = reinterpret_cast(&b); @@ -135,7 +136,8 @@ namespace persistent_data { nr_entries_(0), block_rc_(tm->get_sm(), *this), block_tree_(tm, block_rc_), - rc_(rc) { + rc_(rc), + validator_(new block_manager<>::noop_validator()) { } array(tm_ptr tm, @@ -147,7 +149,8 @@ namespace persistent_data { nr_entries_(nr_entries), block_rc_(tm->get_sm(), *this), block_tree_(tm, root, block_rc_), - rc_(rc) { + rc_(rc), + validator_(new block_manager<>::noop_validator()) { } unsigned get_nr_entries() const { @@ -253,11 +256,6 @@ namespace persistent_data { //-------------------------------- - block_manager<>::validator::ptr validator() const { - return block_manager<>::validator::ptr( - new block_manager<>::noop_validator()); - } - block_address lookup_block_address(unsigned array_index) const { uint64_t key[1] = {array_index}; boost::optional addr = block_tree_.lookup(key); @@ -272,7 +270,7 @@ namespace persistent_data { wblock new_ablock(unsigned 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(); wblock wb(b, rc_); @@ -283,13 +281,13 @@ namespace persistent_data { rblock get_ablock(unsigned ablock_index) const { 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) { uint64_t key[1] = {ablock_index}; block_address addr = lookup_block_address(ablock_index); - std::pair p = tm_->shadow(addr, validator()); + std::pair p = tm_->shadow(addr, validator_); wblock wb = wblock(p.first, rc_); if (p.second) @@ -301,7 +299,7 @@ namespace persistent_data { } 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(); } @@ -311,6 +309,7 @@ namespace persistent_data { block_ref_counter block_rc_; btree<1, block_traits> block_tree_; typename ValueTraits::ref_counter rc_; + block_manager<>::validator::ptr validator_; }; } diff --git a/persistent-data/data-structures/btree.h b/persistent-data/data-structures/btree.h index 776b365..6803c74 100644 --- a/persistent-data/data-structures/btree.h +++ b/persistent-data/data-structures/btree.h @@ -184,8 +184,10 @@ namespace persistent_data { class ro_spine : private noncopyable { public: - ro_spine(transaction_manager::ptr tm) - : tm_(tm) { + ro_spine(transaction_manager::ptr tm, + typename block_manager<>::validator::ptr v) + : tm_(tm), + validator_(v) { } void step(block_address b); @@ -197,6 +199,7 @@ namespace persistent_data { private: transaction_manager::ptr tm_; + typename block_manager<>::validator::ptr validator_; std::list::read_ref> spine_; }; @@ -205,8 +208,11 @@ namespace persistent_data { typedef transaction_manager::read_ref read_ref; typedef transaction_manager::write_ref write_ref; - shadow_spine(transaction_manager::ptr tm) - : tm_(tm) { + shadow_spine(transaction_manager::ptr tm, + typename block_manager<>::validator::ptr v) + + : tm_(tm), + validator_(v) { } // true if the children of the shadow need incrementing @@ -253,6 +259,7 @@ namespace persistent_data { private: transaction_manager::ptr tm_; + typename block_manager<>::validator::ptr validator_; std::list::write_ref> spine_; block_address root_; }; @@ -354,6 +361,7 @@ namespace persistent_data { block_address root_; no_op_ref_counter internal_rc_; typename ValueTraits::ref_counter rc_; + typename block_manager<>::validator::ptr validator_; }; }; diff --git a/persistent-data/data-structures/btree.tcc b/persistent-data/data-structures/btree.tcc index d281cdd..733696a 100644 --- a/persistent-data/data-structures/btree.tcc +++ b/persistent-data/data-structures/btree.tcc @@ -55,11 +55,6 @@ namespace { n->csum = to_disk(sum.get_sum()); } }; - - block_manager<>::validator::ptr - btree_validator() { - return block_manager<>::validator::ptr(new btree_node_validator); - } } //---------------------------------------------------------------- @@ -67,7 +62,7 @@ namespace { inline void ro_spine::step(block_address b) { - spine_.push_back(tm_->read_lock(b, btree_validator())); + spine_.push_back(tm_->read_lock(b, validator_)); if (spine_.size() > 2) spine_.pop_front(); } @@ -75,7 +70,7 @@ ro_spine::step(block_address b) inline bool shadow_spine::step(block_address b) { - pair p = tm_->shadow(b, btree_validator()); + pair p = tm_->shadow(b, validator_); try { step(p.first); } catch (...) { @@ -368,11 +363,12 @@ btree(typename transaction_manager::ptr tm, typename ValueTraits::ref_counter rc) : tm_(tm), destroy_(false), - rc_(rc) + rc_(rc), + validator_(new btree_node_validator) { using namespace btree_detail; - write_ref root = tm_->new_block(btree_validator()); + write_ref root = tm_->new_block(validator_); leaf_node n = to_node(root); n.set_type(btree_detail::LEAF); @@ -391,7 +387,8 @@ btree(typename transaction_manager::ptr tm, : tm_(tm), destroy_(false), root_(root), - rc_(rc) + rc_(rc), + validator_(new btree_node_validator) { } @@ -423,7 +420,7 @@ btree::lookup(key const &key) const { using namespace btree_detail; - ro_spine spine(tm_); + ro_spine spine(tm_, validator_); block_address root = root_; for (unsigned level = 0; level < Levels - 1; ++level) { @@ -466,7 +463,7 @@ insert(key const &key, block_address block = root_; int index = 0; // FIXME: ??? - shadow_spine spine(tm_); + shadow_spine spine(tm_, validator_); for (unsigned level = 0; level < Levels - 1; ++level) { bool need_insert = insert_location(spine, block, key[level], &index); @@ -592,13 +589,13 @@ split_beneath(btree_detail::shadow_spine &spine, node_type type; unsigned nr_left, nr_right; - write_ref left = tm_->new_block(btree_validator()); + write_ref left = tm_->new_block(validator_); node_ref l = to_node(left); l.set_nr_entries(0); l.set_max_entries(); l.set_value_size(sizeof(typename ValueTraits::disk_type)); - write_ref right = tm_->new_block(btree_validator()); + write_ref right = tm_->new_block(validator_); node_ref r = to_node(right); r.set_nr_entries(0); r.set_max_entries(); @@ -652,7 +649,7 @@ split_sibling(btree_detail::shadow_spine &spine, node_ref l = spine.template get_node(); block_address left = spine.get_block(); - write_ref right = tm_->new_block(btree_validator()); + write_ref right = tm_->new_block(validator_); node_ref r = to_node(right); unsigned nr_left = l.get_nr_entries() / 2; diff --git a/persistent-data/space-maps/disk.cc b/persistent-data/space-maps/disk.cc index e7a3ec8..4f13423 100644 --- a/persistent-data/space-maps/disk.cc +++ b/persistent-data/space-maps/disk.cc @@ -59,11 +59,6 @@ namespace { } }; - block_manager<>::validator::ptr - bitmap_validator() { - return block_manager<>::validator::ptr(new bitmap_block_validator()); - } - //-------------------------------- uint64_t const INDEX_CSUM_XOR = 160478; @@ -91,7 +86,6 @@ namespace { } }; - block_manager<>::validator::ptr index_validator() { return block_manager<>::validator::ptr(new index_block_validator()); @@ -105,13 +99,15 @@ namespace { typedef transaction_manager::write_ref write_ref; bitmap(transaction_manager::ptr tm, - index_entry const &ie) + index_entry const &ie, + block_manager<>::validator::ptr v) : tm_(tm), + validator_(v), ie_(ie) { } ref_t lookup(unsigned b) const { - read_ref rr = tm_->read_lock(ie_.blocknr_, bitmap_validator()); + read_ref rr = tm_->read_lock(ie_.blocknr_, validator_); void const *bits = bitmap_data(rr); ref_t b1 = test_bit_le(bits, b * 2); ref_t b2 = test_bit_le(bits, b * 2 + 1); @@ -121,7 +117,7 @@ namespace { } void insert(unsigned b, ref_t n) { - write_ref wr = tm_->shadow(ie_.blocknr_, bitmap_validator()).first; + write_ref wr = tm_->shadow(ie_.blocknr_, validator_).first; void *bits = bitmap_data(wr); bool was_free = !test_bit_le(bits, b * 2) && !test_bit_le(bits, b * 2 + 1); if (n == 1 || n == 3) @@ -162,7 +158,7 @@ namespace { } void iterate(block_address offset, block_address hi, space_map::iterator &it) const { - read_ref rr = tm_->read_lock(ie_.blocknr_, bitmap_validator()); + read_ref rr = tm_->read_lock(ie_.blocknr_, validator_); void const *bits = bitmap_data(rr); for (unsigned b = 0; b < hi; b++) { @@ -186,6 +182,8 @@ namespace { } transaction_manager::ptr tm_; + block_manager<>::validator::ptr validator_; + index_entry ie_; }; @@ -236,6 +234,7 @@ namespace { sm_disk(index_store::ptr indexes, transaction_manager::ptr tm) : tm_(tm), + bitmap_validator_(new bitmap_block_validator), indexes_(indexes), nr_blocks_(0), nr_allocated_(0), @@ -246,6 +245,7 @@ namespace { transaction_manager::ptr tm, sm_root const &root) : tm_(tm), + bitmap_validator_(new bitmap_block_validator), indexes_(indexes), nr_blocks_(root.nr_blocks_), nr_allocated_(root.nr_allocated_), @@ -318,7 +318,7 @@ namespace { for (block_address index = begin_index; index < end_index; index++) { index_entry ie = indexes_->find_ie(index); - bitmap bm(tm_, ie); + bitmap bm(tm_, ie, bitmap_validator_); unsigned bit_begin = (index == begin_index) ? (begin % ENTRIES_PER_BLOCK) : 0; unsigned bit_end = (index == end_index - 1) ? (end % ENTRIES_PER_BLOCK) : ENTRIES_PER_BLOCK; @@ -345,7 +345,7 @@ namespace { indexes_->resize(bitmap_count); 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; ie.blocknr_ = wr.get_location(); @@ -390,7 +390,7 @@ namespace { for (unsigned i = 0; i < nr_indexes; i++) { unsigned hi = (i == nr_indexes - 1) ? (nr_blocks_ % ENTRIES_PER_BLOCK) : ENTRIES_PER_BLOCK; index_entry ie = indexes_->find_ie(i); - bitmap bm(tm_, ie); + bitmap bm(tm_, ie, bitmap_validator_); bm.iterate(i * ENTRIES_PER_BLOCK, hi, wrapper); } } @@ -445,7 +445,7 @@ namespace { private: ref_t lookup_bitmap(block_address b) const { index_entry ie = indexes_->find_ie(b / ENTRIES_PER_BLOCK); - bitmap bm(tm_, ie); + bitmap bm(tm_, ie, bitmap_validator_); return bm.lookup(b % ENTRIES_PER_BLOCK); } @@ -454,7 +454,7 @@ namespace { throw runtime_error("bitmap can only hold 2 bit values"); index_entry ie = indexes_->find_ie(b / ENTRIES_PER_BLOCK); - bitmap bm(tm_, ie); + bitmap bm(tm_, ie, bitmap_validator_); bm.insert(b % ENTRIES_PER_BLOCK, n); indexes_->save_ie(b / ENTRIES_PER_BLOCK, bm.get_ie()); } @@ -478,6 +478,7 @@ namespace { } transaction_manager::ptr tm_; + block_manager<>::validator::ptr bitmap_validator_; index_store::ptr indexes_; block_address nr_blocks_; block_address nr_allocated_;