[btree] Implement btree::destroy() to delete the entire tree
Also decrease the reference count of the mapped values. (e.g., bitmap blocks of btree_index_store)
This commit is contained in:
parent
4e1ec9326b
commit
f803c44e93
@ -124,6 +124,9 @@ namespace persistent_data {
|
|||||||
template <typename RefCounter>
|
template <typename RefCounter>
|
||||||
void inc_children(RefCounter &rc);
|
void inc_children(RefCounter &rc);
|
||||||
|
|
||||||
|
template <typename RefCounter>
|
||||||
|
void dec_children(RefCounter &rc);
|
||||||
|
|
||||||
disk_node *raw() {
|
disk_node *raw() {
|
||||||
return raw_;
|
return raw_;
|
||||||
}
|
}
|
||||||
|
@ -25,6 +25,7 @@
|
|||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
#include <stack>
|
||||||
|
|
||||||
//----------------------------------------------------------------
|
//----------------------------------------------------------------
|
||||||
|
|
||||||
@ -33,6 +34,56 @@ namespace {
|
|||||||
using namespace persistent_data;
|
using namespace persistent_data;
|
||||||
using namespace btree_detail;
|
using namespace btree_detail;
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
|
struct frame {
|
||||||
|
frame(block_address blocknr,
|
||||||
|
uint32_t level,
|
||||||
|
uint32_t nr_entries)
|
||||||
|
: blocknr_(blocknr),
|
||||||
|
level_(level),
|
||||||
|
nr_entries_(nr_entries),
|
||||||
|
current_child_(0) {
|
||||||
|
}
|
||||||
|
block_address blocknr_;
|
||||||
|
uint32_t level_;
|
||||||
|
uint32_t nr_entries_;
|
||||||
|
uint32_t current_child_;
|
||||||
|
};
|
||||||
|
|
||||||
|
// stack for postorder DFS traversal
|
||||||
|
// TODO: Refactor it into a spine-like class, e.g., btree_del_spine,
|
||||||
|
// "Spine" sounds better for btree operations.
|
||||||
|
struct btree_del_stack {
|
||||||
|
public:
|
||||||
|
btree_del_stack(transaction_manager &tm): tm_(tm) {
|
||||||
|
}
|
||||||
|
|
||||||
|
void push_frame(block_address blocknr,
|
||||||
|
uint32_t level,
|
||||||
|
uint32_t nr_entries) {
|
||||||
|
if (tm_.get_sm()->get_count(blocknr) > 1)
|
||||||
|
tm_.get_sm()->dec(blocknr);
|
||||||
|
else
|
||||||
|
spine_.push(frame(blocknr, level, nr_entries));
|
||||||
|
}
|
||||||
|
|
||||||
|
void pop_frame() {
|
||||||
|
tm_.get_sm()->dec(spine_.top().blocknr_);
|
||||||
|
spine_.pop();
|
||||||
|
}
|
||||||
|
|
||||||
|
frame &top_frame() {
|
||||||
|
return spine_.top();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool is_empty() {
|
||||||
|
return spine_.empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
transaction_manager &tm_;
|
||||||
|
std::stack<frame> spine_;
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------
|
//----------------------------------------------------------------
|
||||||
@ -348,6 +399,21 @@ namespace persistent_data {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename ValueTraits>
|
||||||
|
template <typename RefCounter>
|
||||||
|
void
|
||||||
|
node_ref<ValueTraits>::dec_children(RefCounter &rc)
|
||||||
|
{
|
||||||
|
unsigned nr_entries = get_nr_entries();
|
||||||
|
for (unsigned i = 0; i < nr_entries; i++) {
|
||||||
|
typename ValueTraits::value_type v;
|
||||||
|
typename ValueTraits::disk_type d;
|
||||||
|
::memcpy(&d, value_ptr(i), sizeof(d));
|
||||||
|
ValueTraits::unpack(d, v);
|
||||||
|
rc.dec(v);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
template <typename ValueTraits>
|
template <typename ValueTraits>
|
||||||
bool
|
bool
|
||||||
node_ref<ValueTraits>::value_sizes_match() const {
|
node_ref<ValueTraits>::value_sizes_match() const {
|
||||||
@ -565,15 +631,57 @@ namespace persistent_data {
|
|||||||
return ptr(new btree<Levels, ValueTraits>(tm_, root_, rc_));
|
return ptr(new btree<Levels, ValueTraits>(tm_, root_, rc_));
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
|
||||||
template <unsigned Levels, typename ValueTraits>
|
template <unsigned Levels, typename ValueTraits>
|
||||||
void
|
void
|
||||||
btree<Levels, ValueTraits>::destroy()
|
btree<Levels, ValueTraits>::destroy()
|
||||||
{
|
{
|
||||||
using namespace btree_detail;
|
using namespace btree_detail;
|
||||||
|
|
||||||
|
btree_del_stack s(tm_);
|
||||||
|
|
||||||
|
{
|
||||||
|
read_ref blk = tm_.read_lock(root_, validator_);
|
||||||
|
internal_node n = to_node<block_traits>(blk);
|
||||||
|
s.push_frame(root_, 0, n.get_nr_entries());
|
||||||
|
}
|
||||||
|
|
||||||
|
while (!s.is_empty()) {
|
||||||
|
frame &f = s.top_frame();
|
||||||
|
|
||||||
|
if (f.current_child_ >= f.nr_entries_) {
|
||||||
|
s.pop_frame();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// FIXME: Cache the read_ref object in the stack to avoid temporary objects?
|
||||||
|
read_ref current = tm_.read_lock(f.blocknr_, validator_);
|
||||||
|
internal_node n = to_node<block_traits>(current);
|
||||||
|
|
||||||
|
if (n.get_type() == INTERNAL) {
|
||||||
|
// TODO: test performance penalty of prefetching
|
||||||
|
//if (!f.current_child_)
|
||||||
|
// for (unsigned i = 0; i < n.get_nr_entries(); i++)
|
||||||
|
// tm_.prefetch(n.value_at(i));
|
||||||
|
|
||||||
|
block_address b = n.value_at(f.current_child_);
|
||||||
|
read_ref leaf = tm_.read_lock(b, validator_);
|
||||||
|
internal_node o = to_node<block_traits>(leaf);
|
||||||
|
s.push_frame(b, f.level_, o.get_nr_entries());
|
||||||
|
++f.current_child_;
|
||||||
|
// internal leaf
|
||||||
|
} else if (f.level_ < Levels - 1) {
|
||||||
|
block_address b = n.value_at(f.current_child_);
|
||||||
|
read_ref leaf = tm_.read_lock(b, validator_);
|
||||||
|
internal_node o = to_node<block_traits>(leaf);
|
||||||
|
s.push_frame(b, f.level_ + 1, o.get_nr_entries());
|
||||||
|
++f.current_child_;
|
||||||
|
} else {
|
||||||
|
leaf_node o = to_node<ValueTraits>(current);
|
||||||
|
o.dec_children(rc_); // FIXME: move this into pop_frame()
|
||||||
|
s.pop_frame();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
template <unsigned Levels, typename _>
|
template <unsigned Levels, typename _>
|
||||||
template <typename ValueTraits, typename Search>
|
template <typename ValueTraits, typename Search>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user