/src/haproxy/include/import/ceb32_tree.h
Line | Count | Source |
1 | | /* |
2 | | * Compact Elastic Binary Trees - exported functions operating on u32 keys |
3 | | * |
4 | | * Copyright (C) 2014-2025 Willy Tarreau - w@1wt.eu |
5 | | * |
6 | | * Permission is hereby granted, free of charge, to any person obtaining |
7 | | * a copy of this software and associated documentation files (the |
8 | | * "Software"), to deal in the Software without restriction, including |
9 | | * without limitation the rights to use, copy, modify, merge, publish, |
10 | | * distribute, sublicense, and/or sell copies of the Software, and to |
11 | | * permit persons to whom the Software is furnished to do so, subject to |
12 | | * the following conditions: |
13 | | * |
14 | | * The above copyright notice and this permission notice shall be |
15 | | * included in all copies or substantial portions of the Software. |
16 | | * |
17 | | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, |
18 | | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES |
19 | | * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND |
20 | | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT |
21 | | * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, |
22 | | * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
23 | | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR |
24 | | * OTHER DEALINGS IN THE SOFTWARE. |
25 | | */ |
26 | | |
27 | | #ifndef _CEB32_TREE_H |
28 | | #define _CEB32_TREE_H |
29 | | |
30 | | #include "cebtree.h" |
31 | | #include <inttypes.h> |
32 | | |
33 | | /* simpler version */ |
34 | | struct ceb_node *ceb32_imm_insert(struct ceb_root **root, struct ceb_node *node); |
35 | | struct ceb_node *ceb32_imm_first(struct ceb_root *const *root); |
36 | | struct ceb_node *ceb32_imm_last(struct ceb_root *const *root); |
37 | | struct ceb_node *ceb32_imm_lookup(struct ceb_root *const *root, uint32_t key); |
38 | | struct ceb_node *ceb32_imm_lookup_le(struct ceb_root *const *root, uint32_t key); |
39 | | struct ceb_node *ceb32_imm_lookup_lt(struct ceb_root *const *root, uint32_t key); |
40 | | struct ceb_node *ceb32_imm_lookup_ge(struct ceb_root *const *root, uint32_t key); |
41 | | struct ceb_node *ceb32_imm_lookup_gt(struct ceb_root *const *root, uint32_t key); |
42 | | struct ceb_node *ceb32_imm_next_unique(struct ceb_root *const *root, struct ceb_node *node); |
43 | | struct ceb_node *ceb32_imm_prev_unique(struct ceb_root *const *root, struct ceb_node *node); |
44 | | struct ceb_node *ceb32_imm_next_dup(struct ceb_root *const *root, struct ceb_node *node); |
45 | | struct ceb_node *ceb32_imm_prev_dup(struct ceb_root *const *root, struct ceb_node *node); |
46 | | struct ceb_node *ceb32_imm_next(struct ceb_root *const *root, struct ceb_node *node); |
47 | | struct ceb_node *ceb32_imm_prev(struct ceb_root *const *root, struct ceb_node *node); |
48 | | struct ceb_node *ceb32_imm_delete(struct ceb_root **root, struct ceb_node *node); |
49 | | struct ceb_node *ceb32_imm_pick(struct ceb_root **root, uint32_t key); |
50 | | |
51 | | struct ceb_node *cebu32_imm_insert(struct ceb_root **root, struct ceb_node *node); |
52 | | struct ceb_node *cebu32_imm_first(struct ceb_root *const *root); |
53 | | struct ceb_node *cebu32_imm_last(struct ceb_root *const *root); |
54 | | struct ceb_node *cebu32_imm_lookup(struct ceb_root *const *root, uint32_t key); |
55 | | struct ceb_node *cebu32_imm_lookup_le(struct ceb_root *const *root, uint32_t key); |
56 | | struct ceb_node *cebu32_imm_lookup_lt(struct ceb_root *const *root, uint32_t key); |
57 | | struct ceb_node *cebu32_imm_lookup_ge(struct ceb_root *const *root, uint32_t key); |
58 | | struct ceb_node *cebu32_imm_lookup_gt(struct ceb_root *const *root, uint32_t key); |
59 | | struct ceb_node *cebu32_imm_next(struct ceb_root *const *root, struct ceb_node *node); |
60 | | struct ceb_node *cebu32_imm_prev(struct ceb_root *const *root, struct ceb_node *node); |
61 | | struct ceb_node *cebu32_imm_delete(struct ceb_root **root, struct ceb_node *node); |
62 | | struct ceb_node *cebu32_imm_pick(struct ceb_root **root, uint32_t key); |
63 | | |
64 | | /* generic dump function */ |
65 | | void ceb32_imm_default_dump(struct ceb_root **ceb_root, const char *label, const void *ctx, int sub); |
66 | | |
67 | | /* returns the pointer to the uint32_t key */ |
68 | | static inline uint32_t *ceb32_imm_key(const struct ceb_node *node) |
69 | 0 | { |
70 | 0 | return (uint32_t *)ceb_key_ptr(node, sizeof(struct ceb_node)); |
71 | 0 | } Unexecuted instantiation: cfgparse.c:ceb32_imm_key Unexecuted instantiation: cli.c:ceb32_imm_key Unexecuted instantiation: connection.c:ceb32_imm_key Unexecuted instantiation: debug.c:ceb32_imm_key Unexecuted instantiation: errors.c:ceb32_imm_key Unexecuted instantiation: fd.c:ceb32_imm_key Unexecuted instantiation: filters.c:ceb32_imm_key Unexecuted instantiation: flt_http_comp.c:ceb32_imm_key Unexecuted instantiation: frontend.c:ceb32_imm_key Unexecuted instantiation: haproxy.c:ceb32_imm_key Unexecuted instantiation: http_ana.c:ceb32_imm_key Unexecuted instantiation: http_ext.c:ceb32_imm_key Unexecuted instantiation: http_htx.c:ceb32_imm_key Unexecuted instantiation: http_rules.c:ceb32_imm_key Unexecuted instantiation: lb_chash.c:ceb32_imm_key Unexecuted instantiation: limits.c:ceb32_imm_key Unexecuted instantiation: listener.c:ceb32_imm_key Unexecuted instantiation: log.c:ceb32_imm_key Unexecuted instantiation: mailers.c:ceb32_imm_key Unexecuted instantiation: mworker.c:ceb32_imm_key Unexecuted instantiation: peers.c:ceb32_imm_key Unexecuted instantiation: pool.c:ceb32_imm_key Unexecuted instantiation: proto_rhttp.c:ceb32_imm_key Unexecuted instantiation: proto_sockpair.c:ceb32_imm_key Unexecuted instantiation: protocol.c:ceb32_imm_key Unexecuted instantiation: proxy.c:ceb32_imm_key Unexecuted instantiation: queue.c:ceb32_imm_key Unexecuted instantiation: resolvers.c:ceb32_imm_key Unexecuted instantiation: ring.c:ceb32_imm_key Unexecuted instantiation: sample.c:ceb32_imm_key Unexecuted instantiation: server.c:ceb32_imm_key Unexecuted instantiation: session.c:ceb32_imm_key Unexecuted instantiation: sink.c:ceb32_imm_key Unexecuted instantiation: sock.c:ceb32_imm_key Unexecuted instantiation: stats-html.c:ceb32_imm_key Unexecuted instantiation: stats.c:ceb32_imm_key Unexecuted instantiation: stconn.c:ceb32_imm_key Unexecuted instantiation: stick_table.c:ceb32_imm_key Unexecuted instantiation: stream.c:ceb32_imm_key Unexecuted instantiation: tcp_rules.c:ceb32_imm_key Unexecuted instantiation: tcpcheck.c:ceb32_imm_key Unexecuted instantiation: thread.c:ceb32_imm_key Unexecuted instantiation: tools.c:ceb32_imm_key Unexecuted instantiation: trace.c:ceb32_imm_key Unexecuted instantiation: vars.c:ceb32_imm_key Unexecuted instantiation: action.c:ceb32_imm_key Unexecuted instantiation: activity.c:ceb32_imm_key Unexecuted instantiation: applet.c:ceb32_imm_key Unexecuted instantiation: backend.c:ceb32_imm_key Unexecuted instantiation: cache.c:ceb32_imm_key Unexecuted instantiation: cfgparse-global.c:ceb32_imm_key Unexecuted instantiation: cfgparse-listen.c:ceb32_imm_key Unexecuted instantiation: channel.c:ceb32_imm_key Unexecuted instantiation: check.c:ceb32_imm_key Unexecuted instantiation: compression.c:ceb32_imm_key Unexecuted instantiation: dns.c:ceb32_imm_key Unexecuted instantiation: dns_ring.c:ceb32_imm_key Unexecuted instantiation: extcheck.c:ceb32_imm_key Unexecuted instantiation: fcgi-app.c:ceb32_imm_key Unexecuted instantiation: guid.c:ceb32_imm_key Unexecuted instantiation: http_fetch.c:ceb32_imm_key Unexecuted instantiation: mux_spop.c:ceb32_imm_key Unexecuted instantiation: pattern.c:ceb32_imm_key Unexecuted instantiation: payload.c:ceb32_imm_key Unexecuted instantiation: proto_tcp.c:ceb32_imm_key Unexecuted instantiation: stats-json.c:ceb32_imm_key Unexecuted instantiation: stats-proxy.c:ceb32_imm_key Unexecuted instantiation: flt_spoe.c:ceb32_imm_key |
72 | | |
73 | | /* version taking a key offset */ |
74 | | struct ceb_node *ceb32_ofs_insert(struct ceb_root **root, ptrdiff_t kofs, struct ceb_node *node); |
75 | | struct ceb_node *ceb32_ofs_first(struct ceb_root *const *root, ptrdiff_t kofs); |
76 | | struct ceb_node *ceb32_ofs_last(struct ceb_root *const *root, ptrdiff_t kofs); |
77 | | struct ceb_node *ceb32_ofs_lookup(struct ceb_root *const *root, ptrdiff_t kofs, uint32_t key); |
78 | | struct ceb_node *ceb32_ofs_lookup_le(struct ceb_root *const *root, ptrdiff_t kofs, uint32_t key); |
79 | | struct ceb_node *ceb32_ofs_lookup_lt(struct ceb_root *const *root, ptrdiff_t kofs, uint32_t key); |
80 | | struct ceb_node *ceb32_ofs_lookup_ge(struct ceb_root *const *root, ptrdiff_t kofs, uint32_t key); |
81 | | struct ceb_node *ceb32_ofs_lookup_gt(struct ceb_root *const *root, ptrdiff_t kofs, uint32_t key); |
82 | | struct ceb_node *ceb32_ofs_next_unique(struct ceb_root *const *root, ptrdiff_t kofs, struct ceb_node *node); |
83 | | struct ceb_node *ceb32_ofs_prev_unique(struct ceb_root *const *root, ptrdiff_t kofs, struct ceb_node *node); |
84 | | struct ceb_node *ceb32_ofs_next_dup(struct ceb_root *const *root, ptrdiff_t kofs, struct ceb_node *node); |
85 | | struct ceb_node *ceb32_ofs_prev_dup(struct ceb_root *const *root, ptrdiff_t kofs, struct ceb_node *node); |
86 | | struct ceb_node *ceb32_ofs_next(struct ceb_root *const *root, ptrdiff_t kofs, struct ceb_node *node); |
87 | | struct ceb_node *ceb32_ofs_prev(struct ceb_root *const *root, ptrdiff_t kofs, struct ceb_node *node); |
88 | | struct ceb_node *ceb32_ofs_delete(struct ceb_root **root, ptrdiff_t kofs, struct ceb_node *node); |
89 | | struct ceb_node *ceb32_ofs_pick(struct ceb_root **root, ptrdiff_t kofs, uint32_t key); |
90 | | |
91 | | struct ceb_node *cebu32_ofs_insert(struct ceb_root **root, ptrdiff_t kofs, struct ceb_node *node); |
92 | | struct ceb_node *cebu32_ofs_first(struct ceb_root *const *root, ptrdiff_t kofs); |
93 | | struct ceb_node *cebu32_ofs_last(struct ceb_root *const *root, ptrdiff_t kofs); |
94 | | struct ceb_node *cebu32_ofs_lookup(struct ceb_root *const *root, ptrdiff_t kofs, uint32_t key); |
95 | | struct ceb_node *cebu32_ofs_lookup_le(struct ceb_root *const *root, ptrdiff_t kofs, uint32_t key); |
96 | | struct ceb_node *cebu32_ofs_lookup_lt(struct ceb_root *const *root, ptrdiff_t kofs, uint32_t key); |
97 | | struct ceb_node *cebu32_ofs_lookup_ge(struct ceb_root *const *root, ptrdiff_t kofs, uint32_t key); |
98 | | struct ceb_node *cebu32_ofs_lookup_gt(struct ceb_root *const *root, ptrdiff_t kofs, uint32_t key); |
99 | | struct ceb_node *cebu32_ofs_next(struct ceb_root *const *root, ptrdiff_t kofs, struct ceb_node *node); |
100 | | struct ceb_node *cebu32_ofs_prev(struct ceb_root *const *root, ptrdiff_t kofs, struct ceb_node *node); |
101 | | struct ceb_node *cebu32_ofs_delete(struct ceb_root **root, ptrdiff_t kofs, struct ceb_node *node); |
102 | | struct ceb_node *cebu32_ofs_pick(struct ceb_root **root, ptrdiff_t kofs, uint32_t key); |
103 | | |
104 | | /* generic dump function taking a key offset */ |
105 | | void ceb32_ofs_default_dump(struct ceb_root *const *root, ptrdiff_t kofs, const char *label, const void *ctx, int sub); |
106 | | |
107 | | /* returns the pointer to the uint32_t key */ |
108 | | static inline uint32_t *ceb32_ofs_key(const struct ceb_node *node, ptrdiff_t kofs) |
109 | 0 | { |
110 | 0 | return (uint32_t *)ceb_key_ptr(node, kofs); |
111 | 0 | } Unexecuted instantiation: cfgparse.c:ceb32_ofs_key Unexecuted instantiation: cli.c:ceb32_ofs_key Unexecuted instantiation: connection.c:ceb32_ofs_key Unexecuted instantiation: debug.c:ceb32_ofs_key Unexecuted instantiation: errors.c:ceb32_ofs_key Unexecuted instantiation: fd.c:ceb32_ofs_key Unexecuted instantiation: filters.c:ceb32_ofs_key Unexecuted instantiation: flt_http_comp.c:ceb32_ofs_key Unexecuted instantiation: frontend.c:ceb32_ofs_key Unexecuted instantiation: haproxy.c:ceb32_ofs_key Unexecuted instantiation: http_ana.c:ceb32_ofs_key Unexecuted instantiation: http_ext.c:ceb32_ofs_key Unexecuted instantiation: http_htx.c:ceb32_ofs_key Unexecuted instantiation: http_rules.c:ceb32_ofs_key Unexecuted instantiation: lb_chash.c:ceb32_ofs_key Unexecuted instantiation: limits.c:ceb32_ofs_key Unexecuted instantiation: listener.c:ceb32_ofs_key Unexecuted instantiation: log.c:ceb32_ofs_key Unexecuted instantiation: mailers.c:ceb32_ofs_key Unexecuted instantiation: mworker.c:ceb32_ofs_key Unexecuted instantiation: peers.c:ceb32_ofs_key Unexecuted instantiation: pool.c:ceb32_ofs_key Unexecuted instantiation: proto_rhttp.c:ceb32_ofs_key Unexecuted instantiation: proto_sockpair.c:ceb32_ofs_key Unexecuted instantiation: protocol.c:ceb32_ofs_key Unexecuted instantiation: proxy.c:ceb32_ofs_key Unexecuted instantiation: queue.c:ceb32_ofs_key Unexecuted instantiation: resolvers.c:ceb32_ofs_key Unexecuted instantiation: ring.c:ceb32_ofs_key Unexecuted instantiation: sample.c:ceb32_ofs_key Unexecuted instantiation: server.c:ceb32_ofs_key Unexecuted instantiation: session.c:ceb32_ofs_key Unexecuted instantiation: sink.c:ceb32_ofs_key Unexecuted instantiation: sock.c:ceb32_ofs_key Unexecuted instantiation: stats-html.c:ceb32_ofs_key Unexecuted instantiation: stats.c:ceb32_ofs_key Unexecuted instantiation: stconn.c:ceb32_ofs_key Unexecuted instantiation: stick_table.c:ceb32_ofs_key Unexecuted instantiation: stream.c:ceb32_ofs_key Unexecuted instantiation: tcp_rules.c:ceb32_ofs_key Unexecuted instantiation: tcpcheck.c:ceb32_ofs_key Unexecuted instantiation: thread.c:ceb32_ofs_key Unexecuted instantiation: tools.c:ceb32_ofs_key Unexecuted instantiation: trace.c:ceb32_ofs_key Unexecuted instantiation: vars.c:ceb32_ofs_key Unexecuted instantiation: action.c:ceb32_ofs_key Unexecuted instantiation: activity.c:ceb32_ofs_key Unexecuted instantiation: applet.c:ceb32_ofs_key Unexecuted instantiation: backend.c:ceb32_ofs_key Unexecuted instantiation: cache.c:ceb32_ofs_key Unexecuted instantiation: cfgparse-global.c:ceb32_ofs_key Unexecuted instantiation: cfgparse-listen.c:ceb32_ofs_key Unexecuted instantiation: channel.c:ceb32_ofs_key Unexecuted instantiation: check.c:ceb32_ofs_key Unexecuted instantiation: compression.c:ceb32_ofs_key Unexecuted instantiation: dns.c:ceb32_ofs_key Unexecuted instantiation: dns_ring.c:ceb32_ofs_key Unexecuted instantiation: extcheck.c:ceb32_ofs_key Unexecuted instantiation: fcgi-app.c:ceb32_ofs_key Unexecuted instantiation: guid.c:ceb32_ofs_key Unexecuted instantiation: http_fetch.c:ceb32_ofs_key Unexecuted instantiation: mux_spop.c:ceb32_ofs_key Unexecuted instantiation: pattern.c:ceb32_ofs_key Unexecuted instantiation: payload.c:ceb32_ofs_key Unexecuted instantiation: proto_tcp.c:ceb32_ofs_key Unexecuted instantiation: stats-json.c:ceb32_ofs_key Unexecuted instantiation: stats-proxy.c:ceb32_ofs_key Unexecuted instantiation: flt_spoe.c:ceb32_ofs_key |
112 | | |
113 | | /* insert at root <root>, the item <item_ptr> using node member <nname> and |
114 | | * key member <kname>, and returns either the inserted item, or the one that |
115 | | * was found there. |
116 | | */ |
117 | 0 | #define ceb32_item_insert(root, nname, kname, item_ptr) ({ \ |
118 | 0 | ptrdiff_t _nofs = offsetof(typeof(*(item_ptr)), nname); \ |
119 | 0 | ptrdiff_t _kofs = offsetof(typeof(*(item_ptr)), kname) - _nofs; \ |
120 | 0 | struct ceb_node *_node = ceb32_ofs_insert(root, _kofs, &(item_ptr)->nname); \ |
121 | 0 | (typeof(item_ptr))((char *)(_node) - _nofs); \ |
122 | 0 | }) |
123 | | |
124 | | /* descend root <root>, and return the first item of type <type>, using node |
125 | | * member <nname> and key member <kname>, or NULL if the tree is empty. |
126 | | */ |
127 | | #define ceb32_item_first(root, nname, kname, type) ({ \ |
128 | | ptrdiff_t _nofs = offsetof(type, nname); \ |
129 | | ptrdiff_t _kofs = offsetof(type, kname) - _nofs; \ |
130 | | struct ceb_node *_node = ceb32_ofs_first(root, _kofs); \ |
131 | | _node ? (type *)((char *)(_node) - _nofs) : NULL; \ |
132 | | }) |
133 | | |
134 | | /* descend root <root>, and return the last item of type <type>, using node |
135 | | * member <nname> and key member <kname>, or NULL if the tree is empty. |
136 | | */ |
137 | | #define ceb32_item_last(root, nname, kname, type) ({ \ |
138 | | ptrdiff_t _nofs = offsetof(type, nname); \ |
139 | | ptrdiff_t _kofs = offsetof(type, kname) - _nofs; \ |
140 | | struct ceb_node *_node = ceb32_ofs_last(root, _kofs); \ |
141 | | _node ? (type *)((char *)(_node) - _nofs) : NULL; \ |
142 | | }) |
143 | | |
144 | | /* lookup from root <root>, the first item of type <type> which contains the |
145 | | * key <key>, using node member <nname> and key member <kname>. Returns the |
146 | | * pointer to the item, or NULL if not found. |
147 | | */ |
148 | 0 | #define ceb32_item_lookup(root, nname, kname, key, type) ({ \ |
149 | 0 | ptrdiff_t _nofs = offsetof(type, nname); \ |
150 | 0 | ptrdiff_t _kofs = offsetof(type, kname) - _nofs; \ |
151 | 0 | struct ceb_node *_node = ceb32_ofs_lookup(root, _kofs, key); \ |
152 | 0 | _node ? (type *)((char *)(_node) - _nofs) : NULL; \ |
153 | 0 | }) |
154 | | |
155 | | /* lookup from root <root>, the item of type <type> which contains the last of |
156 | | * the greatest keys that are lower than or equal to <key>, using node member |
157 | | * <nname> and key member <kname>. Returns the pointer to the item, or NULL if |
158 | | * not found. |
159 | | */ |
160 | | #define ceb32_item_lookup_le(root, nname, kname, key, type) ({ \ |
161 | | ptrdiff_t _nofs = offsetof(type, nname); \ |
162 | | ptrdiff_t _kofs = offsetof(type, kname) - _nofs; \ |
163 | | struct ceb_node *_node = ceb32_ofs_lookup_le(root, _kofs, key); \ |
164 | | _node ? (type *)((char *)(_node) - _nofs) : NULL; \ |
165 | | }) |
166 | | |
167 | | /* lookup from root <root>, the item of type <type> which contains the last of |
168 | | * the greatest keys that are strictly lower than <key>, using node member |
169 | | * <nname> and key member <kname>. Returns the pointer to the item, or NULL if |
170 | | * not found. |
171 | | */ |
172 | | #define ceb32_item_lookup_lt(root, nname, kname, key, type) ({ \ |
173 | | ptrdiff_t _nofs = offsetof(type, nname); \ |
174 | | ptrdiff_t _kofs = offsetof(type, kname) - _nofs; \ |
175 | | struct ceb_node *_node = ceb32_ofs_lookup_lt(root, _kofs, key); \ |
176 | | _node ? (type *)((char *)(_node) - _nofs) : NULL; \ |
177 | | }) |
178 | | |
179 | | /* lookup from root <root>, the item of type <type> which contains the first of |
180 | | * the lowest keys key that are greater than or equal to <key>, using node |
181 | | * member <nname> and key member <kname>. Returns the pointer to the item, or |
182 | | * NULL if not found. |
183 | | */ |
184 | 0 | #define ceb32_item_lookup_ge(root, nname, kname, key, type) ({ \ |
185 | 0 | ptrdiff_t _nofs = offsetof(type, nname); \ |
186 | 0 | ptrdiff_t _kofs = offsetof(type, kname) - _nofs; \ |
187 | 0 | struct ceb_node *_node = ceb32_ofs_lookup_ge(root, _kofs, key); \ |
188 | 0 | _node ? (type *)((char *)(_node) - _nofs) : NULL; \ |
189 | 0 | }) |
190 | | |
191 | | /* lookup from root <root>, the item of type <type> which contains the first of |
192 | | * the lowest keys that are strictly greater than <key>, using node member |
193 | | * <nname> and key member <kname>. Returns the pointer to the item, or NULL if |
194 | | * not found. |
195 | | */ |
196 | | #define ceb32_item_lookup_gt(root, nname, kname, key, type) ({ \ |
197 | | ptrdiff_t _nofs = offsetof(type, nname); \ |
198 | | ptrdiff_t _kofs = offsetof(type, kname) - _nofs; \ |
199 | | struct ceb_node *_node = ceb32_ofs_lookup_gt(root, _kofs, key); \ |
200 | | _node ? (type *)((char *)(_node) - _nofs) : NULL; \ |
201 | | }) |
202 | | |
203 | | /* lookup from root <root>, the first item after item <item_ptr> that has a |
204 | | * strictly greater key, using node member <nname> and key member <kname>, and |
205 | | * returns either the found item, or NULL if none exists. |
206 | | */ |
207 | | #define ceb32_item_next_unique(root, nname, kname, item_ptr) ({ \ |
208 | | ptrdiff_t _nofs = offsetof(typeof(*(item_ptr)), nname); \ |
209 | | ptrdiff_t _kofs = offsetof(typeof(*(item_ptr)), kname) - _nofs; \ |
210 | | struct ceb_node *_node = ceb32_ofs_next_unique(root, _kofs, &(item_ptr)->nname);\ |
211 | | _node ? (typeof(item_ptr))((char *)(_node) - _nofs) : NULL; \ |
212 | | }) |
213 | | |
214 | | /* lookup from root <root>, the last item before item <item_ptr> that has a |
215 | | * strictly lower key, using node member <nname> and key member <kname>, and |
216 | | * returns either the found item, or NULL if none exists. |
217 | | */ |
218 | | #define ceb32_item_prev_unique(root, nname, kname, item_ptr) ({ \ |
219 | | ptrdiff_t _nofs = offsetof(typeof(*(item_ptr)), nname); \ |
220 | | ptrdiff_t _kofs = offsetof(typeof(*(item_ptr)), kname) - _nofs; \ |
221 | | struct ceb_node *_node = ceb32_ofs_prev_unique(root, _kofs, &(item_ptr)->nname);\ |
222 | | _node ? (typeof(item_ptr))((char *)(_node) - _nofs) : NULL; \ |
223 | | }) |
224 | | |
225 | | /* lookup from root <root>, the first item after item <item_ptr> that has |
226 | | * exactly the same key, using node member <nname> and key member <kname>, and |
227 | | * returns either the found item, or NULL if none exists. |
228 | | */ |
229 | 0 | #define ceb32_item_next_dup(root, nname, kname, item_ptr) ({ \ |
230 | 0 | ptrdiff_t _nofs = offsetof(typeof(*(item_ptr)), nname); \ |
231 | 0 | ptrdiff_t _kofs = offsetof(typeof(*(item_ptr)), kname) - _nofs; \ |
232 | 0 | struct ceb_node *_node = ceb32_ofs_next_dup(root, _kofs, &(item_ptr)->nname); \ |
233 | 0 | _node ? (typeof(item_ptr))((char *)(_node) - _nofs) : NULL; \ |
234 | 0 | }) |
235 | | |
236 | | /* lookup from root <root>, the last item before item <item_ptr> that has |
237 | | * exactly the same key, using node member <nname> and key member <kname>, and |
238 | | * returns either the found item, or NULL if none exists. |
239 | | */ |
240 | | #define ceb32_item_prev_dup(root, nname, kname, item_ptr) ({ \ |
241 | | ptrdiff_t _nofs = offsetof(typeof(*(item_ptr)), nname); \ |
242 | | ptrdiff_t _kofs = offsetof(typeof(*(item_ptr)), kname) - _nofs; \ |
243 | | struct ceb_node *_node = ceb32_ofs_prev_dup(root, _kofs, &(item_ptr)->nname); \ |
244 | | _node ? (typeof(item_ptr))((char *)(_node) - _nofs) : NULL; \ |
245 | | }) |
246 | | |
247 | | /* lookup from root <root>, the first item immediately after item <item_ptr>, |
248 | | * using node member <nname> and key member <kname>, and returns either the |
249 | | * found item, or NULL if none exists. |
250 | | */ |
251 | | #define ceb32_item_next(root, nname, kname, item_ptr) ({ \ |
252 | | ptrdiff_t _nofs = offsetof(typeof(*(item_ptr)), nname); \ |
253 | | ptrdiff_t _kofs = offsetof(typeof(*(item_ptr)), kname) - _nofs; \ |
254 | | struct ceb_node *_node = ceb32_ofs_next(root, _kofs, &(item_ptr)->nname); \ |
255 | | _node ? (typeof(item_ptr))((char *)(_node) - _nofs) : NULL; \ |
256 | | }) |
257 | | |
258 | | /* lookup from root <root>, the last item immediately before item <item_ptr>, |
259 | | * using node member <nname> and key member <kname>, and returns either the |
260 | | * found item, or NULL if none exists. |
261 | | */ |
262 | | #define ceb32_item_prev(root, nname, kname, item_ptr) ({ \ |
263 | | ptrdiff_t _nofs = offsetof(typeof(*(item_ptr)), nname); \ |
264 | | ptrdiff_t _kofs = offsetof(typeof(*(item_ptr)), kname) - _nofs; \ |
265 | | struct ceb_node *_node = ceb32_ofs_prev(root, _kofs, &(item_ptr)->nname); \ |
266 | | _node ? (typeof(item_ptr))((char *)(_node) - _nofs) : NULL; \ |
267 | | }) |
268 | | |
269 | | /* lookup from root <root>, the item <item_ptr> using node member <nname> and |
270 | | * key member <kname>, deletes it and returns it. If the item is NULL or absent |
271 | | * from the tree, NULL is returned. |
272 | | */ |
273 | 0 | #define ceb32_item_delete(root, nname, kname, item_ptr) ({ \ |
274 | 0 | ptrdiff_t _nofs = offsetof(typeof(*(item_ptr)), nname); \ |
275 | 0 | ptrdiff_t _kofs = offsetof(typeof(*(item_ptr)), kname) - _nofs; \ |
276 | 0 | typeof(item_ptr) _item = (item_ptr); \ |
277 | 0 | struct ceb_node *_node = ceb32_ofs_delete(root, _kofs, _item ? &_item->nname : NULL); \ |
278 | 0 | _node ? (typeof(item_ptr))((char *)(_node) - _nofs) : NULL; \ |
279 | 0 | }) |
280 | | |
281 | | /* lookup from root <root>, the first item of type <type> which contains the |
282 | | * key <key>, using node member <nname> and key member <kname>, deletes it and |
283 | | * returns it. If the key is not found in the tree, NULL is returned. |
284 | | */ |
285 | | #define ceb32_item_pick(root, nname, kname, key, type) ({ \ |
286 | | ptrdiff_t _nofs = offsetof(type, nname); \ |
287 | | ptrdiff_t _kofs = offsetof(type, kname) - _nofs; \ |
288 | | struct ceb_node *_node = ceb32_ofs_pick(root, _kofs, key); \ |
289 | | _node ? (type *)((char *)(_node) - _nofs) : NULL; \ |
290 | | }) |
291 | | |
292 | | /*** versions using unique keys below ***/ |
293 | | |
294 | | /* insert at root <root>, the item <item_ptr> using node member <nname> and key |
295 | | * member <kname>, and returns either the inserted item, or the one that was |
296 | | * found there. |
297 | | */ |
298 | 0 | #define cebu32_item_insert(root, nname, kname, item_ptr) ({ \ |
299 | 0 | ptrdiff_t _nofs = offsetof(typeof(*(item_ptr)), nname); \ |
300 | 0 | ptrdiff_t _kofs = offsetof(typeof(*(item_ptr)), kname) - _nofs; \ |
301 | 0 | struct ceb_node *_node = cebu32_ofs_insert(root, _kofs, &(item_ptr)->nname); \ |
302 | 0 | (typeof(item_ptr))((char *)(_node) - _nofs); \ |
303 | 0 | }) |
304 | | |
305 | | /* descend root <root>, and return the first item of type <type>, using node |
306 | | * member <nname> and key member <kname>, or NULL if the tree is empty. |
307 | | */ |
308 | 0 | #define cebu32_item_first(root, nname, kname, type) ({ \ |
309 | 0 | ptrdiff_t _nofs = offsetof(type, nname); \ |
310 | 0 | ptrdiff_t _kofs = offsetof(type, kname) - _nofs; \ |
311 | 0 | struct ceb_node *_node = cebu32_ofs_first(root, _kofs); \ |
312 | 0 | _node ? (type *)((char *)(_node) - _nofs) : NULL; \ |
313 | 0 | }) |
314 | | |
315 | | /* descend root <root>, and return the last item of type <type>, using node |
316 | | * member <nname> and key member <kname>, or NULL if the tree is empty. |
317 | | */ |
318 | | #define cebu32_item_last(root, nname, kname, type) ({ \ |
319 | | ptrdiff_t _nofs = offsetof(type, nname); \ |
320 | | ptrdiff_t _kofs = offsetof(type, kname) - _nofs; \ |
321 | | struct ceb_node *_node = cebu32_ofs_last(root, _kofs); \ |
322 | | _node ? (type *)((char *)(_node) - _nofs) : NULL; \ |
323 | | }) |
324 | | |
325 | | /* lookup from root <root>, the item of type <type> which contains the key |
326 | | * <key>, using node member <nname> and key member <kname>. Returns the pointer |
327 | | * to the item, or NULL if not found. |
328 | | */ |
329 | 0 | #define cebu32_item_lookup(root, nname, kname, key, type) ({ \ |
330 | 0 | ptrdiff_t _nofs = offsetof(type, nname); \ |
331 | 0 | ptrdiff_t _kofs = offsetof(type, kname) - _nofs; \ |
332 | 0 | struct ceb_node *_node = cebu32_ofs_lookup(root, _kofs, key); \ |
333 | 0 | _node ? (type *)((char *)(_node) - _nofs) : NULL; \ |
334 | 0 | }) |
335 | | |
336 | | /* lookup from root <root>, the item of type <type> which contains the greatest |
337 | | * key that is lower than or equal to <key>, using node member <nname> and key |
338 | | * member <kname>. Returns the pointer to the item, or NULL if not found. |
339 | | */ |
340 | | #define cebu32_item_lookup_le(root, nname, kname, key, type) ({ \ |
341 | | ptrdiff_t _nofs = offsetof(type, nname); \ |
342 | | ptrdiff_t _kofs = offsetof(type, kname) - _nofs; \ |
343 | | struct ceb_node *_node = cebu32_ofs_lookup_le(root, _kofs, key); \ |
344 | | _node ? (type *)((char *)(_node) - _nofs) : NULL; \ |
345 | | }) |
346 | | |
347 | | /* lookup from root <root>, the item of type <type> which contains the greatest |
348 | | * key that is strictly lower than <key>, using node member <nname> and key |
349 | | * member <kname>. Returns the pointer to the item, or NULL if not found. |
350 | | */ |
351 | | #define cebu32_item_lookup_lt(root, nname, kname, key, type) ({ \ |
352 | | ptrdiff_t _nofs = offsetof(type, nname); \ |
353 | | ptrdiff_t _kofs = offsetof(type, kname) - _nofs; \ |
354 | | struct ceb_node *_node = cebu32_ofs_lookup_lt(root, _kofs, key); \ |
355 | | _node ? (type *)((char *)(_node) - _nofs) : NULL; \ |
356 | | }) |
357 | | |
358 | | /* lookup from root <root>, the item of type <type> which contains the lowest |
359 | | * key key that is greater than or equal to <key>, using node member <nname> |
360 | | * and key member <kname>. Returns the pointer to the item, or NULL if not |
361 | | * found. |
362 | | */ |
363 | | #define cebu32_item_lookup_ge(root, nname, kname, key, type) ({ \ |
364 | | ptrdiff_t _nofs = offsetof(type, nname); \ |
365 | | ptrdiff_t _kofs = offsetof(type, kname) - _nofs; \ |
366 | | struct ceb_node *_node = cebu32_ofs_lookup_ge(root, _kofs, key); \ |
367 | | _node ? (type *)((char *)(_node) - _nofs) : NULL; \ |
368 | | }) |
369 | | |
370 | | /* lookup from root <root>, the item of type <type> which contains the lowest |
371 | | * key that is strictly greater than <key>, using node member <nname> and key |
372 | | * member <kname>. Returns the pointer to the item, or NULL if not found. |
373 | | */ |
374 | | #define cebu32_item_lookup_gt(root, nname, kname, key, type) ({ \ |
375 | | ptrdiff_t _nofs = offsetof(type, nname); \ |
376 | | ptrdiff_t _kofs = offsetof(type, kname) - _nofs; \ |
377 | | struct ceb_node *_node = cebu32_ofs_lookup_gt(root, _kofs, key); \ |
378 | | _node ? (type *)((char *)(_node) - _nofs) : NULL; \ |
379 | | }) |
380 | | |
381 | | /* lookup from root <root>, the first item immediately after item <item_ptr>, |
382 | | * using node member <nname> and key member <kname>, and returns either the |
383 | | * found item, or NULL if none exists. |
384 | | */ |
385 | 0 | #define cebu32_item_next(root, nname, kname, item_ptr) ({ \ |
386 | 0 | ptrdiff_t _nofs = offsetof(typeof(*(item_ptr)), nname); \ |
387 | 0 | ptrdiff_t _kofs = offsetof(typeof(*(item_ptr)), kname) - _nofs; \ |
388 | 0 | struct ceb_node *_node = cebu32_ofs_next(root, _kofs, &(item_ptr)->nname); \ |
389 | 0 | _node ? (typeof(item_ptr))((char *)(_node) - _nofs) : NULL; \ |
390 | 0 | }) |
391 | | |
392 | | /* lookup from root <root>, the last item immediately before item <item_ptr>, |
393 | | * using node member <nname> and key member <kname>, and returns either the |
394 | | * found item, or NULL if none exists. |
395 | | */ |
396 | | #define cebu32_item_prev(root, nname, kname, item_ptr) ({ \ |
397 | | ptrdiff_t _nofs = offsetof(typeof(*(item_ptr)), nname); \ |
398 | | ptrdiff_t _kofs = offsetof(typeof(*(item_ptr)), kname) - _nofs; \ |
399 | | struct ceb_node *_node = cebu32_ofs_prev(root, _kofs, &(item_ptr)->nname); \ |
400 | | _node ? (typeof(item_ptr))((char *)(_node) - _nofs) : NULL; \ |
401 | | }) |
402 | | |
403 | | /* lookup from root <root>, the item <item_ptr> using node member <nname> and |
404 | | * key member <kname>, deletes it and returns it. If the item is NULL or absent |
405 | | * from the tree, NULL is returned. |
406 | | */ |
407 | 0 | #define cebu32_item_delete(root, nname, kname, item_ptr) ({ \ |
408 | 0 | ptrdiff_t _nofs = offsetof(typeof(*(item_ptr)), nname); \ |
409 | 0 | ptrdiff_t _kofs = offsetof(typeof(*(item_ptr)), kname) - _nofs; \ |
410 | 0 | typeof(item_ptr) _item = (item_ptr); \ |
411 | 0 | struct ceb_node *_node = cebu32_ofs_delete(root, _kofs, _item ? &_item->nname : NULL); \ |
412 | 0 | _node ? (typeof(item_ptr))((char *)(_node) - _nofs) : NULL; \ |
413 | 0 | }) |
414 | | |
415 | | /* lookup from root <root>, the first item of type <type> which contains the |
416 | | * key <key>, using node member <nname> and key member <kname>, deletes it and |
417 | | * returns it. If the key is not found in the tree, NULL is returned. |
418 | | */ |
419 | | #define cebu32_item_pick(root, nname, kname, key, type) ({ \ |
420 | | ptrdiff_t _nofs = offsetof(type, nname); \ |
421 | | ptrdiff_t _kofs = offsetof(type, kname) - _nofs; \ |
422 | | struct ceb_node *_node = cebu32_ofs_pick(root, _kofs, key); \ |
423 | | _node ? (type *)((char *)(_node) - _nofs) : NULL; \ |
424 | | }) |
425 | | |
426 | | #endif /* _CEB32_TREE_H */ |