[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>
|
template <typename ValueTraits, uint32_t BlockSize>
|
||||||
class node_ref {
|
class node_ref {
|
||||||
public:
|
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;
|
node_type get_type() const;
|
||||||
void set_type(node_type t);
|
void set_type(node_type t);
|
||||||
@ -126,6 +130,7 @@ namespace persistent_data {
|
|||||||
void *key_ptr(unsigned i) const;
|
void *key_ptr(unsigned i) const;
|
||||||
void *value_ptr(unsigned i) const;
|
void *value_ptr(unsigned i) const;
|
||||||
|
|
||||||
|
block_address location_;
|
||||||
disk_node *raw_;
|
disk_node *raw_;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -137,6 +142,7 @@ namespace persistent_data {
|
|||||||
{
|
{
|
||||||
// FIXME: this should return a const read_ref somehow.
|
// FIXME: this should return a const read_ref somehow.
|
||||||
return node_ref<ValueTraits, BlockSize>(
|
return node_ref<ValueTraits, BlockSize>(
|
||||||
|
b.get_location(),
|
||||||
reinterpret_cast<disk_node *>(
|
reinterpret_cast<disk_node *>(
|
||||||
const_cast<unsigned char *>(b.data())));
|
const_cast<unsigned char *>(b.data())));
|
||||||
}
|
}
|
||||||
@ -146,6 +152,7 @@ namespace persistent_data {
|
|||||||
to_node(typename block_manager<BlockSize>::write_ref &b)
|
to_node(typename block_manager<BlockSize>::write_ref &b)
|
||||||
{
|
{
|
||||||
return node_ref<ValueTraits, BlockSize>(
|
return node_ref<ValueTraits, BlockSize>(
|
||||||
|
b.get_location(),
|
||||||
reinterpret_cast<disk_node *>(
|
reinterpret_cast<disk_node *>(
|
||||||
const_cast<unsigned char *>(b.data())));
|
const_cast<unsigned char *>(b.data())));
|
||||||
}
|
}
|
||||||
|
@ -31,19 +31,36 @@ namespace {
|
|||||||
create_tm(), rc));
|
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 {
|
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) {
|
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) {
|
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) {
|
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) {
|
void check_constraints(btree<1, uint64_traits, 4096>::ptr tree) {
|
||||||
@ -59,6 +76,7 @@ namespace {
|
|||||||
BOOST_AUTO_TEST_CASE(empty_btree_contains_nothing)
|
BOOST_AUTO_TEST_CASE(empty_btree_contains_nothing)
|
||||||
{
|
{
|
||||||
auto tree = create_btree();
|
auto tree = create_btree();
|
||||||
|
check_constraints(tree);
|
||||||
|
|
||||||
for (uint64_t i = 0; i < 1000; i++) {
|
for (uint64_t i = 0; i < 1000; i++) {
|
||||||
uint64_t key[1] = {i};
|
uint64_t key[1] = {i};
|
||||||
@ -68,18 +86,21 @@ BOOST_AUTO_TEST_CASE(empty_btree_contains_nothing)
|
|||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(insert_works)
|
BOOST_AUTO_TEST_CASE(insert_works)
|
||||||
{
|
{
|
||||||
unsigned const COUNT = 1000000;
|
unsigned const COUNT = 100000;
|
||||||
|
|
||||||
auto tree = create_btree();
|
auto tree = create_btree();
|
||||||
for (uint64_t i = 0; i < COUNT; i++) {
|
for (uint64_t i = 0; i < COUNT; i++) {
|
||||||
uint64_t key[1] = {i * 7};
|
uint64_t key[1] = {i * 7};
|
||||||
uint64_t value = i;
|
uint64_t value = i;
|
||||||
|
|
||||||
tree->insert(key, value);
|
tree->insert(key, value);
|
||||||
|
|
||||||
auto l = tree->lookup(key);
|
auto l = tree->lookup(key);
|
||||||
BOOST_CHECK(l);
|
BOOST_CHECK(l);
|
||||||
BOOST_CHECK_EQUAL(*l, i);
|
BOOST_CHECK_EQUAL(*l, i);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
check_constraints(tree);
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------
|
//----------------------------------------------------------------
|
||||||
|
Loading…
x
Reference in New Issue
Block a user