Skip to content

Commit

Permalink
Merge pull request #26 from ytakano/revert-25-issue24
Browse files Browse the repository at this point in the history
Revert "Replace raw pointers in STL containers with unique_ptr"
  • Loading branch information
ytakano authored Jan 29, 2023
2 parents d32b5ea + 9546466 commit f8bc846
Show file tree
Hide file tree
Showing 3 changed files with 92 additions and 119 deletions.
170 changes: 73 additions & 97 deletions radix_tree.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,9 +46,11 @@ class radix_tree {
typedef radix_tree_it<K, T, Compare> iterator;
typedef std::size_t size_type;

radix_tree() : m_size(0), m_predicate(Compare()) { }
explicit radix_tree(Compare pred) : m_size(0), m_predicate(pred) { }
~radix_tree() = default;
radix_tree() : m_size(0), m_root(NULL), m_predicate(Compare()) { }
explicit radix_tree(Compare pred) : m_size(0), m_root(NULL), m_predicate(pred) { }
~radix_tree() {
delete m_root;
}

size_type size() const {
return m_size;
Expand All @@ -57,7 +59,8 @@ class radix_tree {
return m_size == 0;
}
void clear() {
m_root.reset();
delete m_root;
m_root = NULL;
m_size = 0;
}

Expand Down Expand Up @@ -92,7 +95,7 @@ class radix_tree {

private:
size_type m_size;
std::unique_ptr<radix_tree_node<K, T, Compare>> m_root;
radix_tree_node<K, T, Compare>* m_root;

Compare m_predicate;

Expand All @@ -117,7 +120,7 @@ void radix_tree<K, T, Compare>::prefix_match(const K &key, std::vector<iterator>
radix_tree_node<K, T, Compare> *node;
K key_sub1, key_sub2;

node = find_node(key, m_root.get(), 0);
node = find_node(key, m_root, 0);

if (node->m_is_leaf)
node = node->m_parent;
Expand All @@ -141,7 +144,7 @@ typename radix_tree<K, T, Compare>::iterator radix_tree<K, T, Compare>::longest_
radix_tree_node<K, T, Compare> *node;
K key_sub;

node = find_node(key, m_root.get(), 0);
node = find_node(key, m_root, 0);

if (node->m_is_leaf)
return iterator(node);
Expand All @@ -156,8 +159,8 @@ typename radix_tree<K, T, Compare>::iterator radix_tree<K, T, Compare>::longest_
while (node != NULL) {
typename radix_tree_node<K, T, Compare>::it_child it;
it = node->m_children.find(nul);
if (it != node->m_children.end() && it->second.get()->m_is_leaf)
return iterator(it->second.get());
if (it != node->m_children.end() && it->second->m_is_leaf)
return iterator(it->second);

node = node->m_parent;
}
Expand All @@ -180,7 +183,7 @@ typename radix_tree<K, T, Compare>::iterator radix_tree<K, T, Compare>::begin()
if (m_root == NULL || m_size == 0)
node = NULL;
else
node = begin(m_root.get());
node = begin(m_root);

return iterator(node);
}
Expand All @@ -194,7 +197,7 @@ radix_tree_node<K, T, Compare>* radix_tree<K, T, Compare>::begin(radix_tree_node

assert(!node->m_children.empty());

return begin(node->m_children.begin()->second.get());
return begin(node->m_children.begin()->second);
}

template <typename K, typename T, typename Compare>
Expand Down Expand Up @@ -227,7 +230,7 @@ void radix_tree<K, T, Compare>::greedy_match(const K &key, std::vector<iterator>
if (m_root == NULL)
return;

node = find_node(key, m_root.get(), 0);
node = find_node(key, m_root, 0);

if (node->m_is_leaf)
node = node->m_parent;
Expand All @@ -246,7 +249,7 @@ void radix_tree<K, T, Compare>::greedy_match(radix_tree_node<K, T, Compare> *nod
typename std::map<K, radix_tree_node<K, T, Compare>*>::iterator it;

for (it = node->m_children.begin(); it != node->m_children.end(); ++it) {
greedy_match(it->second.get(), vec);
greedy_match(it->second, vec);
}
}

Expand All @@ -267,14 +270,16 @@ bool radix_tree<K, T, Compare>::erase(const K &key)
radix_tree_node<K, T, Compare> *grandparent;
K nul = radix_substr(key, 0, 0);

child = find_node(key, m_root.get(), 0);
child = find_node(key, m_root, 0);

if (! child->m_is_leaf)
return 0;

parent = child->m_parent;
parent->m_children.erase(nul);

delete child;

m_size--;

if (parent == m_root)
Expand All @@ -286,6 +291,7 @@ bool radix_tree<K, T, Compare>::erase(const K &key)
if (parent->m_children.empty()) {
grandparent = parent->m_parent;
grandparent->m_children.erase(parent->m_key);
delete parent;
} else {
grandparent = parent;
}
Expand All @@ -299,25 +305,21 @@ bool radix_tree<K, T, Compare>::erase(const K &key)
typename std::map<K, radix_tree_node<K, T, Compare>*>::iterator it;
it = grandparent->m_children.begin();

auto uncle_ptr = it->second.get();
radix_tree_node<K, T, Compare> *uncle = it->second;

if (uncle_ptr->m_is_leaf)
if (uncle->m_is_leaf)
return 1;

// Transfer ownership of the uncle to a local variable.
std::unique_ptr<radix_tree_node<K, T, Compare>> uncle = std::move(it->second);
grandparent->m_children.erase(it);

uncle->m_depth = grandparent->m_depth;
uncle->m_key = radix_join(grandparent->m_key, uncle->m_key);
uncle->m_parent = grandparent->m_parent;

// Transfer ownership of the uncle to the grandparent's parent's children.
// Local uncle variable is no longer valid after this point.
grandparent->m_parent->m_children[uncle->m_key] = std::move(uncle);

// Erase the grandparent from the grandparent's parent's children.
grandparent->m_children.erase(it);

grandparent->m_parent->m_children.erase(grandparent->m_key);
grandparent->m_parent->m_children[uncle->m_key] = uncle;

delete grandparent;
}

return 1;
Expand All @@ -330,54 +332,43 @@ radix_tree_node<K, T, Compare>* radix_tree<K, T, Compare>::append(radix_tree_nod
int depth;
int len;
K nul = radix_substr(val.first, 0, 0);
std::unique_ptr<radix_tree_node<K, T, Compare>> node_c, node_cc;
radix_tree_node<K, T, Compare> *node_c, *node_cc;

depth = parent->m_depth + radix_length(parent->m_key);
len = radix_length(val.first) - depth;

if (len == 0) {
node_c = std::make_unique<radix_tree_node<K, T, Compare>>(val, m_predicate);

// Grab the raw pointer to return.
auto node_c_ptr = node_c.get();
node_c = new radix_tree_node<K, T, Compare>(val, m_predicate);

node_c->m_depth = depth;
node_c->m_parent = parent;
node_c->m_key = nul;
node_c->m_is_leaf = true;

// Transfer ownership to parent's children map.
// Local node_c variable is no longer valid after this point.
parent->m_children[nul] = std::move(node_c);
parent->m_children[nul] = node_c;

return node_c_ptr;
return node_c;
} else {
node_c = std::make_unique<radix_tree_node<K, T, Compare>>(val, m_predicate);
node_cc = std::make_unique<radix_tree_node<K, T, Compare>>(val, m_predicate);

// Grab the raw pointer to return.
auto node_cc_ptr = node_cc.get();
node_c = new radix_tree_node<K, T, Compare>(val, m_predicate);

K key_sub = radix_substr(val.first, depth, len);

parent->m_children[key_sub] = node_c;

node_c->m_depth = depth;
node_c->m_parent = parent;
node_c->m_key = key_sub;


node_cc = new radix_tree_node<K, T, Compare>(val, m_predicate);
node_c->m_children[nul] = node_cc;

node_cc->m_depth = depth + len;
node_cc->m_parent = node_c.get();
node_cc->m_parent = node_c;
node_cc->m_key = nul;
node_cc->m_is_leaf = true;

// Transfer ownership to node_c's children map.
// Local node_cc variable is no longer valid after this point.
node_c->m_children[nul] = std::move(node_cc);

// Transfer ownership to parent's children map.
// Local node_c variable is no longer valid after this point.
parent->m_children[key_sub] = std::move(node_c);

return node_cc_ptr;
return node_cc;
}
}

Expand All @@ -397,69 +388,53 @@ radix_tree_node<K, T, Compare>* radix_tree<K, T, Compare>::prepend(radix_tree_no

assert(count != 0);

// Transfer ownership to local_node variable.
std::unique_ptr<radix_tree_node<K, T, Compare>> local_node = std::move(node->m_parent->m_children[node->m_key]);
local_node->m_parent->m_children.erase(node->m_key);
node->m_parent->m_children.erase(node->m_key);

std::unique_ptr<radix_tree_node<K, T, Compare>> node_a = std::make_unique<radix_tree_node<K, T, Compare>>(m_predicate);
auto node_a_ptr = node_a.get();
radix_tree_node<K, T, Compare> *node_a = new radix_tree_node<K, T, Compare>(m_predicate);

node_a->m_parent = node->m_parent;
node_a->m_key = radix_substr(node->m_key, 0, count);
node_a->m_depth = node->m_depth;
node_a->m_parent->m_children[node_a->m_key] = node_a;


node->m_depth += count;
node->m_parent = node_a_ptr;
node->m_parent = node_a;
node->m_key = radix_substr(node->m_key, count, len1 - count);

// Transfer ownership of local_node to node's parent's children map.
// Local node is no longer valid after this point.
node->m_parent->m_children[node->m_key] = std::move(local_node);

// Transfer ownership from local node_a variable to node_a's children map.
// Local node_a is no longer valid after this point.
node_a->m_parent->m_children[node_a->m_key] = std::move(node_a);
node->m_parent->m_children[node->m_key] = node;

K nul = radix_substr(val.first, 0, 0);
if (count == len2) {
std::unique_ptr<radix_tree_node<K, T, Compare>> node_b = std::make_unique<radix_tree_node<K, T, Compare>>(val, m_predicate);
// Grab the raw pointer to return.
auto node_b_ptr = node_b.get();
radix_tree_node<K, T, Compare> *node_b;

node_b = new radix_tree_node<K, T, Compare>(val, m_predicate);

node_b->m_parent = node_a_ptr;
node_b->m_parent = node_a;
node_b->m_key = nul;
node_b->m_depth = node_a_ptr->m_depth + count;
node_b->m_depth = node_a->m_depth + count;
node_b->m_is_leaf = true;
node_b->m_parent->m_children[nul] = node_b;

// Transfer ownership to parent's children map.
node_b->m_parent->m_children[nul] = std::move(node_b);

return node_b_ptr;
return node_b;
} else {
std::unique_ptr<radix_tree_node<K, T, Compare>> node_b, node_c;

node_b = std::make_unique<radix_tree_node<K, T, Compare>>(m_predicate);
auto node_b_ptr = node_b.get();
radix_tree_node<K, T, Compare> *node_b, *node_c;

node_c = std::make_unique<radix_tree_node<K, T, Compare>>(val, m_predicate);
auto node_c_ptr = node_c.get();
node_b = new radix_tree_node<K, T, Compare>(m_predicate);

node_b->m_parent = node_a_ptr;
node_b->m_parent = node_a;
node_b->m_depth = node->m_depth;
node_b->m_key = radix_substr(val.first, node_b->m_depth, len2 - count);
node_b->m_parent->m_children[node_b->m_key] = node_b;

node_c = new radix_tree_node<K, T, Compare>(val, m_predicate);

node_c->m_parent = node_b_ptr;
node_c->m_parent = node_b;
node_c->m_depth = radix_length(val.first);
node_c->m_key = nul;
node_c->m_is_leaf = true;

// Transfer ownership to node_b's children map.
node_c->m_parent->m_children[nul] = std::move(node_c);
node_c->m_parent->m_children[nul] = node_c;

// Transfer ownership to parent's children map.
node_b->m_parent->m_children[node_b->m_key] = std::move(node_b);

return node_c_ptr;
return node_c;
}
}

Expand All @@ -469,17 +444,18 @@ std::pair<typename radix_tree<K, T, Compare>::iterator, bool> radix_tree<K, T, C
if (m_root == NULL) {
K nul = radix_substr(val.first, 0, 0);

m_root = std::make_unique<radix_tree_node<K, T, Compare>>(m_predicate);
m_root = new radix_tree_node<K, T, Compare>(m_predicate);
m_root->m_key = nul;
}

radix_tree_node<K, T, Compare>* node = find_node(val.first, m_root.get(), 0);

radix_tree_node<K, T, Compare> *node = find_node(val.first, m_root, 0);

if (node->m_is_leaf) {
return std::pair<iterator, bool>(node, false);
} else if (node == m_root.get()) {
} else if (node == m_root) {
m_size++;
return std::pair<iterator, bool>(append(m_root.get(), val), true);
return std::pair<iterator, bool>(append(m_root, val), true);
} else {
m_size++;
int len = radix_length(node->m_key);
Expand All @@ -499,7 +475,7 @@ typename radix_tree<K, T, Compare>::iterator radix_tree<K, T, Compare>::find(con
if (m_root == NULL)
return iterator(NULL);

radix_tree_node<K, T, Compare> *node = find_node(key, m_root.get(), 0);
radix_tree_node<K, T, Compare> *node = find_node(key, m_root, 0);

// if the node is a internal node, return NULL
if (! node->m_is_leaf)
Expand All @@ -520,19 +496,19 @@ radix_tree_node<K, T, Compare>* radix_tree<K, T, Compare>::find_node(const K &ke
for (it = node->m_children.begin(); it != node->m_children.end(); ++it) {
if (len_key == 0) {
if (it->second->m_is_leaf)
return it->second.get();
return it->second;
else
continue;
}

if (! it->second.get()->m_is_leaf && key[depth] == it->first[0] ) {
if (! it->second->m_is_leaf && key[depth] == it->first[0] ) {
int len_node = radix_length(it->first);
K key_sub = radix_substr(key, depth, len_node);
K key_sub = radix_substr(key, depth, len_node);

if (key_sub == it->first) {
return find_node(key, it->second.get(), depth + len_node);
return find_node(key, it->second, depth+len_node);
} else {
return it->second.get();
return it->second;
}
}
}
Expand Down
Loading

0 comments on commit f8bc846

Please sign in to comment.