interval_tree_generic.h 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187
  1. /* SPDX-License-Identifier: GPL-2.0-or-later */
  2. /*
  3. Interval Trees
  4. (C) 2012 Michel Lespinasse <[email protected]>
  5. include/linux/interval_tree_generic.h
  6. */
  7. #include <linux/rbtree_augmented.h>
  8. /*
  9. * Template for implementing interval trees
  10. *
  11. * ITSTRUCT: struct type of the interval tree nodes
  12. * ITRB: name of struct rb_node field within ITSTRUCT
  13. * ITTYPE: type of the interval endpoints
  14. * ITSUBTREE: name of ITTYPE field within ITSTRUCT holding last-in-subtree
  15. * ITSTART(n): start endpoint of ITSTRUCT node n
  16. * ITLAST(n): last endpoint of ITSTRUCT node n
  17. * ITSTATIC: 'static' or empty
  18. * ITPREFIX: prefix to use for the inline tree definitions
  19. *
  20. * Note - before using this, please consider if generic version
  21. * (interval_tree.h) would work for you...
  22. */
  23. #define INTERVAL_TREE_DEFINE(ITSTRUCT, ITRB, ITTYPE, ITSUBTREE, \
  24. ITSTART, ITLAST, ITSTATIC, ITPREFIX) \
  25. \
  26. /* Callbacks for augmented rbtree insert and remove */ \
  27. \
  28. RB_DECLARE_CALLBACKS_MAX(static, ITPREFIX ## _augment, \
  29. ITSTRUCT, ITRB, ITTYPE, ITSUBTREE, ITLAST) \
  30. \
  31. /* Insert / remove interval nodes from the tree */ \
  32. \
  33. ITSTATIC void ITPREFIX ## _insert(ITSTRUCT *node, \
  34. struct rb_root_cached *root) \
  35. { \
  36. struct rb_node **link = &root->rb_root.rb_node, *rb_parent = NULL; \
  37. ITTYPE start = ITSTART(node), last = ITLAST(node); \
  38. ITSTRUCT *parent; \
  39. bool leftmost = true; \
  40. \
  41. while (*link) { \
  42. rb_parent = *link; \
  43. parent = rb_entry(rb_parent, ITSTRUCT, ITRB); \
  44. if (parent->ITSUBTREE < last) \
  45. parent->ITSUBTREE = last; \
  46. if (start < ITSTART(parent)) \
  47. link = &parent->ITRB.rb_left; \
  48. else { \
  49. link = &parent->ITRB.rb_right; \
  50. leftmost = false; \
  51. } \
  52. } \
  53. \
  54. node->ITSUBTREE = last; \
  55. rb_link_node(&node->ITRB, rb_parent, link); \
  56. rb_insert_augmented_cached(&node->ITRB, root, \
  57. leftmost, &ITPREFIX ## _augment); \
  58. } \
  59. \
  60. ITSTATIC void ITPREFIX ## _remove(ITSTRUCT *node, \
  61. struct rb_root_cached *root) \
  62. { \
  63. rb_erase_augmented_cached(&node->ITRB, root, &ITPREFIX ## _augment); \
  64. } \
  65. \
  66. /* \
  67. * Iterate over intervals intersecting [start;last] \
  68. * \
  69. * Note that a node's interval intersects [start;last] iff: \
  70. * Cond1: ITSTART(node) <= last \
  71. * and \
  72. * Cond2: start <= ITLAST(node) \
  73. */ \
  74. \
  75. static ITSTRUCT * \
  76. ITPREFIX ## _subtree_search(ITSTRUCT *node, ITTYPE start, ITTYPE last) \
  77. { \
  78. while (true) { \
  79. /* \
  80. * Loop invariant: start <= node->ITSUBTREE \
  81. * (Cond2 is satisfied by one of the subtree nodes) \
  82. */ \
  83. if (node->ITRB.rb_left) { \
  84. ITSTRUCT *left = rb_entry(node->ITRB.rb_left, \
  85. ITSTRUCT, ITRB); \
  86. if (start <= left->ITSUBTREE) { \
  87. /* \
  88. * Some nodes in left subtree satisfy Cond2. \
  89. * Iterate to find the leftmost such node N. \
  90. * If it also satisfies Cond1, that's the \
  91. * match we are looking for. Otherwise, there \
  92. * is no matching interval as nodes to the \
  93. * right of N can't satisfy Cond1 either. \
  94. */ \
  95. node = left; \
  96. continue; \
  97. } \
  98. } \
  99. if (ITSTART(node) <= last) { /* Cond1 */ \
  100. if (start <= ITLAST(node)) /* Cond2 */ \
  101. return node; /* node is leftmost match */ \
  102. if (node->ITRB.rb_right) { \
  103. node = rb_entry(node->ITRB.rb_right, \
  104. ITSTRUCT, ITRB); \
  105. if (start <= node->ITSUBTREE) \
  106. continue; \
  107. } \
  108. } \
  109. return NULL; /* No match */ \
  110. } \
  111. } \
  112. \
  113. ITSTATIC ITSTRUCT * \
  114. ITPREFIX ## _iter_first(struct rb_root_cached *root, \
  115. ITTYPE start, ITTYPE last) \
  116. { \
  117. ITSTRUCT *node, *leftmost; \
  118. \
  119. if (!root->rb_root.rb_node) \
  120. return NULL; \
  121. \
  122. /* \
  123. * Fastpath range intersection/overlap between A: [a0, a1] and \
  124. * B: [b0, b1] is given by: \
  125. * \
  126. * a0 <= b1 && b0 <= a1 \
  127. * \
  128. * ... where A holds the lock range and B holds the smallest \
  129. * 'start' and largest 'last' in the tree. For the later, we \
  130. * rely on the root node, which by augmented interval tree \
  131. * property, holds the largest value in its last-in-subtree. \
  132. * This allows mitigating some of the tree walk overhead for \
  133. * for non-intersecting ranges, maintained and consulted in O(1). \
  134. */ \
  135. node = rb_entry(root->rb_root.rb_node, ITSTRUCT, ITRB); \
  136. if (node->ITSUBTREE < start) \
  137. return NULL; \
  138. \
  139. leftmost = rb_entry(root->rb_leftmost, ITSTRUCT, ITRB); \
  140. if (ITSTART(leftmost) > last) \
  141. return NULL; \
  142. \
  143. return ITPREFIX ## _subtree_search(node, start, last); \
  144. } \
  145. \
  146. ITSTATIC ITSTRUCT * \
  147. ITPREFIX ## _iter_next(ITSTRUCT *node, ITTYPE start, ITTYPE last) \
  148. { \
  149. struct rb_node *rb = node->ITRB.rb_right, *prev; \
  150. \
  151. while (true) { \
  152. /* \
  153. * Loop invariants: \
  154. * Cond1: ITSTART(node) <= last \
  155. * rb == node->ITRB.rb_right \
  156. * \
  157. * First, search right subtree if suitable \
  158. */ \
  159. if (rb) { \
  160. ITSTRUCT *right = rb_entry(rb, ITSTRUCT, ITRB); \
  161. if (start <= right->ITSUBTREE) \
  162. return ITPREFIX ## _subtree_search(right, \
  163. start, last); \
  164. } \
  165. \
  166. /* Move up the tree until we come from a node's left child */ \
  167. do { \
  168. rb = rb_parent(&node->ITRB); \
  169. if (!rb) \
  170. return NULL; \
  171. prev = &node->ITRB; \
  172. node = rb_entry(rb, ITSTRUCT, ITRB); \
  173. rb = node->ITRB.rb_right; \
  174. } while (prev == rb); \
  175. \
  176. /* Check if the node intersects [start;last] */ \
  177. if (last < ITSTART(node)) /* !Cond1 */ \
  178. return NULL; \
  179. else if (start <= ITLAST(node)) /* Cond2 */ \
  180. return node; \
  181. } \
  182. }