node_ref now checks the value_type sizes match, and the data fits within a single block.

This commit is contained in:
Joe Thornber 2014-06-06 15:05:41 +01:00
parent cf5d2e3225
commit 256cd16ab3
2 changed files with 35 additions and 1 deletions

View File

@ -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
};
//------------------------------------------------

View File

@ -87,7 +87,8 @@ namespace persistent_data {
template <typename ValueTraits>
node_ref<ValueTraits>::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<ValueTraits>::key_ptr(unsigned i) const
{
check_fits_within_block();
return raw_->keys + i;
}
@ -337,6 +340,8 @@ namespace persistent_data {
void *
node_ref<ValueTraits>::value_ptr(unsigned i) const
{
check_fits_within_block();
void *value_base = &raw_->keys[to_cpu<uint32_t>(raw_->header.max_entries)];
return static_cast<unsigned char *>(value_base) +
sizeof(typename ValueTraits::disk_type) * i;
@ -357,6 +362,32 @@ namespace persistent_data {
}
}
template <typename ValueTraits>
void
node_ref<ValueTraits>::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 <unsigned Levels, typename ValueTraits>