Allow counting_visitor to work with damaged btrees

This commit is contained in:
Ming-Hung Tsai 2016-02-27 15:22:00 +08:00
parent ad03114bf7
commit b22495997a
2 changed files with 23 additions and 10 deletions

View File

@ -2,35 +2,44 @@
#define PERSISTENT_DATA_DATA_STRUCTURES_BTREE_COUNTER_H #define PERSISTENT_DATA_DATA_STRUCTURES_BTREE_COUNTER_H
#include "persistent-data/data-structures/btree.h" #include "persistent-data/data-structures/btree.h"
#include "persistent-data/data-structures/btree_base_visitor.h"
#include "persistent-data/data-structures/btree_damage_visitor.h"
#include "persistent-data/block_counter.h" #include "persistent-data/block_counter.h"
//---------------------------------------------------------------- //----------------------------------------------------------------
namespace persistent_data { namespace persistent_data {
namespace btree_count_detail { namespace btree_count_detail {
template <unsigned Levels, typename ValueTraits, typename ValueCounter> template <typename ValueVisitor, typename DamageVisitor, unsigned Levels, typename ValueTraits, typename ValueCounter>
class counting_visitor : public btree<Levels, ValueTraits>::visitor { class counting_visitor : public btree_damage_visitor<ValueVisitor, DamageVisitor, Levels, ValueTraits> {
typedef btree_damage_visitor<ValueVisitor, DamageVisitor, Levels, ValueTraits> BtreeDamageVisitor;
public: public:
typedef btree<Levels, ValueTraits> tree; typedef btree<Levels, ValueTraits> tree;
counting_visitor(block_counter &bc, ValueCounter &vc) counting_visitor(ValueVisitor &value_visitor,
: bc_(bc), DamageVisitor &damage_visitor,
block_counter &bc,
ValueCounter &vc)
: BtreeDamageVisitor(value_visitor, damage_visitor, false),
bc_(bc),
vc_(vc) { vc_(vc) {
} }
virtual bool visit_internal(node_location const &l, virtual bool visit_internal(node_location const &l,
typename tree::internal_node const &n) { typename tree::internal_node const &n) {
return visit_node(n); return BtreeDamageVisitor::visit_internal(l, n) ?
visit_node(n) : false;
} }
virtual bool visit_internal_leaf(node_location const &l, virtual bool visit_internal_leaf(node_location const &l,
typename tree::internal_node const &n) { typename tree::internal_node const &n) {
return visit_node(n); return BtreeDamageVisitor::visit_internal_leaf(l, n) ?
visit_node(n) : false;
} }
virtual bool visit_leaf(node_location const &l, virtual bool visit_leaf(node_location const &l,
typename tree::leaf_node const &n) { typename tree::leaf_node const &n) {
if (visit_node(n)) { if (BtreeDamageVisitor::visit_leaf(l, n) && visit_node(n)) {
unsigned nr = n.get_nr_entries(); unsigned nr = n.get_nr_entries();
for (unsigned i = 0; i < nr; i++) { for (unsigned i = 0; i < nr; i++) {
@ -85,7 +94,10 @@ namespace persistent_data {
// is not corrupt. // is not corrupt.
template <unsigned Levels, typename ValueTraits, typename ValueCounter> template <unsigned Levels, typename ValueTraits, typename ValueCounter>
void count_btree_blocks(btree<Levels, ValueTraits> const &tree, block_counter &bc, ValueCounter &vc) { void count_btree_blocks(btree<Levels, ValueTraits> const &tree, block_counter &bc, ValueCounter &vc) {
btree_count_detail::counting_visitor<Levels, ValueTraits, ValueCounter> v(bc, vc); typedef noop_value_visitor<typename ValueTraits::value_type> NoopValueVisitor;
NoopValueVisitor noop_vv;
noop_damage_visitor noop_dv;
btree_count_detail::counting_visitor<NoopValueVisitor, noop_damage_visitor, Levels, ValueTraits, ValueCounter> v(noop_vv, noop_dv, bc, vc);
tree.visit_depth_first(v); tree.visit_depth_first(v);
} }
} }

View File

@ -158,8 +158,9 @@ namespace persistent_data {
typedef boost::optional<run64> maybe_run64; typedef boost::optional<run64> maybe_run64;
btree_damage_visitor(ValueVisitor &value_visitor, btree_damage_visitor(ValueVisitor &value_visitor,
DamageVisitor &damage_visitor) DamageVisitor &damage_visitor,
: avoid_repeated_visits_(true), bool avoid_repeated_visits = true)
: avoid_repeated_visits_(avoid_repeated_visits),
value_visitor_(value_visitor), value_visitor_(value_visitor),
damage_visitor_(damage_visitor) { damage_visitor_(damage_visitor) {
} }