Chinaunix首页 | 论坛 | 博客
  • 博客访问: 900040
  • 博文数量: 119
  • 博客积分: 2493
  • 博客等级: 大尉
  • 技术积分: 2363
  • 用 户 组: 普通用户
  • 注册时间: 2012-06-03 14:00
文章分类

全部博文(119)

文章存档

2013年(19)

2012年(100)

分类: LINUX

2012-08-10 09:46:19

http://blog.chinaunix.net/uid-27033491-id-3305959.html
  1. void rb_insert_color(struct rb_node *node, struct rb_root *root)
  2. //将node节点插入到root为根的树中
  3. {
  4. struct rb_node *parent, *gparent;//定义parent为父节点,gparent为爷爷节点。

  5. while ((parent = rb_parent(node)) && rb_is_red(parent)) //循环出口是父节点颜色不是红色。
  6. {
  7. gparent = rb_parent(parent);//给爷爷节点初始化。

  8. if (parent == gparent->rb_left)//如果parent是左子树。
  9. {
  10. {
  11. register struct rb_node *uncle = gparent->rb_right;//定义node的叔叔节点
  12. //case 1
  13. if (uncle && rb_is_red(uncle))//如果叔叔节点存在,而且是红色。
  14. {
  15. rb_set_black(uncle);//设置叔叔节点为黑色。
  16. rb_set_black(parent);//设置父节点为黑色
  17. rb_set_red(gparent);//设置爷爷节点为红色。
  18. node = gparent;//让node指向爷爷节点,不断从低向上迭代。
  19. continue;
  20. }
  21. }
  22. //case 2
  23. if (parent->rb_right == node) //如果node为右节点。
  24. {
  25. register struct rb_node *tmp;
  26. __rb_rotate_left(parent, root);//以node的父节点为轴,左旋。
  27. tmp = parent;//如果node和parent交换位置。
  28. parent = node;
  29. node = tmp;
  30. }
  31. //case 3
  32. rb_set_black(parent);//设置父节点为黑色。
  33. rb_set_red(gparent);//设置爷爷节点为红色。
  34. __rb_rotate_right(gparent, root);//将爷爷节点右旋。
  35. } else { //如果parent是右子树。和上面的都是对称的。
  36. {
  37. register struct rb_node *uncle = gparent->rb_left;
  38. if (uncle && rb_is_red(uncle))
  39. {
  40. rb_set_black(uncle);
  41. rb_set_black(parent);
  42. rb_set_red(gparent);
  43. node = gparent;
  44. continue;
  45. }
  46. }

  47. if (parent->rb_left == node)
  48. {
  49. register struct rb_node *tmp;
  50. __rb_rotate_right(parent, root);
  51. tmp = parent;
  52. parent = node;
  53. node = tmp;
  54. }

  55. rb_set_black(parent);
  56. rb_set_red(gparent);
  57. __rb_rotate_left(gparent, root);
  58. }
  59. }

  60. rb_set_black(root->rb_node);//最后设置根节点为黑节点。
  61. }
--------------------------------------------------------------------------------------------
  1.  325 /*
  2.  326 * Enqueue an entity into the rb-tree:
  3.  327 */
  4.  328 static void __enqueue_entity(struct cfs_rq *cfs_rq, struct sched_entity *se)
  5.  329 {
  6.  330 struct rb_node **link = &cfs_rq->tasks_timeline.rb_node;//获取红黑树的根。
  7.  331 struct rb_node *parent = NULL;
  8.  332 struct sched_entity *entry;
  9.  333 s64 key = entity_key(cfs_rq, se);//获取该节点的key值。
  10.  334 int leftmost = 1;
  11.  335
  12.  336 /*
  13.  337 * Find the right place in the rbtree:
  14.  338 */
  15.  339 while (*link) { //根据该节点的key值找红黑树中应插入的位置。
  16.  340 parent = *link;
  17.  341 entry = rb_entry(parent, struct sched_entity, run_node);
  18.          //由红黑树的节点返回到调度实体。
  19.  342 /*
  20.  343 * We dont care about collisions. Nodes with
  21.  344 * the same key stay together.
  22.  345 */
  23.  346 if (key < entity_key(cfs_rq, entry)) {
  24.  347 link = &parent->rb_left;
  25.  348 } else {
  26.  349 link = &parent->rb_right;
  27.  350 leftmost = 0;//一旦有朝右走,则将该leftmost标志设置为0
  28.  351 }
  29.  352 }
  30.  353
  31.  354 /*
  32.  355 * Maintain a cache of leftmost tree entries (it is frequently
  33.  356 * used):
  34.  357 */
  35.  358 if (leftmost) //如果在插入新节点的时候,一直都在往左走,
  36.          //则说明新插入的节点插在树的最左边, 则需要更新leftmost值,只要有向右走,该值就不需要更新。
  37.  359 cfs_rq->rb_leftmost = &se->run_node;
  38.      //如果插入节点的插在最左边,则将CFS的运行队列中维护的leftmost指针更新为当前节点。
  39.  360
  40.  361 rb_link_node(&se->run_node, parent, link);
  41.      //将该节点,与parent这个节点链接起来。实际上有两道链接,类似于“双向链表”
  42.  362 rb_insert_color(&se->run_node, &cfs_rq->tasks_timeline);
  43.         //调整红黑树。保证插入一个节点后仍然是红黑树。
  44.  363 }
   my_rb_tree.rar
---------------------------------------------------------------------------------------------
 
阅读(1101) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~