[btree_t] check for duplicate blocks

This commit is contained in:
Joe Thornber 2011-08-22 14:14:10 +01:00
parent d9e99dc00c
commit 29c2831f3e
2 changed files with 34 additions and 6 deletions

View File

@ -70,7 +70,11 @@ namespace persistent_data {
template <typename ValueTraits, uint32_t BlockSize>
class node_ref {
public:
explicit node_ref(disk_node *raw);
explicit node_ref(block_address b, disk_node *raw);
block_address get_location() const {
return location_;
}
node_type get_type() const;
void set_type(node_type t);
@ -126,6 +130,7 @@ namespace persistent_data {
void *key_ptr(unsigned i) const;
void *value_ptr(unsigned i) const;
block_address location_;
disk_node *raw_;
};
@ -137,6 +142,7 @@ namespace persistent_data {
{
// FIXME: this should return a const read_ref somehow.
return node_ref<ValueTraits, BlockSize>(
b.get_location(),
reinterpret_cast<disk_node *>(
const_cast<unsigned char *>(b.data())));
}
@ -146,6 +152,7 @@ namespace persistent_data {
to_node(typename block_manager<BlockSize>::write_ref &b)
{
return node_ref<ValueTraits, BlockSize>(
b.get_location(),
reinterpret_cast<disk_node *>(
const_cast<unsigned char *>(b.data())));
}

View File

@ -31,19 +31,36 @@ namespace {
create_tm(), rc));
}
// Checks that a btree is well formed.
//
// i) No block should be in the tree more than once.
//
class constraint_visitor : public btree<1, uint64_traits, 4096>::visitor {
private:
public:
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;
check_duplicate_block(n.get_location());
}
void visit_internal_leaf(unsigned level, btree_detail::node_ref<uint64_traits, 4096> const &n) {
// cout << "internal_leaf !" << endl;
check_duplicate_block(n.get_location());
}
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;
check_duplicate_block(n.get_location());
}
private:
void check_duplicate_block(block_address b) {
if (seen_.count(b)) {
ostringstream out;
out << "duplicate block in btree: " << b;
throw runtime_error(out.str());
}
seen_.insert(b);
}
set<block_address> seen_;
};
void check_constraints(btree<1, uint64_traits, 4096>::ptr tree) {
@ -59,6 +76,7 @@ namespace {
BOOST_AUTO_TEST_CASE(empty_btree_contains_nothing)
{
auto tree = create_btree();
check_constraints(tree);
for (uint64_t i = 0; i < 1000; i++) {
uint64_t key[1] = {i};
@ -68,18 +86,21 @@ BOOST_AUTO_TEST_CASE(empty_btree_contains_nothing)
BOOST_AUTO_TEST_CASE(insert_works)
{
unsigned const COUNT = 1000000;
unsigned const COUNT = 100000;
auto tree = create_btree();
for (uint64_t i = 0; i < COUNT; i++) {
uint64_t key[1] = {i * 7};
uint64_t value = i;
tree->insert(key, value);
auto l = tree->lookup(key);
BOOST_CHECK(l);
BOOST_CHECK_EQUAL(*l, i);
}
check_constraints(tree);
}
//----------------------------------------------------------------