remove btree_checker, and add btree_counter
This commit is contained in:
81
persistent-data/data-structures/btree_counter.h
Normal file
81
persistent-data/data-structures/btree_counter.h
Normal file
@@ -0,0 +1,81 @@
|
||||
#ifndef PERSISTENT_DATA_DATA_STRUCTURES_BTREE_COUNTER_H
|
||||
#define PERSISTENT_DATA_DATA_STRUCTURES_BTREE_COUNTER_H
|
||||
|
||||
#include "persistent-data/block_counter.h"
|
||||
|
||||
//----------------------------------------------------------------
|
||||
|
||||
namespace persistent_data {
|
||||
namespace btree_count_detail {
|
||||
template <unsigned Levels, typename ValueTraits, typename ValueCounter>
|
||||
class counting_visitor : public btree<Levels, ValueTraits>::visitor {
|
||||
public:
|
||||
typedef btree<Levels, ValueTraits> tree;
|
||||
|
||||
counting_visitor(block_counter &bc, ValueCounter &vc)
|
||||
: bc_(bc),
|
||||
vc_(vc) {
|
||||
}
|
||||
|
||||
virtual bool visit_internal(node_location const &l,
|
||||
typename tree::internal_node const &n) {
|
||||
return visit_node(n);
|
||||
}
|
||||
|
||||
virtual bool visit_internal_leaf(node_location const &l,
|
||||
typename tree::internal_node const &n) {
|
||||
return visit_node(n);
|
||||
}
|
||||
|
||||
virtual bool visit_leaf(node_location const &l,
|
||||
typename tree::leaf_node const &n) {
|
||||
if (visit_node(n)) {
|
||||
unsigned nr = n.get_nr_entries();
|
||||
|
||||
for (unsigned i = 0; i < nr; i++) {
|
||||
// FIXME: confirm l2 is correct
|
||||
node_location l2(l);
|
||||
l2.push_key(i);
|
||||
vc_.visit(l2, n.value_at(i));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private:
|
||||
template <typename Node>
|
||||
bool visit_node(Node const &n) {
|
||||
block_address b = n.get_location();
|
||||
bool seen = bc_.get_count(b);
|
||||
bc_.inc(b);
|
||||
return !seen;
|
||||
}
|
||||
|
||||
block_counter &bc_;
|
||||
ValueCounter &vc_;
|
||||
};
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
struct noop_value_counter {
|
||||
void visit(btree_detail::node_location const &loc, T const &v) {
|
||||
}
|
||||
};
|
||||
|
||||
// Counts how many times each metadata block is referenced in the
|
||||
// tree. Blocks already referenced in the block counter are not
|
||||
// walked. This walk should only be done once you're sure the tree
|
||||
// is not corrupt.
|
||||
template <unsigned Levels, typename ValueTraits, typename ValueCounter>
|
||||
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);
|
||||
tree.visit_depth_first(v);
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user