rbtree_i.h 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187
  1. /*
  2. * Copyright (c) 2010, 2011 Richard Braun.
  3. * All rights reserved.
  4. *
  5. * Redistribution and use in source and binary forms, with or without
  6. * modification, are permitted provided that the following conditions
  7. * are met:
  8. * 1. Redistributions of source code must retain the above copyright
  9. * notice, this list of conditions and the following disclaimer.
  10. * 2. Redistributions in binary form must reproduce the above copyright
  11. * notice, this list of conditions and the following disclaimer in the
  12. * documentation and/or other materials provided with the distribution.
  13. *
  14. * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
  15. * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  16. * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  17. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
  18. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  19. * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  20. * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  21. * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  22. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  23. * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  24. */
  25. #ifndef _KERN_RBTREE_I_H
  26. #define _KERN_RBTREE_I_H
  27. #include <kern/assert.h>
  28. /*
  29. * Red-black node structure.
  30. *
  31. * To reduce the number of branches and the instruction cache footprint,
  32. * the left and right child pointers are stored in an array, and the symmetry
  33. * of most tree operations is exploited by using left/right variables when
  34. * referring to children.
  35. *
  36. * In addition, this implementation assumes that all nodes are 4-byte aligned,
  37. * so that the least significant bit of the parent member can be used to store
  38. * the color of the node. This is true for all modern 32 and 64 bits
  39. * architectures, as long as the nodes aren't embedded in structures with
  40. * special alignment constraints such as member packing.
  41. */
  42. struct rbtree_node {
  43. unsigned long parent;
  44. struct rbtree_node *children[2];
  45. };
  46. /*
  47. * Red-black tree structure.
  48. */
  49. struct rbtree {
  50. struct rbtree_node *root;
  51. };
  52. /*
  53. * Masks applied on the parent member of a node to obtain either the
  54. * color or the parent address.
  55. */
  56. #define RBTREE_COLOR_MASK 0x1UL
  57. #define RBTREE_PARENT_MASK (~0x3UL)
  58. /*
  59. * Node colors.
  60. */
  61. #define RBTREE_COLOR_RED 0
  62. #define RBTREE_COLOR_BLACK 1
  63. /*
  64. * Masks applied on slots to obtain either the child index or the parent
  65. * address.
  66. */
  67. #define RBTREE_SLOT_INDEX_MASK 0x1UL
  68. #define RBTREE_SLOT_PARENT_MASK (~RBTREE_SLOT_INDEX_MASK)
  69. /*
  70. * Return true if the given pointer is suitably aligned.
  71. */
  72. static inline int rbtree_check_alignment(const struct rbtree_node *node)
  73. {
  74. return ((unsigned long)node & (~RBTREE_PARENT_MASK)) == 0;
  75. }
  76. /*
  77. * Return true if the given index is a valid child index.
  78. */
  79. static inline int rbtree_check_index(int index)
  80. {
  81. return index == (index & 1);
  82. }
  83. /*
  84. * Convert the result of a comparison into an index in the children array
  85. * (0 or 1).
  86. *
  87. * This function is mostly used when looking up a node.
  88. */
  89. static inline int rbtree_d2i(int diff)
  90. {
  91. return !(diff <= 0);
  92. }
  93. /*
  94. * Return the parent of a node.
  95. */
  96. static inline struct rbtree_node * rbtree_parent(const struct rbtree_node *node)
  97. {
  98. return (struct rbtree_node *)(node->parent & RBTREE_PARENT_MASK);
  99. }
  100. /*
  101. * Translate an insertion point into a slot.
  102. */
  103. static inline unsigned long rbtree_slot(struct rbtree_node *parent, int index)
  104. {
  105. assert(rbtree_check_alignment(parent));
  106. assert(rbtree_check_index(index));
  107. return (unsigned long)parent | index;
  108. }
  109. /*
  110. * Extract the parent address from a slot.
  111. */
  112. static inline struct rbtree_node * rbtree_slot_parent(unsigned long slot)
  113. {
  114. return (struct rbtree_node *)(slot & RBTREE_SLOT_PARENT_MASK);
  115. }
  116. /*
  117. * Extract the index from a slot.
  118. */
  119. static inline int rbtree_slot_index(unsigned long slot)
  120. {
  121. return slot & RBTREE_SLOT_INDEX_MASK;
  122. }
  123. /*
  124. * Insert a node in a tree, rebalancing it if necessary.
  125. *
  126. * The index parameter is the index in the children array of the parent where
  127. * the new node is to be inserted. It is ignored if the parent is null.
  128. *
  129. * This function is intended to be used by the rbtree_insert() macro only.
  130. */
  131. void rbtree_insert_rebalance(struct rbtree *tree, struct rbtree_node *parent,
  132. int index, struct rbtree_node *node);
  133. /*
  134. * Return the previous or next node relative to a location in a tree.
  135. *
  136. * The parent and index parameters define the location, which can be empty.
  137. * The direction parameter is either RBTREE_LEFT (to obtain the previous
  138. * node) or RBTREE_RIGHT (to obtain the next one).
  139. */
  140. struct rbtree_node * rbtree_nearest(struct rbtree_node *parent, int index,
  141. int direction);
  142. /*
  143. * Return the first or last node of a tree.
  144. *
  145. * The direction parameter is either RBTREE_LEFT (to obtain the first node)
  146. * or RBTREE_RIGHT (to obtain the last one).
  147. */
  148. struct rbtree_node * rbtree_firstlast(const struct rbtree *tree, int direction);
  149. /*
  150. * Return the node next to, or previous to the given node.
  151. *
  152. * The direction parameter is either RBTREE_LEFT (to obtain the previous node)
  153. * or RBTREE_RIGHT (to obtain the next one).
  154. */
  155. struct rbtree_node * rbtree_walk(struct rbtree_node *node, int direction);
  156. /*
  157. * Return the left-most deepest node of a tree, which is the starting point of
  158. * the postorder traversal performed by rbtree_for_each_remove().
  159. */
  160. struct rbtree_node * rbtree_postwalk_deepest(const struct rbtree *tree);
  161. /*
  162. * Unlink a node from its tree and return the next (right) node in postorder.
  163. */
  164. struct rbtree_node * rbtree_postwalk_unlink(struct rbtree_node *node);
  165. #endif /* _KERN_RBTREE_I_H */