[btree] Fix ref-counting on overwritten values

This commit is contained in:
Ming-Hung Tsai 2021-09-09 09:58:45 +08:00
parent f8c40a1fda
commit e7fa012701
5 changed files with 44 additions and 9 deletions

View File

@ -22,6 +22,14 @@ namespace era {
uint64_t writeset_root;
};
inline bool operator==(era_detail const& lhs, era_detail const& rhs) {
return lhs.nr_bits == rhs.nr_bits && lhs.writeset_root == rhs.writeset_root;
}
inline bool operator!=(era_detail const& lhs, era_detail const& rhs) {
return !(lhs == rhs);
}
struct era_detail_ref_counter {
era_detail_ref_counter(persistent_data::transaction_manager::ptr tm)
: tm_(tm) {
@ -31,7 +39,7 @@ namespace era {
tm_->get_sm()->inc(d.writeset_root);
}
void dec(persistent_data::block_address b) {
void dec(era_detail const &d) {
// I don't think we ever do this in the tools
throw std::runtime_error("not implemented");
}

View File

@ -693,9 +693,15 @@ namespace persistent_data {
leaf_node n = spine.template get_node<ValueTraits>();
if (need_insert)
n.insert_at(index, key[Levels - 1], value);
else
// FIXME: check if we're overwriting with the same value.
n.set_value(index, value);
else {
typename ValueTraits::value_type old_value = n.value_at(index);
if (value != old_value) {
// do decrement the old value if it already exists
rc_.dec(old_value);
n.set_value(index, value);
}
}
root_ = spine.get_root();
@ -981,11 +987,6 @@ namespace persistent_data {
if (i < 0 || leaf.key_at(i) != key)
i++;
// do decrement the old value if it already exists
// FIXME: I'm not sure about this, I don't understand the |inc| reference
if (static_cast<unsigned>(i) < leaf.get_nr_entries() && leaf.key_at(i) == key && inc) {
// dec old entry
}
*index = i;
return ((static_cast<unsigned>(i) >= leaf.get_nr_entries()) ||

View File

@ -42,6 +42,16 @@ namespace persistent_data {
uint32_t none_free_before_;
};
inline bool operator==(index_entry const& lhs, index_entry const& rhs) {
// The return value doesn't matter, since the ref-counts of bitmap blocks
// are managed by shadow operations.
return false;
}
inline bool operator!=(index_entry const& lhs, index_entry const& rhs) {
return !(lhs == rhs);
}
struct index_entry_traits {
typedef index_entry_disk disk_type;
typedef index_entry value_type;

View File

@ -25,6 +25,14 @@ namespace thin_provisioning {
uint32_t snapshotted_time_;
};
inline bool operator==(device_details const& lhs, device_details const& rhs) {
return false; // device_details are not compariable
}
inline bool operator!=(device_details const& lhs, device_details const& rhs) {
return !(lhs == rhs);
}
struct device_details_traits {
typedef device_details_disk disk_type;
typedef device_details value_type;

View File

@ -24,6 +24,14 @@ namespace thin_provisioning {
uint32_t time_;
};
inline bool operator==(block_time const& lhs, block_time const& rhs) {
return lhs.block_ == rhs.block_;
}
inline bool operator!=(block_time const& lhs, block_time const& rhs) {
return !(lhs == rhs);
}
class block_time_ref_counter {
public:
block_time_ref_counter(space_map::ptr sm);