网络子系统41_inet_peer平衡二叉树的删除
//1.p存在左孩子,则使用p的左孩子的最右孩子替换p,然后重平衡树//2.p不存在左孩子,则使用p的右孩子替换p,然后重平衡树1.1 static void unlink_from_pool(struct inet_peer *p){int do_free;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;if (lookup(p->v4daddr,stack) != p)//查找要被删除的节点,路径上所有的节点保存在栈中,p为要删除的节点BUG();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.2struct 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;if (delp[1] != &p->avl_left)BUG();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);elseinet_putpeer(p);}//查找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;\})