[btree] allow people to visit all the nodes in a btree.
This commit is contained in:
parent
9be40b76b5
commit
4d37416075
19
btree.h
19
btree.h
@ -299,6 +299,22 @@ namespace persistent_data {
|
||||
// free the on disk btree when the destructor is called
|
||||
void destroy();
|
||||
|
||||
|
||||
// Derive a class from this base class if you need to
|
||||
// inspect the individual nodes that make up a btree.
|
||||
class visitor {
|
||||
public:
|
||||
virtual ~visitor() {}
|
||||
typedef boost::shared_ptr<visitor> ptr;
|
||||
|
||||
virtual void visit_internal(unsigned level, btree_detail::node_ref<uint64_traits, BlockSize> const &n) = 0;
|
||||
virtual void visit_internal_leaf(unsigned level, btree_detail::node_ref<uint64_traits, BlockSize> const &n) = 0;
|
||||
virtual void visit_leaf(unsigned level, btree_detail::node_ref<ValueTraits, BlockSize> const &n) = 0;
|
||||
};
|
||||
|
||||
// Walks the tree in depth first order
|
||||
void visit(typename visitor::ptr visitor);
|
||||
|
||||
private:
|
||||
template <typename ValueTraits2>
|
||||
void split_node(btree_detail::shadow_spine<BlockSize> &spine,
|
||||
@ -321,6 +337,9 @@ namespace persistent_data {
|
||||
uint64_t key,
|
||||
int *index);
|
||||
|
||||
void walk_tree(typename visitor::ptr visitor,
|
||||
unsigned level, block_address b);
|
||||
|
||||
typename persistent_data::transaction_manager<BlockSize>::ptr tm_;
|
||||
bool destroy_;
|
||||
block_address root_;
|
||||
|
31
btree.tcc
31
btree.tcc
@ -590,5 +590,36 @@ insert_location(btree_detail::shadow_spine<BlockSize> &spine,
|
||||
(leaf.key_at(i) != key));
|
||||
}
|
||||
|
||||
template <unsigned Levels, typename ValueTraits, uint32_t BlockSize>
|
||||
void
|
||||
btree<Levels, ValueTraits, BlockSize>::visit(typename visitor::ptr visitor)
|
||||
{
|
||||
walk_tree(visitor, 0, root_);
|
||||
}
|
||||
|
||||
template <unsigned Levels, typename ValueTraits, uint32_t BlockSize>
|
||||
void
|
||||
btree<Levels, ValueTraits, BlockSize>::
|
||||
walk_tree(typename visitor::ptr visitor,
|
||||
unsigned level, block_address b)
|
||||
{
|
||||
using namespace btree_detail;
|
||||
auto blk = tm_->read_lock(b);
|
||||
auto o = to_node<uint64_traits, BlockSize>(blk);
|
||||
if (o.get_type() == INTERNAL) {
|
||||
visitor->visit_internal(level, o);
|
||||
for (unsigned i = 0; i < o.get_nr_entries(); i++)
|
||||
walk_tree(visitor, level, o.value_at(i));
|
||||
|
||||
} else if (level < Levels - 1) {
|
||||
visitor->visit_internal_leaf(level, o);
|
||||
for (unsigned i = 0; i < o.get_nr_entries(); i++)
|
||||
walk_tree(visitor, level + 1, o.value_at(i));
|
||||
|
||||
} else {
|
||||
auto ov = to_node<ValueTraits, BlockSize>(blk);
|
||||
visitor->visit_leaf(level, ov);
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------
|
||||
|
@ -30,6 +30,28 @@ namespace {
|
||||
new btree<1, uint64_traits, 4096>(
|
||||
create_tm(), rc));
|
||||
}
|
||||
|
||||
class constraint_visitor : public btree<1, uint64_traits, 4096>::visitor {
|
||||
private:
|
||||
void visit_internal(unsigned level, btree_detail::node_ref<uint64_traits, 4096> const &n) {
|
||||
// cout << "internal: level = " << level << ", nr_entries = " << n.get_nr_entries() << endl;
|
||||
}
|
||||
|
||||
void visit_internal_leaf(unsigned level, btree_detail::node_ref<uint64_traits, 4096> const &n) {
|
||||
// cout << "internal_leaf !" << endl;
|
||||
}
|
||||
|
||||
void visit_leaf(unsigned level, btree_detail::node_ref<uint64_traits, 4096> const &n) {
|
||||
// cout << "leaf: level = " << level << ", nr_entries = " << n.get_nr_entries() << endl;
|
||||
}
|
||||
};
|
||||
|
||||
void check_constraints(btree<1, uint64_traits, 4096>::ptr tree) {
|
||||
typedef btree<1, uint64_traits, 4096> tree_type;
|
||||
|
||||
typename tree_type::visitor::ptr v(new constraint_visitor);
|
||||
tree->visit(v);
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------
|
||||
|
Loading…
Reference in New Issue
Block a user