这篇开始分析API的实现细节,本文讲rb_link_node
,非常简单
调用示例(还是之前的)
static void __insert_vmap_area(struct vmap_area *va)
{
struct rb_node **p = &vmap_area_root.rb_node;
struct rb_node *parent = NULL;
struct rb_node *tmp;
// 遍历 rb_tree
while (*p) {
struct vmap_area *tmp_va;
parent = *p;
tmp_va = rb_entry(parent, struct vmap_area, rb_node);
// 比较,找到合适的插入位置
if (va->va_start < tmp_va->va_end)
p = &(*p)->rb_left;
else if (va->va_end > tmp_va->va_start)
p = &(*p)->rb_right;
else
BUG();
}
// 插入节点
rb_link_node(&va->rb_node, parent, p);
// 上色
rb_insert_color(&va->rb_node, &vmap_area_root);
//...
}
实现
static inline void rb_link_node(struct rb_node * node, struct rb_node * parent, struct rb_node ** rb_link)
{
node->__rb_parent_color = (unsigned long)parent;
node->rb_left = node->rb_right = NULL;
*rb_link = node;
}
/**
参数:
node - 待插入的 rb_node 的地址(struct rb_node *)
parent - rb-tree 中待插入的父节点的地址(struct rb_node *)
rb_link - 父节点rb_left或rb_right的地址(struct rb_node **) &parent->rb_left or &parent->rb_right (因为是对指针变量赋值,所以参数类型是指针的指针)
功能:
把新节点放到当前树的叶子节点上。
新节点__rb_parent_color设置为parent (struct rb_node *)
新节点rb_left和rb_right设置为NULL
parent的rb_left或rb_right(根据比较的大小判断)设置为新节点地址
只是简单的遍历,并插入,不会调整树结构
*/
callback
之前说__rb_parent_color
保存的是父节点地址和当前节点color , 这里就是先把父节点地址设置了