node_ref now checks the value_type sizes match, and the data fits within a single block.
This commit is contained in:
parent
cf5d2e3225
commit
256cd16ab3
@ -163,12 +163,15 @@ namespace persistent_data {
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
static unsigned calc_max_entries(void);
|
static unsigned calc_max_entries(void);
|
||||||
|
void check_fits_within_block() const;
|
||||||
|
|
||||||
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_;
|
block_address location_;
|
||||||
disk_node *raw_;
|
disk_node *raw_;
|
||||||
|
|
||||||
|
mutable bool checked_; // flag indicating we've checked the data fits in the block
|
||||||
};
|
};
|
||||||
|
|
||||||
//------------------------------------------------
|
//------------------------------------------------
|
||||||
|
@ -87,7 +87,8 @@ namespace persistent_data {
|
|||||||
template <typename ValueTraits>
|
template <typename ValueTraits>
|
||||||
node_ref<ValueTraits>::node_ref(block_address location, disk_node *raw)
|
node_ref<ValueTraits>::node_ref(block_address location, disk_node *raw)
|
||||||
: location_(location),
|
: location_(location),
|
||||||
raw_(raw)
|
raw_(raw),
|
||||||
|
checked_(false)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -330,6 +331,8 @@ namespace persistent_data {
|
|||||||
void *
|
void *
|
||||||
node_ref<ValueTraits>::key_ptr(unsigned i) const
|
node_ref<ValueTraits>::key_ptr(unsigned i) const
|
||||||
{
|
{
|
||||||
|
check_fits_within_block();
|
||||||
|
|
||||||
return raw_->keys + i;
|
return raw_->keys + i;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -337,6 +340,8 @@ namespace persistent_data {
|
|||||||
void *
|
void *
|
||||||
node_ref<ValueTraits>::value_ptr(unsigned i) const
|
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)];
|
void *value_base = &raw_->keys[to_cpu<uint32_t>(raw_->header.max_entries)];
|
||||||
return static_cast<unsigned char *>(value_base) +
|
return static_cast<unsigned char *>(value_base) +
|
||||||
sizeof(typename ValueTraits::disk_type) * i;
|
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>
|
template <unsigned Levels, typename ValueTraits>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user