xref: /freebsd-src/sys/compat/linuxkpi/common/include/linux/interval_tree_generic.h (revision 4d846d260e2b9a3d4d0a701462568268cbfe7a5b)
1dbc920bdSVladimir Kondratyev /*-
2*4d846d26SWarner Losh  * SPDX-License-Identifier: BSD-2-Clause
3dbc920bdSVladimir Kondratyev  *
4dbc920bdSVladimir Kondratyev  * Copyright (c) 2019 Mark Kettenis <kettenis@OpenBSD.org>
5dbc920bdSVladimir Kondratyev  * Copyright (c) 2021 Vladimir Kondratyev <wulf@FreeBSD.org>
6dbc920bdSVladimir Kondratyev  *
7dbc920bdSVladimir Kondratyev  * Redistribution and use in source and binary forms, with or without
8dbc920bdSVladimir Kondratyev  * modification, are permitted provided that the following conditions
9dbc920bdSVladimir Kondratyev  * are met:
10dbc920bdSVladimir Kondratyev  * 1. Redistributions of source code must retain the above copyright
11dbc920bdSVladimir Kondratyev  *    notice unmodified, this list of conditions, and the following
12dbc920bdSVladimir Kondratyev  *    disclaimer.
13dbc920bdSVladimir Kondratyev  * 2. Redistributions in binary form must reproduce the above copyright
14dbc920bdSVladimir Kondratyev  *    notice, this list of conditions and the following disclaimer in the
15dbc920bdSVladimir Kondratyev  *    documentation and/or other materials provided with the distribution.
16dbc920bdSVladimir Kondratyev  *
17dbc920bdSVladimir Kondratyev  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18dbc920bdSVladimir Kondratyev  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19dbc920bdSVladimir Kondratyev  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20dbc920bdSVladimir Kondratyev  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21dbc920bdSVladimir Kondratyev  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22dbc920bdSVladimir Kondratyev  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23dbc920bdSVladimir Kondratyev  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24dbc920bdSVladimir Kondratyev  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25dbc920bdSVladimir Kondratyev  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26dbc920bdSVladimir Kondratyev  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27dbc920bdSVladimir Kondratyev  */
28dbc920bdSVladimir Kondratyev 
29dbc920bdSVladimir Kondratyev #include <linux/rbtree.h>
30dbc920bdSVladimir Kondratyev 
31dbc920bdSVladimir Kondratyev #define	INTERVAL_TREE_DEFINE(type, field, valtype, dummy, START, LAST, 	\
32dbc920bdSVladimir Kondratyev 		attr, name)						\
33dbc920bdSVladimir Kondratyev 	__IT_DEFINE_ITER_FROM(type, field, valtype, START, LAST, name)	\
34dbc920bdSVladimir Kondratyev 	__IT_DEFINE_ITER_FIRST(type, valtype, attr, name)		\
35dbc920bdSVladimir Kondratyev 	__IT_DEFINE_ITER_NEXT(type, field, valtype, attr, name)		\
36dbc920bdSVladimir Kondratyev 	__IT_DEFINE_INSERT(type, field, START, attr, name)		\
37dbc920bdSVladimir Kondratyev 	__IT_DEFINE_REMOVE(type, field, attr, name)
38dbc920bdSVladimir Kondratyev 
39dbc920bdSVladimir Kondratyev #define	__IT_DEFINE_ITER_FROM(type, field, valtype, START, LAST, name)	\
40dbc920bdSVladimir Kondratyev static inline type *							\
41dbc920bdSVladimir Kondratyev name##_iter_from(struct rb_node *rb, valtype start, valtype last)	\
42dbc920bdSVladimir Kondratyev {									\
43dbc920bdSVladimir Kondratyev 	type *node;							\
44dbc920bdSVladimir Kondratyev 									\
45dbc920bdSVladimir Kondratyev 	while (rb != NULL) {						\
46dbc920bdSVladimir Kondratyev 		node = rb_entry(rb, type, field);			\
47dbc920bdSVladimir Kondratyev 		if (LAST(node) >= start && START(node) <= last)		\
48dbc920bdSVladimir Kondratyev 			return (node);					\
49dbc920bdSVladimir Kondratyev 		else if (START(node) > last)				\
50dbc920bdSVladimir Kondratyev 			break;						\
51dbc920bdSVladimir Kondratyev 		rb = rb_next(rb);					\
52dbc920bdSVladimir Kondratyev 	}								\
53dbc920bdSVladimir Kondratyev 	return (NULL);							\
54dbc920bdSVladimir Kondratyev }
55dbc920bdSVladimir Kondratyev 
56dbc920bdSVladimir Kondratyev #define	__IT_DEFINE_ITER_FIRST(type, valtype, attr, name)		\
57dbc920bdSVladimir Kondratyev attr type *								\
58dbc920bdSVladimir Kondratyev name##_iter_first(struct rb_root_cached *root, valtype start, valtype last) \
59dbc920bdSVladimir Kondratyev {									\
60dbc920bdSVladimir Kondratyev 	return (name##_iter_from(rb_first_cached(root), start, last));	\
61dbc920bdSVladimir Kondratyev }
62dbc920bdSVladimir Kondratyev 
63dbc920bdSVladimir Kondratyev #define	__IT_DEFINE_ITER_NEXT(type, field, valtype, attr, name)		\
64dbc920bdSVladimir Kondratyev attr type *								\
65dbc920bdSVladimir Kondratyev name##_iter_next(type *node, valtype start, valtype last)		\
66dbc920bdSVladimir Kondratyev {									\
67dbc920bdSVladimir Kondratyev 	return (name##_iter_from(rb_next(&node->field), start, last));	\
68dbc920bdSVladimir Kondratyev }
69dbc920bdSVladimir Kondratyev 
70dbc920bdSVladimir Kondratyev #define	__IT_DEFINE_INSERT(type, field, START, attr, name)		\
71dbc920bdSVladimir Kondratyev attr void								\
72dbc920bdSVladimir Kondratyev name##_insert(type *node, struct rb_root_cached *root)			\
73dbc920bdSVladimir Kondratyev {									\
74dbc920bdSVladimir Kondratyev 	struct rb_node **iter = &root->rb_root.rb_node;			\
75dbc920bdSVladimir Kondratyev 	struct rb_node *parent = NULL;					\
76dbc920bdSVladimir Kondratyev 	type *iter_node;						\
77dbc920bdSVladimir Kondratyev 	bool min_entry = true;						\
78dbc920bdSVladimir Kondratyev 									\
79dbc920bdSVladimir Kondratyev 	while (*iter != NULL) {						\
80dbc920bdSVladimir Kondratyev 		parent = *iter;						\
81dbc920bdSVladimir Kondratyev 		iter_node = rb_entry(parent, type, field);		\
82dbc920bdSVladimir Kondratyev 		if (START(node) < START(iter_node))			\
83dbc920bdSVladimir Kondratyev 			iter = &parent->rb_left;			\
84dbc920bdSVladimir Kondratyev 		else {							\
85dbc920bdSVladimir Kondratyev 			iter = &parent->rb_right;			\
86dbc920bdSVladimir Kondratyev 			min_entry = false;				\
87dbc920bdSVladimir Kondratyev 		}							\
88dbc920bdSVladimir Kondratyev 	}								\
89dbc920bdSVladimir Kondratyev 									\
90dbc920bdSVladimir Kondratyev 	rb_link_node(&node->field, parent, iter);			\
91dbc920bdSVladimir Kondratyev 	rb_insert_color_cached(&node->field, root, min_entry);		\
92dbc920bdSVladimir Kondratyev }
93dbc920bdSVladimir Kondratyev 
94dbc920bdSVladimir Kondratyev #define	__IT_DEFINE_REMOVE(type, field, attr, name)			\
95dbc920bdSVladimir Kondratyev attr void								\
96dbc920bdSVladimir Kondratyev name##_remove(type *node, struct rb_root_cached *root)			\
97dbc920bdSVladimir Kondratyev {									\
98dbc920bdSVladimir Kondratyev 	rb_erase_cached(&node->field, root);				\
99dbc920bdSVladimir Kondratyev }
100