linux内存管理中红黑树算法源码详解
linux内存管理模块中使用红黑树算法来提升虚拟内存查找速度,源码请参考linux内核目录下rbtree.c文件。
红黑树算法原理
在阅读红黑树算法源代码之前最好先了解红黑树原理,维基百科上有一篇文章讲得非常详细:http://zh.wikipedia.org/zh/%E7%BA%A2%E9%BB%91%E6%A0%91
rb_insert_color函数详解:
void rb_insert_color(rb_node_t * node, rb_root_t * root)
{
rb_node_t * parent, * gparent;
while ((parent = node->rb_parent) && parent->rb_color == RB_RED)
{
gparent = parent->rb_parent;
if (parent == gparent->rb_left)
{
{
register rb_node_t * uncle = gparent->rb_right;
if (uncle && uncle->rb_color == RB_RED)
{
uncle->rb_color = RB_BLACK;
parent->rb_color = RB_BLACK;
gparent->rb_color = RB_RED;
node = gparent;
continue;
}
}
if (parent->rb_right == node)
{
register rb_node_t * tmp;
__rb_rotate_left(parent, root);
tmp = parent;
parent = node;
node = tmp;
}
parent->rb_color = RB_BLACK;
gparent->rb_color = RB_RED;
__rb_rotate_right(gparent, root);
} else {
{
register rb_node_t * uncle = gparent->rb_left;
if (uncle && uncle->rb_color == RB_RED)
{
uncle->rb_color = RB_BLACK;
parent->rb_color = RB_BLACK;
gparent->rb_color = RB_RED;
node = gparent;
continue;
}
}
if (parent->rb_left == node)
{
register rb_node_t * tmp;
__rb_rotate_right(parent, root);
tmp = parent;
parent = node;
node = tmp;
}
parent->rb_color = RB_BLACK;
gparent->rb_color = RB_RED;
__rb_rotate_left(gparent, root);
}
}
root->rb_node->rb_color = RB_BLACK;
}
注解:
函数参数
node:新插入的结点。
root:红黑树的根结点。
第5行:往红黑树中插入结点时,总是将新插入结点颜色设置为红色。当新结点的父结点不存在或者父结点颜色为黑色时,不需要做红黑树调整直接跳到第63行。
第7行:获取node结点的祖父结点。
(第9-35行 处理node父结点是其祖父结点左子结点的情况)
第12行:获取node的叔父结点。
第13-20行:当叔父结点存在并且颜色为红色,就将node的父结点与叔父结点的颜色设成黑色,并且将node的祖父结点颜色设成红色。现在祖父结点的颜色为红色,但祖父结点的父结点也可能为红色,不满足红黑树性质,因此将祖父结点当做新插入的结点重新进行红黑树调整。
第23-30行:叔父结点不存在或者颜色为黑色,此时node的祖父结点颜色必为黑色(因为node父结点颜色为红色),针对node的父结点进行一次左旋转