diff --git a/persistent-data/data-structures/btree.h b/persistent-data/data-structures/btree.h index f4130c7..3966148 100644 --- a/persistent-data/data-structures/btree.h +++ b/persistent-data/data-structures/btree.h @@ -161,6 +161,9 @@ namespace persistent_data { return raw_; } + bool value_sizes_match() const; + std::string value_mismatch_string() const; + private: static unsigned calc_max_entries(void); void check_fits_within_block() const; diff --git a/persistent-data/data-structures/btree.tcc b/persistent-data/data-structures/btree.tcc index ef03013..74cbd15 100644 --- a/persistent-data/data-structures/btree.tcc +++ b/persistent-data/data-structures/btree.tcc @@ -362,19 +362,31 @@ namespace persistent_data { } } + template + bool + node_ref::value_sizes_match() const { + return sizeof(typename ValueTraits::disk_type) == get_value_size(); + } + + template + std::string + node_ref::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 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()); - } + if (!value_sizes_match()) + throw std::runtime_error(value_mismatch_string()); unsigned max = calc_max_entries(); diff --git a/persistent-data/data-structures/btree_damage_visitor.h b/persistent-data/data-structures/btree_damage_visitor.h index 1eede99..ca4a069 100644 --- a/persistent-data/data-structures/btree_damage_visitor.h +++ b/persistent-data/data-structures/btree_damage_visitor.h @@ -210,6 +210,7 @@ namespace persistent_data { btree_detail::node_ref const &n) { if (!already_visited(n) && check_block_nr(n) && + check_value_size(n) && check_max_entries(n) && check_nr_entries(n, loc.is_sub_root()) && check_ordered_keys(n) && @@ -229,6 +230,7 @@ namespace persistent_data { btree_detail::node_ref const &n) { if (!already_visited(n) && check_block_nr(n) && + check_value_size(n) && check_max_entries(n) && check_nr_entries(n, loc.is_sub_root()) && check_ordered_keys(n) && @@ -275,6 +277,16 @@ namespace persistent_data { return true; } + template + bool check_value_size(node const &n) { + if (!n.value_sizes_match()) { + report_damage(n.value_mismatch_string()); + return false; + } + + return true; + } + template bool check_max_entries(node const &n) { size_t elt_size = sizeof(uint64_t) + n.get_value_size();