rbtree_i.h 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193
  1. /*
  2. * Copyright (c) 2010-2017 Richard Braun.
  3. *
  4. * This program is free software: you can redistribute it and/or modify
  5. * it under the terms of the GNU General Public License as published by
  6. * the Free Software Foundation, either version 3 of the License, or
  7. * (at your option) any later version.
  8. *
  9. * This program is distributed in the hope that it will be useful,
  10. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. * GNU General Public License for more details.
  13. *
  14. * You should have received a copy of the GNU General Public License
  15. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  16. *
  17. * Upstream site with license notes :
  18. * http://git.sceen.net/rbraun/librbraun.git/
  19. */
  20. #ifndef KERN_RBTREE_I_H
  21. #define KERN_RBTREE_I_H
  22. #include <assert.h>
  23. #include <stddef.h>
  24. #include <stdint.h>
  25. #include <kern/macros.h>
  26. /*
  27. * Red-black node structure.
  28. *
  29. * To reduce the number of branches and the instruction cache footprint,
  30. * the left and right child pointers are stored in an array, and the symmetry
  31. * of most tree operations is exploited by using left/right variables when
  32. * referring to children.
  33. *
  34. * In addition, this implementation assumes that all nodes are 4-byte aligned,
  35. * so that the least significant bit of the parent member can be used to store
  36. * the color of the node. This is true for all modern 32 and 64 bits
  37. * architectures, as long as the nodes aren't embedded in structures with
  38. * special alignment constraints such as member packing.
  39. */
  40. struct rbtree_node {
  41. uintptr_t parent;
  42. struct rbtree_node *children[2];
  43. };
  44. /*
  45. * Red-black tree structure.
  46. */
  47. struct rbtree {
  48. struct rbtree_node *root;
  49. };
  50. /*
  51. * Masks applied on the parent member of a node to obtain either the
  52. * color or the parent address.
  53. */
  54. #define RBTREE_COLOR_MASK ((uintptr_t)0x1)
  55. #define RBTREE_PARENT_MASK (~(uintptr_t)0x3)
  56. /*
  57. * Node colors.
  58. */
  59. #define RBTREE_COLOR_RED 0
  60. #define RBTREE_COLOR_BLACK 1
  61. /*
  62. * Masks applied on slots to obtain either the child index or the parent
  63. * address.
  64. */
  65. #define RBTREE_SLOT_INDEX_MASK 0x1UL
  66. #define RBTREE_SLOT_PARENT_MASK (~RBTREE_SLOT_INDEX_MASK)
  67. /*
  68. * Return true if the given index is a valid child index.
  69. */
  70. static inline int
  71. rbtree_check_index(int index)
  72. {
  73. return index == (index & 1);
  74. }
  75. /*
  76. * Convert the result of a comparison into an index in the children array
  77. * (0 or 1).
  78. *
  79. * This function is mostly used when looking up a node.
  80. */
  81. static inline int
  82. rbtree_d2i(int diff)
  83. {
  84. return !(diff <= 0);
  85. }
  86. /*
  87. * Return true if the given pointer is suitably aligned.
  88. */
  89. static inline int
  90. rbtree_node_check_alignment(const struct rbtree_node *node)
  91. {
  92. return ((uintptr_t)node & (~RBTREE_PARENT_MASK)) == 0;
  93. }
  94. /*
  95. * Return the parent of a node.
  96. */
  97. static inline struct rbtree_node *
  98. rbtree_node_parent(const struct rbtree_node *node)
  99. {
  100. return (struct rbtree_node *)(node->parent & RBTREE_PARENT_MASK);
  101. }
  102. /*
  103. * Translate an insertion point into a slot.
  104. */
  105. static inline rbtree_slot_t
  106. rbtree_slot(struct rbtree_node *parent, int index)
  107. {
  108. assert(rbtree_node_check_alignment(parent));
  109. assert(rbtree_check_index(index));
  110. return (rbtree_slot_t)parent | index;
  111. }
  112. /*
  113. * Extract the parent address from a slot.
  114. */
  115. static inline struct rbtree_node *
  116. rbtree_slot_parent(rbtree_slot_t slot)
  117. {
  118. return (struct rbtree_node *)(slot & RBTREE_SLOT_PARENT_MASK);
  119. }
  120. /*
  121. * Extract the index from a slot.
  122. */
  123. static inline int
  124. rbtree_slot_index(rbtree_slot_t slot)
  125. {
  126. return slot & RBTREE_SLOT_INDEX_MASK;
  127. }
  128. /*
  129. * Insert a node in a tree, rebalancing it if necessary.
  130. *
  131. * The index parameter is the index in the children array of the parent where
  132. * the new node is to be inserted. It is ignored if the parent is NULL.
  133. *
  134. * This function is intended to be used by the rbtree_insert() macro only.
  135. */
  136. void rbtree_insert_rebalance(struct rbtree *tree, struct rbtree_node *parent,
  137. int index, struct rbtree_node *node);
  138. /*
  139. * Return the previous or next node relative to a location in a tree.
  140. *
  141. * The parent and index parameters define the location, which can be empty.
  142. * The direction parameter is either RBTREE_LEFT (to obtain the previous
  143. * node) or RBTREE_RIGHT (to obtain the next one).
  144. */
  145. struct rbtree_node * rbtree_nearest(struct rbtree_node *parent, int index,
  146. int direction);
  147. /*
  148. * Return the first or last node of a tree.
  149. *
  150. * The direction parameter is either RBTREE_LEFT (to obtain the first node)
  151. * or RBTREE_RIGHT (to obtain the last one).
  152. */
  153. struct rbtree_node * rbtree_firstlast(const struct rbtree *tree, int direction);
  154. /*
  155. * Return the node next to, or previous to the given node.
  156. *
  157. * The direction parameter is either RBTREE_LEFT (to obtain the previous node)
  158. * or RBTREE_RIGHT (to obtain the next one).
  159. */
  160. struct rbtree_node * rbtree_walk(struct rbtree_node *node, int direction);
  161. /*
  162. * Return the left-most deepest node of a tree, which is the starting point of
  163. * the postorder traversal performed by rbtree_for_each_remove().
  164. */
  165. struct rbtree_node * rbtree_postwalk_deepest(const struct rbtree *tree);
  166. /*
  167. * Unlink a node from its tree and return the next (right) node in postorder.
  168. */
  169. struct rbtree_node * rbtree_postwalk_unlink(struct rbtree_node *node);
  170. #endif /* KERN_RBTREE_I_H */