blob: 64816a29b6b4d752f7bc24d8648658c10a78e8e2 [file] [log] [blame]
Willy Tarreauc2186022009-10-26 19:48:54 +01001/*
2 * Elastic Binary Trees - macros and structures for operations on pointer nodes.
Willy Tarreauf3bfede2011-07-25 11:38:17 +02003 * Version 6.0.6
4 * (C) 2002-2011 - Willy Tarreau <w@1wt.eu>
Willy Tarreauc2186022009-10-26 19:48:54 +01005 *
Willy Tarreauf3bfede2011-07-25 11:38:17 +02006 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation, version 2.1
9 * exclusively.
Willy Tarreauc2186022009-10-26 19:48:54 +010010 *
Willy Tarreauf3bfede2011-07-25 11:38:17 +020011 * This library is distributed in the hope that it will be useful,
Willy Tarreauc2186022009-10-26 19:48:54 +010012 * but WITHOUT ANY WARRANTY; without even the implied warranty of
Willy Tarreauf3bfede2011-07-25 11:38:17 +020013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
Willy Tarreauc2186022009-10-26 19:48:54 +010015 *
Willy Tarreauf3bfede2011-07-25 11:38:17 +020016 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Willy Tarreauc2186022009-10-26 19:48:54 +010019 */
20
21#ifndef _EBPTTREE_H
22#define _EBPTTREE_H
23
24#include "ebtree.h"
25#include "eb32tree.h"
26#include "eb64tree.h"
27
28
29/* Return the structure of type <type> whose member <member> points to <ptr> */
30#define ebpt_entry(ptr, type, member) container_of(ptr, type, member)
31
Willy Tarreauc2186022009-10-26 19:48:54 +010032/*
33 * Exported functions and macros.
34 * Many of them are always inlined because they are extremely small, and
35 * are generally called at most once or twice in a program.
36 */
37
38/* Return leftmost node in the tree, or NULL if none */
39static forceinline struct ebpt_node *ebpt_first(struct eb_root *root)
40{
41 return ebpt_entry(eb_first(root), struct ebpt_node, node);
42}
43
44/* Return rightmost node in the tree, or NULL if none */
45static forceinline struct ebpt_node *ebpt_last(struct eb_root *root)
46{
47 return ebpt_entry(eb_last(root), struct ebpt_node, node);
48}
49
50/* Return next node in the tree, or NULL if none */
51static forceinline struct ebpt_node *ebpt_next(struct ebpt_node *ebpt)
52{
53 return ebpt_entry(eb_next(&ebpt->node), struct ebpt_node, node);
54}
55
56/* Return previous node in the tree, or NULL if none */
57static forceinline struct ebpt_node *ebpt_prev(struct ebpt_node *ebpt)
58{
59 return ebpt_entry(eb_prev(&ebpt->node), struct ebpt_node, node);
60}
61
Willy Tarreau2b570202013-05-07 15:58:28 +020062/* Return next leaf node within a duplicate sub-tree, or NULL if none. */
63static inline struct ebpt_node *ebpt_next_dup(struct ebpt_node *ebpt)
64{
65 return ebpt_entry(eb_next_dup(&ebpt->node), struct ebpt_node, node);
66}
67
68/* Return previous leaf node within a duplicate sub-tree, or NULL if none. */
69static inline struct ebpt_node *ebpt_prev_dup(struct ebpt_node *ebpt)
70{
71 return ebpt_entry(eb_prev_dup(&ebpt->node), struct ebpt_node, node);
72}
73
Willy Tarreauc2186022009-10-26 19:48:54 +010074/* Return next node in the tree, skipping duplicates, or NULL if none */
75static forceinline struct ebpt_node *ebpt_next_unique(struct ebpt_node *ebpt)
76{
77 return ebpt_entry(eb_next_unique(&ebpt->node), struct ebpt_node, node);
78}
79
80/* Return previous node in the tree, skipping duplicates, or NULL if none */
81static forceinline struct ebpt_node *ebpt_prev_unique(struct ebpt_node *ebpt)
82{
83 return ebpt_entry(eb_prev_unique(&ebpt->node), struct ebpt_node, node);
84}
85
86/* Delete node from the tree if it was linked in. Mark the node unused. Note
87 * that this function relies on a non-inlined generic function: eb_delete.
88 */
89static forceinline void ebpt_delete(struct ebpt_node *ebpt)
90{
91 eb_delete(&ebpt->node);
92}
93
94/*
95 * The following functions are inlined but derived from the integer versions.
96 */
97static forceinline struct ebpt_node *ebpt_lookup(struct eb_root *root, void *x)
98{
99 if (sizeof(void *) == 4)
100 return (struct ebpt_node *)eb32_lookup(root, (u32)(PTR_INT_TYPE)x);
101 else
102 return (struct ebpt_node *)eb64_lookup(root, (u64)(PTR_INT_TYPE)x);
103}
104
105static forceinline struct ebpt_node *ebpt_lookup_le(struct eb_root *root, void *x)
106{
107 if (sizeof(void *) == 4)
108 return (struct ebpt_node *)eb32_lookup_le(root, (u32)(PTR_INT_TYPE)x);
109 else
110 return (struct ebpt_node *)eb64_lookup_le(root, (u64)(PTR_INT_TYPE)x);
111}
112
113static forceinline struct ebpt_node *ebpt_lookup_ge(struct eb_root *root, void *x)
114{
115 if (sizeof(void *) == 4)
116 return (struct ebpt_node *)eb32_lookup_ge(root, (u32)(PTR_INT_TYPE)x);
117 else
118 return (struct ebpt_node *)eb64_lookup_ge(root, (u64)(PTR_INT_TYPE)x);
119}
120
121static forceinline struct ebpt_node *ebpt_insert(struct eb_root *root, struct ebpt_node *new)
122{
123 if (sizeof(void *) == 4)
124 return (struct ebpt_node *)eb32_insert(root, (struct eb32_node *)new);
125 else
126 return (struct ebpt_node *)eb64_insert(root, (struct eb64_node *)new);
127}
128
129/*
130 * The following functions are less likely to be used directly, because
131 * their code is larger. The non-inlined version is preferred.
132 */
133
134/* Delete node from the tree if it was linked in. Mark the node unused. */
135static forceinline void __ebpt_delete(struct ebpt_node *ebpt)
136{
137 __eb_delete(&ebpt->node);
138}
139
140static forceinline struct ebpt_node *__ebpt_lookup(struct eb_root *root, void *x)
141{
142 if (sizeof(void *) == 4)
143 return (struct ebpt_node *)__eb32_lookup(root, (u32)(PTR_INT_TYPE)x);
144 else
145 return (struct ebpt_node *)__eb64_lookup(root, (u64)(PTR_INT_TYPE)x);
146}
147
148static forceinline struct ebpt_node *__ebpt_insert(struct eb_root *root, struct ebpt_node *new)
149{
150 if (sizeof(void *) == 4)
151 return (struct ebpt_node *)__eb32_insert(root, (struct eb32_node *)new);
152 else
153 return (struct ebpt_node *)__eb64_insert(root, (struct eb64_node *)new);
154}
155
156#endif /* _EBPT_TREE_H */