[counting_visitor] fix unnecessary value visiting
1. Do not inherit btree_damage_visitor to avoid unnecessary
value visiting.
(reverts commit b22495997a
)
2. Use btree_node_checker to do node checking
This commit is contained in:
parent
4a4dc1a5e0
commit
6dc9a90fec
@ -2,44 +2,36 @@
|
||||
#define PERSISTENT_DATA_DATA_STRUCTURES_BTREE_COUNTER_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/data-structures/btree_node_checker.h"
|
||||
#include "persistent-data/block_counter.h"
|
||||
|
||||
//----------------------------------------------------------------
|
||||
|
||||
namespace persistent_data {
|
||||
namespace btree_count_detail {
|
||||
template <typename ValueVisitor, typename DamageVisitor, unsigned Levels, typename ValueTraits, typename ValueCounter>
|
||||
class counting_visitor : public btree_damage_visitor<ValueVisitor, DamageVisitor, Levels, ValueTraits> {
|
||||
typedef btree_damage_visitor<ValueVisitor, DamageVisitor, Levels, ValueTraits> BtreeDamageVisitor;
|
||||
template <unsigned Levels, typename ValueTraits, typename ValueCounter>
|
||||
class counting_visitor : public btree<Levels, ValueTraits>::visitor {
|
||||
public:
|
||||
typedef btree<Levels, ValueTraits> tree;
|
||||
|
||||
counting_visitor(ValueVisitor &value_visitor,
|
||||
DamageVisitor &damage_visitor,
|
||||
block_counter &bc,
|
||||
ValueCounter &vc)
|
||||
: BtreeDamageVisitor(value_visitor, damage_visitor, false),
|
||||
bc_(bc),
|
||||
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 BtreeDamageVisitor::visit_internal(l, n) ?
|
||||
visit_node(n) : false;
|
||||
return check_internal(l, n) ? visit_node(n) : false;
|
||||
}
|
||||
|
||||
virtual bool visit_internal_leaf(node_location const &l,
|
||||
typename tree::internal_node const &n) {
|
||||
return BtreeDamageVisitor::visit_internal_leaf(l, n) ?
|
||||
visit_node(n) : false;
|
||||
return check_leaf(l, n) ? visit_node(n) : false;
|
||||
}
|
||||
|
||||
virtual bool visit_leaf(node_location const &l,
|
||||
typename tree::leaf_node const &n) {
|
||||
if (BtreeDamageVisitor::visit_leaf(l, n) && visit_node(n)) {
|
||||
if (check_leaf(l, n) && visit_node(n)) {
|
||||
unsigned nr = n.get_nr_entries();
|
||||
|
||||
for (unsigned i = 0; i < nr; i++) {
|
||||
@ -55,7 +47,57 @@ namespace persistent_data {
|
||||
return false;
|
||||
}
|
||||
|
||||
typedef typename btree<Levels, ValueTraits>::visitor::error_outcome error_outcome;
|
||||
|
||||
error_outcome error_accessing_node(node_location const &l, block_address b,
|
||||
std::string const &what) {
|
||||
return btree<Levels, ValueTraits>::visitor::EXCEPTION_HANDLED;
|
||||
}
|
||||
|
||||
private:
|
||||
bool check_internal(node_location const &l,
|
||||
btree_detail::node_ref<block_traits> const &n) {
|
||||
if (!checker_.check_block_nr(n) ||
|
||||
!checker_.check_value_size(n) ||
|
||||
!checker_.check_max_entries(n) ||
|
||||
!checker_.check_nr_entries(n, l.is_sub_root()) ||
|
||||
!checker_.check_ordered_keys(n) ||
|
||||
!checker_.check_parent_key(n, l.is_sub_root() ? boost::optional<uint64_t>() : l.key))
|
||||
return false;
|
||||
|
||||
if (l.is_sub_root())
|
||||
new_root(l.level());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename ValueTraits2>
|
||||
bool check_leaf(node_location const &l,
|
||||
btree_detail::node_ref<ValueTraits2> const &n) {
|
||||
if (!checker_.check_block_nr(n) ||
|
||||
!checker_.check_value_size(n) ||
|
||||
!checker_.check_max_entries(n) ||
|
||||
!checker_.check_nr_entries(n, l.is_sub_root()) ||
|
||||
!checker_.check_ordered_keys(n) ||
|
||||
!checker_.check_parent_key(n, l.is_sub_root() ? boost::optional<uint64_t>() : l.key))
|
||||
return false;
|
||||
|
||||
if (l.is_sub_root())
|
||||
new_root(l.level());
|
||||
|
||||
bool r = checker_.check_leaf_key(n, last_leaf_key_[l.level()]);
|
||||
if (r && n.get_nr_entries() > 0)
|
||||
last_leaf_key_[l.level()] = n.key_at(n.get_nr_entries() - 1);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
void new_root(unsigned level) {
|
||||
// we're starting a new subtree, so should
|
||||
// reset the last_leaf value.
|
||||
last_leaf_key_[level] = boost::optional<uint64_t>();
|
||||
}
|
||||
|
||||
template <typename Node>
|
||||
bool visit_node(Node const &n) {
|
||||
block_address b = n.get_location();
|
||||
@ -66,6 +108,8 @@ namespace persistent_data {
|
||||
|
||||
block_counter &bc_;
|
||||
ValueCounter &vc_;
|
||||
btree_node_checker checker_;
|
||||
boost::optional<uint64_t> last_leaf_key_[Levels];
|
||||
};
|
||||
}
|
||||
|
||||
@ -94,21 +138,7 @@ namespace persistent_data {
|
||||
// is not corrupt.
|
||||
template <unsigned Levels, typename ValueTraits, typename ValueCounter>
|
||||
void count_btree_blocks(btree<Levels, ValueTraits> const &tree, block_counter &bc, ValueCounter &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);
|
||||
}
|
||||
|
||||
template <unsigned Levels, typename ValueTraits>
|
||||
void count_btree_blocks(btree<Levels, ValueTraits> const &tree, block_counter &bc) {
|
||||
typedef noop_value_visitor<typename ValueTraits::value_type> NoopValueVisitor;
|
||||
NoopValueVisitor noop_vv;
|
||||
noop_damage_visitor noop_dv;
|
||||
typedef noop_value_counter<typename ValueTraits::value_type> NoopValueCounter;
|
||||
NoopValueCounter vc;
|
||||
btree_count_detail::counting_visitor<NoopValueVisitor, noop_damage_visitor, Levels, ValueTraits, NoopValueCounter> v(noop_vv, noop_dv, bc, vc);
|
||||
btree_count_detail::counting_visitor<Levels, ValueTraits, ValueCounter> v(bc, vc);
|
||||
tree.visit_depth_first(v);
|
||||
}
|
||||
}
|
||||
|
@ -158,9 +158,8 @@ namespace persistent_data {
|
||||
typedef boost::optional<run64> maybe_run64;
|
||||
|
||||
btree_damage_visitor(ValueVisitor &value_visitor,
|
||||
DamageVisitor &damage_visitor,
|
||||
bool avoid_repeated_visits = true)
|
||||
: avoid_repeated_visits_(avoid_repeated_visits),
|
||||
DamageVisitor &damage_visitor)
|
||||
: avoid_repeated_visits_(true),
|
||||
value_visitor_(value_visitor),
|
||||
damage_visitor_(damage_visitor) {
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user