[btree_damage_visitor] Check the value_size agrees.

Patch from Ming-Hung Tsai
This commit is contained in:
Joe Thornber 2015-05-26 12:06:34 +01:00
parent 270c0f7041
commit 85d1701ba1
3 changed files with 34 additions and 7 deletions

View File

@ -161,6 +161,9 @@ namespace persistent_data {
return raw_; return raw_;
} }
bool value_sizes_match() const;
std::string value_mismatch_string() const;
private: private:
static unsigned calc_max_entries(void); static unsigned calc_max_entries(void);
void check_fits_within_block() const; void check_fits_within_block() const;

View File

@ -362,19 +362,31 @@ namespace persistent_data {
} }
} }
template <typename ValueTraits>
bool
node_ref<ValueTraits>::value_sizes_match() const {
return sizeof(typename ValueTraits::disk_type) == get_value_size();
}
template <typename ValueTraits>
std::string
node_ref<ValueTraits>::value_mismatch_string() const {
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;
return out.str();
}
template <typename ValueTraits> template <typename ValueTraits>
void void
node_ref<ValueTraits>::check_fits_within_block() const { node_ref<ValueTraits>::check_fits_within_block() const {
if (checked_) if (checked_)
return; return;
if (sizeof(typename ValueTraits::disk_type) != get_value_size()) { if (!value_sizes_match())
std::ostringstream out; throw std::runtime_error(value_mismatch_string());
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(); unsigned max = calc_max_entries();

View File

@ -210,6 +210,7 @@ namespace persistent_data {
btree_detail::node_ref<block_traits> const &n) { btree_detail::node_ref<block_traits> const &n) {
if (!already_visited(n) && if (!already_visited(n) &&
check_block_nr(n) && check_block_nr(n) &&
check_value_size(n) &&
check_max_entries(n) && check_max_entries(n) &&
check_nr_entries(n, loc.is_sub_root()) && check_nr_entries(n, loc.is_sub_root()) &&
check_ordered_keys(n) && check_ordered_keys(n) &&
@ -229,6 +230,7 @@ namespace persistent_data {
btree_detail::node_ref<ValueTraits2> const &n) { btree_detail::node_ref<ValueTraits2> const &n) {
if (!already_visited(n) && if (!already_visited(n) &&
check_block_nr(n) && check_block_nr(n) &&
check_value_size(n) &&
check_max_entries(n) && check_max_entries(n) &&
check_nr_entries(n, loc.is_sub_root()) && check_nr_entries(n, loc.is_sub_root()) &&
check_ordered_keys(n) && check_ordered_keys(n) &&
@ -275,6 +277,16 @@ namespace persistent_data {
return true; return true;
} }
template <typename node>
bool check_value_size(node const &n) {
if (!n.value_sizes_match()) {
report_damage(n.value_mismatch_string());
return false;
}
return true;
}
template <typename node> template <typename node>
bool check_max_entries(node const &n) { bool check_max_entries(node const &n) {
size_t elt_size = sizeof(uint64_t) + n.get_value_size(); size_t elt_size = sizeof(uint64_t) + n.get_value_size();