[btree_t] check for duplicate blocks
This commit is contained in:
parent
d9e99dc00c
commit
29c2831f3e
9
btree.h
9
btree.h
@ -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())));
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------
|
||||
|
Loading…
Reference in New Issue
Block a user