网络子系统41_inet_peer平衡二叉树的删除
// 二叉树删除节点: // 1.待删除节点存在左孩子,则使用p的左孩子的最右孩子替换p,然后重平衡树 // 2.待删除节点不存在左孩子,则使用p的右孩子替换p,然后重平衡树 // 调用路径:clean_up->unlink_from_pool 1.1 static void unlink_from_pool(struct inet_peer *p) { int do_free = 0; write_lock_bh(&peer_pool_lock); //在clean_up中,会设置refcnt=0的为1,防止其突然被删除 if (atomic_read(&p->refcnt) == 1) {//refcnt=1,说明,此节点没有引用计数 struct inet_peer **stack[PEER_MAXDEPTH]; struct inet_peer ***stackptr, ***delp; delp = stackptr - 1; //*delp[0]指向p节点在栈中的位置 if (p->avl_left == peer_avl_empty) {//如果p节点没有左孩子,情况1.1 *delp[0] = p->avl_right;//*delp[0]指向其右孩子 --stackptr;//stackptr指向p节点 } else {//p节点有左孩子,在左子树中寻找一个节点,替换p,情况1.2 struct inet_peer *t; t = lookup_rightempty(p);//t为p的左孩子的最右孩子 **--stackptr = t->avl_left;//p的左孩子的最右孩子的左孩子,覆盖栈中p的最右孩子 *delp[0] = t;//*delp[0]指向p的左孩子的最右孩子 t->avl_left = p->avl_left; t->avl_right = p->avl_right; t->avl_height = p->avl_height; delp[1] = &t->avl_left; /* was &p->avl_left */ } peer_avl_rebalance(stack, stackptr); peer_total--; do_free = 1; } write_unlock_bh(&peer_pool_lock); if (do_free) kmem_cache_free(peer_cachep, p); else inet_putpeer(p); } // 查找节点左孩子的最右孩子 1.2 #define lookup_rightempty(start) \ ({ \ struct inet_peer *u, **v; \ *stackptr++ = &start->avl_left; //将p的左孩子入栈,此时栈中为p的所有祖先节点,p节点,p的左孩子 \ v = &start->avl_left; \ for (u = *v; u->avl_right != peer_avl_empty; ) { \ v = &u->avl_right; //p的左孩子的右孩子 \ *stackptr++ = v; //入栈,此时栈中为p的所有祖先节点,p节点,p的左孩子,p的左孩子的右孩子 \ u = *v; \ } \ u; \ })
最后更新:2017-04-03 14:53:37