interval_tree_generic.h 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217
  1. /*
  2. Interval Trees
  3. (C) 2012 Michel Lespinasse <walken@google.com>
  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 2 of the License, or
  7. (at your option) any later version.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. GNU General Public License for more details.
  12. You should have received a copy of the GNU General Public License
  13. along with this program; if not, write to the Free Software
  14. Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  15. include/linux/interval_tree_generic.h
  16. */
  17. #include <linux/rbtree_augmented.h>
  18. /*
  19. * Template for implementing interval trees
  20. *
  21. * ITSTRUCT: struct type of the interval tree nodes
  22. * ITRB: name of struct rb_node field within ITSTRUCT
  23. * ITTYPE: type of the interval endpoints
  24. * ITSUBTREE: name of ITTYPE field within ITSTRUCT holding last-in-subtree
  25. * ITSTART(n): start endpoint of ITSTRUCT node n
  26. * ITLAST(n): last endpoint of ITSTRUCT node n
  27. * ITSTATIC: 'static' or empty
  28. * ITPREFIX: prefix to use for the inline tree definitions
  29. *
  30. * Note - before using this, please consider if generic version
  31. * (interval_tree.h) would work for you...
  32. */
  33. #define INTERVAL_TREE_DEFINE(ITSTRUCT, ITRB, ITTYPE, ITSUBTREE, \
  34. ITSTART, ITLAST, ITSTATIC, ITPREFIX) \
  35. \
  36. /* Callbacks for augmented rbtree insert and remove */ \
  37. \
  38. static inline ITTYPE ITPREFIX ## _compute_subtree_last(ITSTRUCT *node) \
  39. { \
  40. ITTYPE max = ITLAST(node), subtree_last; \
  41. if (node->ITRB.rb_left) { \
  42. subtree_last = rb_entry(node->ITRB.rb_left, \
  43. ITSTRUCT, ITRB)->ITSUBTREE; \
  44. if (max < subtree_last) \
  45. max = subtree_last; \
  46. } \
  47. if (node->ITRB.rb_right) { \
  48. subtree_last = rb_entry(node->ITRB.rb_right, \
  49. ITSTRUCT, ITRB)->ITSUBTREE; \
  50. if (max < subtree_last) \
  51. max = subtree_last; \
  52. } \
  53. return max; \
  54. } \
  55. \
  56. RB_DECLARE_CALLBACKS(static, ITPREFIX ## _augment, ITSTRUCT, ITRB, \
  57. ITTYPE, ITSUBTREE, ITPREFIX ## _compute_subtree_last) \
  58. \
  59. /* Insert / remove interval nodes from the tree */ \
  60. \
  61. ITSTATIC void ITPREFIX ## _insert(ITSTRUCT *node, \
  62. struct rb_root_cached *root) \
  63. { \
  64. struct rb_node **link = &root->rb_root.rb_node, *rb_parent = NULL; \
  65. ITTYPE start = ITSTART(node), last = ITLAST(node); \
  66. ITSTRUCT *parent; \
  67. bool leftmost = true; \
  68. \
  69. while (*link) { \
  70. rb_parent = *link; \
  71. parent = rb_entry(rb_parent, ITSTRUCT, ITRB); \
  72. if (parent->ITSUBTREE < last) \
  73. parent->ITSUBTREE = last; \
  74. if (start < ITSTART(parent)) \
  75. link = &parent->ITRB.rb_left; \
  76. else { \
  77. link = &parent->ITRB.rb_right; \
  78. leftmost = false; \
  79. } \
  80. } \
  81. \
  82. node->ITSUBTREE = last; \
  83. rb_link_node(&node->ITRB, rb_parent, link); \
  84. rb_insert_augmented_cached(&node->ITRB, root, \
  85. leftmost, &ITPREFIX ## _augment); \
  86. } \
  87. \
  88. ITSTATIC void ITPREFIX ## _remove(ITSTRUCT *node, \
  89. struct rb_root_cached *root) \
  90. { \
  91. rb_erase_augmented_cached(&node->ITRB, root, &ITPREFIX ## _augment); \
  92. } \
  93. \
  94. /* \
  95. * Iterate over intervals intersecting [start;last] \
  96. * \
  97. * Note that a node's interval intersects [start;last] iff: \
  98. * Cond1: ITSTART(node) <= last \
  99. * and \
  100. * Cond2: start <= ITLAST(node) \
  101. */ \
  102. \
  103. static ITSTRUCT * \
  104. ITPREFIX ## _subtree_search(ITSTRUCT *node, ITTYPE start, ITTYPE last) \
  105. { \
  106. while (true) { \
  107. /* \
  108. * Loop invariant: start <= node->ITSUBTREE \
  109. * (Cond2 is satisfied by one of the subtree nodes) \
  110. */ \
  111. if (node->ITRB.rb_left) { \
  112. ITSTRUCT *left = rb_entry(node->ITRB.rb_left, \
  113. ITSTRUCT, ITRB); \
  114. if (start <= left->ITSUBTREE) { \
  115. /* \
  116. * Some nodes in left subtree satisfy Cond2. \
  117. * Iterate to find the leftmost such node N. \
  118. * If it also satisfies Cond1, that's the \
  119. * match we are looking for. Otherwise, there \
  120. * is no matching interval as nodes to the \
  121. * right of N can't satisfy Cond1 either. \
  122. */ \
  123. node = left; \
  124. continue; \
  125. } \
  126. } \
  127. if (ITSTART(node) <= last) { /* Cond1 */ \
  128. if (start <= ITLAST(node)) /* Cond2 */ \
  129. return node; /* node is leftmost match */ \
  130. if (node->ITRB.rb_right) { \
  131. node = rb_entry(node->ITRB.rb_right, \
  132. ITSTRUCT, ITRB); \
  133. if (start <= node->ITSUBTREE) \
  134. continue; \
  135. } \
  136. } \
  137. return NULL; /* No match */ \
  138. } \
  139. } \
  140. \
  141. ITSTATIC ITSTRUCT * \
  142. ITPREFIX ## _iter_first(struct rb_root_cached *root, \
  143. ITTYPE start, ITTYPE last) \
  144. { \
  145. ITSTRUCT *node, *leftmost; \
  146. \
  147. if (!root->rb_root.rb_node) \
  148. return NULL; \
  149. \
  150. /* \
  151. * Fastpath range intersection/overlap between A: [a0, a1] and \
  152. * B: [b0, b1] is given by: \
  153. * \
  154. * a0 <= b1 && b0 <= a1 \
  155. * \
  156. * ... where A holds the lock range and B holds the smallest \
  157. * 'start' and largest 'last' in the tree. For the later, we \
  158. * rely on the root node, which by augmented interval tree \
  159. * property, holds the largest value in its last-in-subtree. \
  160. * This allows mitigating some of the tree walk overhead for \
  161. * for non-intersecting ranges, maintained and consulted in O(1). \
  162. */ \
  163. node = rb_entry(root->rb_root.rb_node, ITSTRUCT, ITRB); \
  164. if (node->ITSUBTREE < start) \
  165. return NULL; \
  166. \
  167. leftmost = rb_entry(root->rb_leftmost, ITSTRUCT, ITRB); \
  168. if (ITSTART(leftmost) > last) \
  169. return NULL; \
  170. \
  171. return ITPREFIX ## _subtree_search(node, start, last); \
  172. } \
  173. \
  174. ITSTATIC ITSTRUCT * \
  175. ITPREFIX ## _iter_next(ITSTRUCT *node, ITTYPE start, ITTYPE last) \
  176. { \
  177. struct rb_node *rb = node->ITRB.rb_right, *prev; \
  178. \
  179. while (true) { \
  180. /* \
  181. * Loop invariants: \
  182. * Cond1: ITSTART(node) <= last \
  183. * rb == node->ITRB.rb_right \
  184. * \
  185. * First, search right subtree if suitable \
  186. */ \
  187. if (rb) { \
  188. ITSTRUCT *right = rb_entry(rb, ITSTRUCT, ITRB); \
  189. if (start <= right->ITSUBTREE) \
  190. return ITPREFIX ## _subtree_search(right, \
  191. start, last); \
  192. } \
  193. \
  194. /* Move up the tree until we come from a node's left child */ \
  195. do { \
  196. rb = rb_parent(&node->ITRB); \
  197. if (!rb) \
  198. return NULL; \
  199. prev = &node->ITRB; \
  200. node = rb_entry(rb, ITSTRUCT, ITRB); \
  201. rb = node->ITRB.rb_right; \
  202. } while (prev == rb); \
  203. \
  204. /* Check if the node intersects [start;last] */ \
  205. if (last < ITSTART(node)) /* !Cond1 */ \
  206. return NULL; \
  207. else if (start <= ITLAST(node)) /* Cond2 */ \
  208. return node; \
  209. } \
  210. }