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_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 ReducedValue = typename Reduce::value_type;
|
||||
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_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,
|
||||
// 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;
|
||||
}
|
||||
|
||||
this->child_v_[d] = new_x;
|
||||
|
||||
|
|
@ -386,6 +387,35 @@ namespace xo {
|
|||
}
|
||||
} /*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
|
||||
* 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);
|
||||
|
||||
/* insert into left subtree somewhere */
|
||||
RbNode *C = N->child(d);
|
||||
RbNode * C = N->child(d);
|
||||
|
||||
if (!C)
|
||||
break;
|
||||
|
|
@ -835,10 +835,11 @@ namespace xo {
|
|||
if (N) {
|
||||
RbNode * new_node = RbNode::make_leaf(alloc,
|
||||
kv_pair,
|
||||
|
||||
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)));
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue