xo-ordinaltree: alloc-aware node reparenting. WIP.
This commit is contained in:
parent
c56dd72292
commit
451425af87
3 changed files with 39 additions and 5 deletions
|
|
@ -71,6 +71,9 @@ namespace xo {
|
||||||
using allocator_type = Allocator;
|
using allocator_type = Allocator;
|
||||||
using allocator_traits = xo::gc::gc_allocator_traits<Allocator>;
|
using allocator_traits = xo::gc::gc_allocator_traits<Allocator>;
|
||||||
|
|
||||||
|
/** WARNING:
|
||||||
|
* - GcObjectInterface is typed + assoc type is pair<Key const, Value>.
|
||||||
|
**/
|
||||||
using GcObjectInterface = allocator_traits::object_interface_type;
|
using GcObjectInterface = allocator_traits::object_interface_type;
|
||||||
using ReducedValue = typename Reduce::value_type;
|
using ReducedValue = typename Reduce::value_type;
|
||||||
using RbUtil = detail::RbTreeUtil<Key, Value, Reduce, GcObjectInterface>;
|
using RbUtil = detail::RbTreeUtil<Key, Value, Reduce, GcObjectInterface>;
|
||||||
|
|
|
||||||
|
|
@ -371,13 +371,14 @@ namespace xo {
|
||||||
void assign_size(size_t z) { this->size_ = z; }
|
void assign_size(size_t z) { this->size_ = z; }
|
||||||
|
|
||||||
void assign_child_reparent(Direction d, Node *new_x) {
|
void assign_child_reparent(Direction d, Node *new_x) {
|
||||||
Node *old_x = this->child_v_[d];
|
Node * old_x = this->child_v_[d];
|
||||||
|
|
||||||
// trying to fix old_x can be counterproductive,
|
// trying to fix old_x can be counterproductive,
|
||||||
// since old_x->parent_ may already have been corrected,
|
// since old_x->parent_ may already have been corrected,
|
||||||
//
|
//
|
||||||
if (old_x && (old_x->parent_ == this))
|
if (old_x && (old_x->parent_ == this)) {
|
||||||
old_x->parent_ = nullptr;
|
old_x->parent_ = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
this->child_v_[d] = new_x;
|
this->child_v_[d] = new_x;
|
||||||
|
|
||||||
|
|
@ -386,6 +387,35 @@ namespace xo {
|
||||||
}
|
}
|
||||||
} /*assign_child_reparent*/
|
} /*assign_child_reparent*/
|
||||||
|
|
||||||
|
template <typename NodeAllocator>
|
||||||
|
void assign_child_reparent_2(NodeAllocator & alloc,
|
||||||
|
Direction d,
|
||||||
|
Node * new_x)
|
||||||
|
{
|
||||||
|
Node * old_x = this->child_v_[d];
|
||||||
|
|
||||||
|
using node_allocator_traits = xo::gc::gc_allocator_traits<NodeAllocator>;
|
||||||
|
using kvpair_allocator_type = node_allocator_traits::template rebind_alloc<value_type>;
|
||||||
|
|
||||||
|
kvpair_allocator_type assign_alloc(alloc);
|
||||||
|
|
||||||
|
// trying to fix old_x can be counterproductive,
|
||||||
|
// since old_x->parent_ may already have been corrected,
|
||||||
|
//
|
||||||
|
if (old_x && (old_x->parent_ == this)) {
|
||||||
|
old_x->parent_ = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
Node ** child_addr = &(this->child_v_[d]);
|
||||||
|
this->_gc_assign_member(child_addr, new_x, assign_alloc);
|
||||||
|
//this->child_v_[d] = new_x;
|
||||||
|
|
||||||
|
if (new_x) {
|
||||||
|
this->_gc_assign_member(&(new_x->parent_), this, assign_alloc);
|
||||||
|
//new_x->parent_ = this;
|
||||||
|
}
|
||||||
|
} /*assign_child_reparent*/
|
||||||
|
|
||||||
/* replace child that points to x, with child that points to x_new
|
/* replace child that points to x, with child that points to x_new
|
||||||
* and return direction of the child that was replaced
|
* and return direction of the child that was replaced
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -822,7 +822,7 @@ namespace xo {
|
||||||
d = ((kv_pair.first < N->key()) ? D_Left : D_Right);
|
d = ((kv_pair.first < N->key()) ? D_Left : D_Right);
|
||||||
|
|
||||||
/* insert into left subtree somewhere */
|
/* insert into left subtree somewhere */
|
||||||
RbNode *C = N->child(d);
|
RbNode * C = N->child(d);
|
||||||
|
|
||||||
if (!C)
|
if (!C)
|
||||||
break;
|
break;
|
||||||
|
|
@ -835,10 +835,11 @@ namespace xo {
|
||||||
if (N) {
|
if (N) {
|
||||||
RbNode * new_node = RbNode::make_leaf(alloc,
|
RbNode * new_node = RbNode::make_leaf(alloc,
|
||||||
kv_pair,
|
kv_pair,
|
||||||
|
|
||||||
reduce_fn.leaf(kv_pair.second));
|
reduce_fn.leaf(kv_pair.second));
|
||||||
|
|
||||||
N->assign_child_reparent(d, new_node);
|
N->assign_child_reparent_2(alloc,
|
||||||
|
d,
|
||||||
|
new_node);
|
||||||
|
|
||||||
assert(is_red(N->child(d)));
|
assert(is_red(N->child(d)));
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue