Go to the documentation of this file.
35 #ifndef _SYS_INTERVALTREE_H_
36 #define _SYS_INTERVALTREE_H_
38 #if defined(__clang_analyzer__)
39 #define _T_ASSERT(a) assert((a))
60 #define IRB_HEAD(name, type) \
62 struct type *rbh_root; \
65 #define IRB_INITIALIZER(root) \
70 #define IRB_INIT(root) \
72 (root)->rbh_root = NULL; \
77 #define IRB_ENTRY(type) \
79 struct type *rbe_left; \
80 struct type *rbe_right; \
81 struct type *rbe_parent; \
85 #define IRB_LEFT(elm, field) (elm)->field.rbe_left
86 #define IRB_RIGHT(elm, field) (elm)->field.rbe_right
87 #define IRB_PARENT(elm, field) (elm)->field.rbe_parent
88 #define IRB_COLOR(elm, field) (elm)->field.rbe_color
89 #define IRB_ROOT(head) (head)->rbh_root
90 #define IRB_EMPTY(head) (IRB_ROOT(head) == NULL)
92 #define IRB_SET(elm, parent, field) \
94 IRB_PARENT(elm, field) = parent; \
95 IRB_LEFT(elm, field) = IRB_RIGHT(elm, field) = NULL; \
96 IRB_COLOR(elm, field) = IRB_RED; \
99 #define IRB_SET_BLACKRED(black, red, field) \
101 IRB_COLOR(black, field) = IRB_BLACK; \
102 IRB_COLOR(red, field) = IRB_RED; \
111 #define IRB_AUGMENT(x, field) \
115 if (IRB_LEFT(x, field) != NULL) { \
116 x->max = MAX(x->max, IRB_LEFT(x, field)->max); \
118 if (IRB_RIGHT(x, field) != NULL) { \
119 x->max = MAX(x->max, IRB_RIGHT(x, field)->max); \
125 #define IRB_ROTATE_LEFT(head, elm, tmp, field) \
127 (tmp) = IRB_RIGHT(elm, field); \
128 if ((IRB_RIGHT(elm, field) = IRB_LEFT(tmp, field)) != NULL) { \
129 IRB_PARENT(IRB_LEFT(tmp, field), field) = (elm); \
131 if ((IRB_PARENT(tmp, field) = IRB_PARENT(elm, field)) != NULL) { \
132 if ((elm) == IRB_LEFT(IRB_PARENT(elm, field), field)) \
133 IRB_LEFT(IRB_PARENT(elm, field), field) = (tmp); \
135 IRB_RIGHT(IRB_PARENT(elm, field), field) = (tmp); \
137 (head)->rbh_root = (tmp); \
138 IRB_LEFT(tmp, field) = (elm); \
139 IRB_PARENT(elm, field) = (tmp); \
140 IRB_AUGMENT(elm, field); \
141 IRB_AUGMENT(tmp, field); \
142 if ((IRB_PARENT(tmp, field))) \
143 IRB_AUGMENT(IRB_PARENT(tmp, field), field); \
146 #define IRB_ROTATE_RIGHT(head, elm, tmp, field) \
148 (tmp) = IRB_LEFT(elm, field); \
149 if ((IRB_LEFT(elm, field) = IRB_RIGHT(tmp, field)) != NULL) { \
150 IRB_PARENT(IRB_RIGHT(tmp, field), field) = (elm); \
152 if ((IRB_PARENT(tmp, field) = IRB_PARENT(elm, field)) != NULL) { \
153 if ((elm) == IRB_LEFT(IRB_PARENT(elm, field), field)) \
154 IRB_LEFT(IRB_PARENT(elm, field), field) = (tmp); \
156 IRB_RIGHT(IRB_PARENT(elm, field), field) = (tmp); \
158 (head)->rbh_root = (tmp); \
159 IRB_RIGHT(tmp, field) = (elm); \
160 IRB_PARENT(elm, field) = (tmp); \
161 IRB_AUGMENT(elm, field); \
162 IRB_AUGMENT(tmp, field); \
163 if ((IRB_PARENT(tmp, field))) \
164 IRB_AUGMENT(IRB_PARENT(tmp, field), field); \
168 #define IRB_PROTOTYPE(name, type, field, cmp) IRB_PROTOTYPE_INTERNAL(name, type, field, cmp, )
169 #define IRB_PROTOTYPE_STATIC(name, type, field, cmp) \
170 IRB_PROTOTYPE_INTERNAL(name, type, field, cmp, __unused static)
171 #define IRB_PROTOTYPE_INTERNAL(name, type, field, cmp, attr) \
172 IRB_PROTOTYPE_INSERT_COLOR(name, type, attr); \
173 IRB_PROTOTYPE_REMOVE_COLOR(name, type, attr); \
174 IRB_PROTOTYPE_INSERT(name, type, attr); \
175 IRB_PROTOTYPE_REMOVE(name, type, attr); \
176 IRB_PROTOTYPE_FIND(name, type, attr); \
177 IRB_PROTOTYPE_NFIND(name, type, attr); \
178 IRB_PROTOTYPE_NEXT(name, type, attr); \
179 IRB_PROTOTYPE_PREV(name, type, attr); \
180 IRB_PROTOTYPE_MINMAX(name, type, attr);
181 #define IRB_PROTOTYPE_INSERT_COLOR(name, type, attr) \
182 attr void name##_IRB_INSERT_COLOR(struct name *, struct type *)
183 #define IRB_PROTOTYPE_REMOVE_COLOR(name, type, attr) \
184 attr void name##_IRB_REMOVE_COLOR(struct name *, struct type *, struct type *)
185 #define IRB_PROTOTYPE_REMOVE(name, type, attr) \
186 attr struct type *name##_IRB_REMOVE(struct name *, struct type *)
187 #define IRB_PROTOTYPE_INSERT(name, type, attr) \
188 attr struct type *name##_IRB_INSERT(struct name *, struct type *)
189 #define IRB_PROTOTYPE_FIND(name, type, attr) \
190 attr struct type *name##_IRB_FIND(struct name *, struct type *)
191 #define IRB_PROTOTYPE_NFIND(name, type, attr) \
192 attr struct type *name##_IRB_NFIND(struct name *, struct type *)
193 #define IRB_PROTOTYPE_NEXT(name, type, attr) attr struct type *name##_IRB_NEXT(struct type *)
194 #define IRB_PROTOTYPE_PREV(name, type, attr) attr struct type *name##_IRB_PREV(struct type *)
195 #define IRB_PROTOTYPE_MINMAX(name, type, attr) \
196 attr struct type *name##_IRB_MINMAX(struct name *, int)
201 #define IRB_GENERATE(name, type, field, cmp) IRB_GENERATE_INTERNAL(name, type, field, cmp, )
202 #define IRB_GENERATE_STATIC(name, type, field, cmp) \
203 IRB_GENERATE_INTERNAL(name, type, field, cmp, __unused static)
204 #define IRB_GENERATE_INTERNAL(name, type, field, cmp, attr) \
205 IRB_GENERATE_INSERT_COLOR(name, type, field, attr) \
206 IRB_GENERATE_REMOVE_COLOR(name, type, field, attr) \
207 IRB_GENERATE_INSERT(name, type, field, cmp, attr) \
208 IRB_GENERATE_REMOVE(name, type, field, attr) \
209 IRB_GENERATE_FIND(name, type, field, cmp, attr) \
210 IRB_GENERATE_NFIND(name, type, field, cmp, attr) \
211 IRB_GENERATE_NEXT(name, type, field, attr) \
212 IRB_GENERATE_PREV(name, type, field, attr) \
213 IRB_GENERATE_MINMAX(name, type, field, attr)
215 #define IRB_GENERATE_INSERT_COLOR(name, type, field, attr) \
216 attr void name##_IRB_INSERT_COLOR(struct name *head, struct type *elm) \
218 struct type *parent, *gparent, *tmp; \
219 while ((parent = IRB_PARENT(elm, field)) != NULL && IRB_COLOR(parent, field) == IRB_RED) { \
220 gparent = IRB_PARENT(parent, field); \
221 _T_ASSERT(gparent); \
222 if (parent == IRB_LEFT(gparent, field)) { \
223 tmp = IRB_RIGHT(gparent, field); \
224 if (tmp && IRB_COLOR(tmp, field) == IRB_RED) { \
225 IRB_COLOR(tmp, field) = IRB_BLACK; \
226 IRB_SET_BLACKRED(parent, gparent, field); \
230 if (IRB_RIGHT(parent, field) == elm) { \
231 IRB_ROTATE_LEFT(head, parent, tmp, field); \
236 IRB_SET_BLACKRED(parent, gparent, field); \
237 IRB_ROTATE_RIGHT(head, gparent, tmp, field); \
239 tmp = IRB_LEFT(gparent, field); \
240 if (tmp && IRB_COLOR(tmp, field) == IRB_RED) { \
241 IRB_COLOR(tmp, field) = IRB_BLACK; \
242 IRB_SET_BLACKRED(parent, gparent, field); \
246 if (IRB_LEFT(parent, field) == elm) { \
247 IRB_ROTATE_RIGHT(head, parent, tmp, field); \
252 IRB_SET_BLACKRED(parent, gparent, field); \
253 IRB_ROTATE_LEFT(head, gparent, tmp, field); \
256 IRB_COLOR(head->rbh_root, field) = IRB_BLACK; \
259 #define IRB_GENERATE_REMOVE_COLOR(name, type, field, attr) \
260 attr void name##_IRB_REMOVE_COLOR(struct name *head, struct type *parent, struct type *elm) \
263 while ((elm == NULL || IRB_COLOR(elm, field) == IRB_BLACK) && elm != IRB_ROOT(head)) { \
264 if (IRB_LEFT(parent, field) == elm) { \
265 tmp = IRB_RIGHT(parent, field); \
266 if (IRB_COLOR(tmp, field) == IRB_RED) { \
267 IRB_SET_BLACKRED(tmp, parent, field); \
268 IRB_ROTATE_LEFT(head, parent, tmp, field); \
269 tmp = IRB_RIGHT(parent, field); \
272 if ((IRB_LEFT(tmp, field) == NULL || \
273 IRB_COLOR(IRB_LEFT(tmp, field), field) == IRB_BLACK) && \
274 (IRB_RIGHT(tmp, field) == NULL || \
275 IRB_COLOR(IRB_RIGHT(tmp, field), field) == IRB_BLACK)) { \
276 IRB_COLOR(tmp, field) = IRB_RED; \
278 parent = IRB_PARENT(elm, field); \
280 if (IRB_RIGHT(tmp, field) == NULL || \
281 IRB_COLOR(IRB_RIGHT(tmp, field), field) == IRB_BLACK) { \
282 struct type *oleft; \
283 if ((oleft = IRB_LEFT(tmp, field)) != NULL) \
284 IRB_COLOR(oleft, field) = IRB_BLACK; \
285 IRB_COLOR(tmp, field) = IRB_RED; \
286 IRB_ROTATE_RIGHT(head, tmp, oleft, field); \
287 tmp = IRB_RIGHT(parent, field); \
289 IRB_COLOR(tmp, field) = IRB_COLOR(parent, field); \
290 IRB_COLOR(parent, field) = IRB_BLACK; \
291 if (IRB_RIGHT(tmp, field)) \
292 IRB_COLOR(IRB_RIGHT(tmp, field), field) = IRB_BLACK; \
293 IRB_ROTATE_LEFT(head, parent, tmp, field); \
294 elm = IRB_ROOT(head); \
298 tmp = IRB_LEFT(parent, field); \
299 if (IRB_COLOR(tmp, field) == IRB_RED) { \
300 IRB_SET_BLACKRED(tmp, parent, field); \
301 IRB_ROTATE_RIGHT(head, parent, tmp, field); \
302 tmp = IRB_LEFT(parent, field); \
305 if ((IRB_LEFT(tmp, field) == NULL || \
306 IRB_COLOR(IRB_LEFT(tmp, field), field) == IRB_BLACK) && \
307 (IRB_RIGHT(tmp, field) == NULL || \
308 IRB_COLOR(IRB_RIGHT(tmp, field), field) == IRB_BLACK)) { \
309 IRB_COLOR(tmp, field) = IRB_RED; \
311 parent = IRB_PARENT(elm, field); \
313 if (IRB_LEFT(tmp, field) == NULL || \
314 IRB_COLOR(IRB_LEFT(tmp, field), field) == IRB_BLACK) { \
315 struct type *oright; \
316 if ((oright = IRB_RIGHT(tmp, field)) != NULL) \
317 IRB_COLOR(oright, field) = IRB_BLACK; \
318 IRB_COLOR(tmp, field) = IRB_RED; \
319 IRB_ROTATE_LEFT(head, tmp, oright, field); \
320 tmp = IRB_LEFT(parent, field); \
322 IRB_COLOR(tmp, field) = IRB_COLOR(parent, field); \
323 IRB_COLOR(parent, field) = IRB_BLACK; \
324 if (IRB_LEFT(tmp, field)) \
325 IRB_COLOR(IRB_LEFT(tmp, field), field) = IRB_BLACK; \
326 IRB_ROTATE_RIGHT(head, parent, tmp, field); \
327 elm = IRB_ROOT(head); \
333 IRB_COLOR(elm, field) = IRB_BLACK; \
336 #define IRB_GENERATE_REMOVE(name, type, field, attr) \
337 attr struct type *name##_IRB_REMOVE(struct name *head, struct type *elm) \
339 struct type *child, *parent, *old = elm; \
341 if (IRB_LEFT(elm, field) == NULL) \
342 child = IRB_RIGHT(elm, field); \
343 else if (IRB_RIGHT(elm, field) == NULL) \
344 child = IRB_LEFT(elm, field); \
347 elm = IRB_RIGHT(elm, field); \
348 while ((left = IRB_LEFT(elm, field)) != NULL) \
350 child = IRB_RIGHT(elm, field); \
351 parent = IRB_PARENT(elm, field); \
352 color = IRB_COLOR(elm, field); \
354 IRB_PARENT(child, field) = parent; \
356 if (IRB_LEFT(parent, field) == elm) \
357 IRB_LEFT(parent, field) = child; \
359 IRB_RIGHT(parent, field) = child; \
360 IRB_AUGMENT(parent, field); \
362 IRB_ROOT(head) = child; \
363 if (IRB_PARENT(elm, field) == old) \
366 (elm)->field = (old)->field; \
367 if (IRB_PARENT(old, field)) { \
368 if (IRB_LEFT(IRB_PARENT(old, field), field) == old) \
369 IRB_LEFT(IRB_PARENT(old, field), field) = elm; \
371 IRB_RIGHT(IRB_PARENT(old, field), field) = elm; \
372 IRB_AUGMENT(IRB_PARENT(old, field), field); \
374 IRB_ROOT(head) = elm; \
376 _T_ASSERT(IRB_LEFT(old, field)); \
377 IRB_PARENT(IRB_LEFT(old, field), field) = elm; \
378 if (IRB_RIGHT(old, field)) \
379 IRB_PARENT(IRB_RIGHT(old, field), field) = elm; \
383 IRB_AUGMENT(left, field); \
384 } while ((left = IRB_PARENT(left, field)) != NULL); \
388 parent = IRB_PARENT(elm, field); \
389 color = IRB_COLOR(elm, field); \
391 IRB_PARENT(child, field) = parent; \
393 if (IRB_LEFT(parent, field) == elm) \
394 IRB_LEFT(parent, field) = child; \
396 IRB_RIGHT(parent, field) = child; \
397 IRB_AUGMENT(parent, field); \
399 IRB_ROOT(head) = child; \
401 if (color == IRB_BLACK) \
402 name##_IRB_REMOVE_COLOR(head, parent, child); \
406 #define IRB_GENERATE_INSERT(name, type, field, cmp, attr) \
408 attr struct type *name##_IRB_INSERT(struct name *head, struct type *elm) \
411 struct type *parent = NULL; \
413 tmp = IRB_ROOT(head); \
416 comp = (cmp)(elm, parent); \
418 tmp = IRB_LEFT(tmp, field); \
419 } else if (comp > 0) { \
420 tmp = IRB_RIGHT(tmp, field); \
424 IRB_SET(elm, parent, field); \
425 if (parent != NULL) { \
427 IRB_LEFT(parent, field) = elm; \
429 IRB_RIGHT(parent, field) = elm; \
431 IRB_ROOT(head) = elm; \
432 IRB_AUGMENT(elm, field); \
433 name##_IRB_INSERT_COLOR(head, elm); \
437 #define IRB_GENERATE_FIND(name, type, field, cmp, attr) \
439 attr struct type *name##_IRB_FIND(struct name *head, struct type *elm) \
441 struct type *tmp = IRB_ROOT(head); \
444 comp = cmp(elm, tmp); \
446 tmp = IRB_LEFT(tmp, field); \
448 tmp = IRB_RIGHT(tmp, field); \
455 #define IRB_GENERATE_NFIND(name, type, field, cmp, attr) \
457 attr struct type *name##_IRB_NFIND(struct name *head, struct type *elm) \
459 struct type *tmp = IRB_ROOT(head); \
460 struct type *res = NULL; \
463 comp = cmp(elm, tmp); \
466 tmp = IRB_LEFT(tmp, field); \
467 } else if (comp > 0) \
468 tmp = IRB_RIGHT(tmp, field); \
475 #define IRB_GENERATE_NEXT(name, type, field, attr) \
477 attr struct type *name##_IRB_NEXT(struct type *elm) \
479 if (IRB_RIGHT(elm, field)) { \
480 elm = IRB_RIGHT(elm, field); \
481 while (IRB_LEFT(elm, field)) \
482 elm = IRB_LEFT(elm, field); \
484 if (IRB_PARENT(elm, field) && (elm == IRB_LEFT(IRB_PARENT(elm, field), field))) \
485 elm = IRB_PARENT(elm, field); \
487 while (IRB_PARENT(elm, field) && \
488 (elm == IRB_RIGHT(IRB_PARENT(elm, field), field))) \
489 elm = IRB_PARENT(elm, field); \
490 elm = IRB_PARENT(elm, field); \
496 #define IRB_GENERATE_PREV(name, type, field, attr) \
498 attr struct type *name##_IRB_PREV(struct type *elm) \
500 if (IRB_LEFT(elm, field)) { \
501 elm = IRB_LEFT(elm, field); \
502 while (IRB_RIGHT(elm, field)) \
503 elm = IRB_RIGHT(elm, field); \
505 if (IRB_PARENT(elm, field) && (elm == IRB_RIGHT(IRB_PARENT(elm, field), field))) \
506 elm = IRB_PARENT(elm, field); \
508 while (IRB_PARENT(elm, field) && (elm == IRB_LEFT(IRB_PARENT(elm, field), field))) \
509 elm = IRB_PARENT(elm, field); \
510 elm = IRB_PARENT(elm, field); \
516 #define IRB_GENERATE_MINMAX(name, type, field, attr) \
517 attr struct type *name##_IRB_MINMAX(struct name *head, int val) \
519 struct type *tmp = IRB_ROOT(head); \
520 struct type *parent = NULL; \
524 tmp = IRB_LEFT(tmp, field); \
526 tmp = IRB_RIGHT(tmp, field); \
531 #define IRB_NEGINF -1
534 #define IRB_INSERT(name, x, y) name##_IRB_INSERT(x, y)
535 #define IRB_REMOVE(name, x, y) name##_IRB_REMOVE(x, y)
536 #define IRB_FIND(name, x, y) name##_IRB_FIND(x, y)
537 #define IRB_NFIND(name, x, y) name##_IRB_NFIND(x, y)
538 #define IRB_NEXT(name, x, y) name##_IRB_NEXT(y)
539 #define IRB_PREV(name, x, y) name##_IRB_PREV(y)
540 #define IRB_MIN(name, x) name##_IRB_MINMAX(x, IRB_NEGINF)
541 #define IRB_MAX(name, x) name##_IRB_MINMAX(x, IRB_INF)
543 #define IRB_FOREACH(x, name, head) \
544 for ((x) = IRB_MIN(name, head); (x) != NULL; (x) = name##_IRB_NEXT(x))
546 #define IRB_FOREACH_FROM(x, name, y) \
547 for ((x) = (y); ((x) != NULL) && ((y) = name##_IRB_NEXT(x), (x) != NULL); (x) = (y))
549 #define IRB_FOREACH_SAFE(x, name, head, y) \
550 for ((x) = IRB_MIN(name, head); ((x) != NULL) && ((y) = name##_IRB_NEXT(x), (x) != NULL); \
553 #define IRB_FOREACH_REVERSE(x, name, head) \
554 for ((x) = IRB_MAX(name, head); (x) != NULL; (x) = name##_IRB_PREV(x))
556 #define IRB_FOREACH_REVERSE_FROM(x, name, y) \
557 for ((x) = (y); ((x) != NULL) && ((y) = name##_IRB_PREV(x), (x) != NULL); (x) = (y))
559 #define IRB_FOREACH_REVERSE_SAFE(x, name, head, y) \
560 for ((x) = IRB_MAX(name, head); ((x) != NULL) && ((y) = name##_IRB_PREV(x), (x) != NULL); \