From 256cd16ab3363d9cc537da589bee4f99b5a535d6 Mon Sep 17 00:00:00 2001 From: Joe Thornber Date: Fri, 6 Jun 2014 15:05:41 +0100 Subject: [PATCH] node_ref now checks the value_type sizes match, and the data fits within a single block. --- persistent-data/data-structures/btree.h | 3 +++ persistent-data/data-structures/btree.tcc | 33 ++++++++++++++++++++++- 2 files changed, 35 insertions(+), 1 deletion(-) diff --git a/persistent-data/data-structures/btree.h b/persistent-data/data-structures/btree.h index f060279..e3b6175 100644 --- a/persistent-data/data-structures/btree.h +++ b/persistent-data/data-structures/btree.h @@ -163,12 +163,15 @@ namespace persistent_data { private: static unsigned calc_max_entries(void); + void check_fits_within_block() const; void *key_ptr(unsigned i) const; void *value_ptr(unsigned i) const; block_address location_; disk_node *raw_; + + mutable bool checked_; // flag indicating we've checked the data fits in the block }; //------------------------------------------------ diff --git a/persistent-data/data-structures/btree.tcc b/persistent-data/data-structures/btree.tcc index 9674ade..42ec41e 100644 --- a/persistent-data/data-structures/btree.tcc +++ b/persistent-data/data-structures/btree.tcc @@ -87,7 +87,8 @@ namespace persistent_data { template node_ref::node_ref(block_address location, disk_node *raw) : location_(location), - raw_(raw) + raw_(raw), + checked_(false) { } @@ -330,6 +331,8 @@ namespace persistent_data { void * node_ref::key_ptr(unsigned i) const { + check_fits_within_block(); + return raw_->keys + i; } @@ -337,6 +340,8 @@ namespace persistent_data { void * node_ref::value_ptr(unsigned i) const { + check_fits_within_block(); + void *value_base = &raw_->keys[to_cpu(raw_->header.max_entries)]; return static_cast(value_base) + sizeof(typename ValueTraits::disk_type) * i; @@ -357,6 +362,32 @@ namespace persistent_data { } } + template + void + node_ref::check_fits_within_block() const { + if (checked_) + return; + + if (sizeof(typename ValueTraits::disk_type) != get_value_size()) { + std::ostringstream out; + out << "value size mismatch: expected " << sizeof(typename ValueTraits::disk_type) + << ", but got " << get_value_size() + << ". This is not the btree you are looking for." << std::endl; + throw std::runtime_error(out.str()); + } + + unsigned max = calc_max_entries(); + + if (max < get_nr_entries()) { + std::ostringstream out; + out << "Bad nr of elements: max per block = " + << max << ", actual = " << get_nr_entries() << std::endl; + throw std::runtime_error(out.str()); + } + + checked_ = true; + } + //-------------------------------- template