aboutsummaryrefslogtreecommitdiffstats
path: root/include/linux
diff options
context:
space:
mode:
authorIlya Dryomov <idryomov@gmail.com>2017-06-19 06:18:05 -0400
committerIlya Dryomov <idryomov@gmail.com>2017-07-07 11:25:17 -0400
commit76f827a7b1faaaebc53f89d184e95ea3a0b8dd71 (patch)
treec37c66afbd422e72ec26e4642193eff4270610fd /include/linux
parentdf28152d53b449a72258000f592472215fc9371e (diff)
libceph: make DEFINE_RB_* helpers more general
Initially for ceph_pg_mapping, ceph_spg_mapping and ceph_hobject_id, compared with ceph_pg_compare(), ceph_spg_compare() and hoid_compare() respectively. Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
Diffstat (limited to 'include/linux')
-rw-r--r--include/linux/ceph/libceph.h49
1 files changed, 37 insertions, 12 deletions
diff --git a/include/linux/ceph/libceph.h b/include/linux/ceph/libceph.h
index 3229ae6c7846..8a79587e1317 100644
--- a/include/linux/ceph/libceph.h
+++ b/include/linux/ceph/libceph.h
@@ -184,10 +184,11 @@ static inline int calc_pages_for(u64 off, u64 len)
184 (off >> PAGE_SHIFT); 184 (off >> PAGE_SHIFT);
185} 185}
186 186
187/* 187#define RB_BYVAL(a) (a)
188 * These are not meant to be generic - an integer key is assumed. 188#define RB_BYPTR(a) (&(a))
189 */ 189#define RB_CMP3WAY(a, b) ((a) < (b) ? -1 : (a) > (b))
190#define DEFINE_RB_INSDEL_FUNCS(name, type, keyfld, nodefld) \ 190
191#define DEFINE_RB_INSDEL_FUNCS2(name, type, keyfld, cmpexp, keyexp, nodefld) \
191static void insert_##name(struct rb_root *root, type *t) \ 192static void insert_##name(struct rb_root *root, type *t) \
192{ \ 193{ \
193 struct rb_node **n = &root->rb_node; \ 194 struct rb_node **n = &root->rb_node; \
@@ -197,11 +198,13 @@ static void insert_##name(struct rb_root *root, type *t) \
197 \ 198 \
198 while (*n) { \ 199 while (*n) { \
199 type *cur = rb_entry(*n, type, nodefld); \ 200 type *cur = rb_entry(*n, type, nodefld); \
201 int cmp; \
200 \ 202 \
201 parent = *n; \ 203 parent = *n; \
202 if (t->keyfld < cur->keyfld) \ 204 cmp = cmpexp(keyexp(t->keyfld), keyexp(cur->keyfld)); \
205 if (cmp < 0) \
203 n = &(*n)->rb_left; \ 206 n = &(*n)->rb_left; \
204 else if (t->keyfld > cur->keyfld) \ 207 else if (cmp > 0) \
205 n = &(*n)->rb_right; \ 208 n = &(*n)->rb_right; \
206 else \ 209 else \
207 BUG(); \ 210 BUG(); \
@@ -217,19 +220,24 @@ static void erase_##name(struct rb_root *root, type *t) \
217 RB_CLEAR_NODE(&t->nodefld); \ 220 RB_CLEAR_NODE(&t->nodefld); \
218} 221}
219 222
220#define DEFINE_RB_LOOKUP_FUNC(name, type, keyfld, nodefld) \ 223/*
221extern type __lookup_##name##_key; \ 224 * @lookup_param_type is a parameter and not constructed from (@type,
222static type *lookup_##name(struct rb_root *root, \ 225 * @keyfld) with typeof() because adding const is too unwieldy.
223 typeof(__lookup_##name##_key.keyfld) key) \ 226 */
227#define DEFINE_RB_LOOKUP_FUNC2(name, type, keyfld, cmpexp, keyexp, \
228 lookup_param_type, nodefld) \
229static type *lookup_##name(struct rb_root *root, lookup_param_type key) \
224{ \ 230{ \
225 struct rb_node *n = root->rb_node; \ 231 struct rb_node *n = root->rb_node; \
226 \ 232 \
227 while (n) { \ 233 while (n) { \
228 type *cur = rb_entry(n, type, nodefld); \ 234 type *cur = rb_entry(n, type, nodefld); \
235 int cmp; \
229 \ 236 \
230 if (key < cur->keyfld) \ 237 cmp = cmpexp(key, keyexp(cur->keyfld)); \
238 if (cmp < 0) \
231 n = n->rb_left; \ 239 n = n->rb_left; \
232 else if (key > cur->keyfld) \ 240 else if (cmp > 0) \
233 n = n->rb_right; \ 241 n = n->rb_right; \
234 else \ 242 else \
235 return cur; \ 243 return cur; \
@@ -238,6 +246,23 @@ static type *lookup_##name(struct rb_root *root, \
238 return NULL; \ 246 return NULL; \
239} 247}
240 248
249#define DEFINE_RB_FUNCS2(name, type, keyfld, cmpexp, keyexp, \
250 lookup_param_type, nodefld) \
251DEFINE_RB_INSDEL_FUNCS2(name, type, keyfld, cmpexp, keyexp, nodefld) \
252DEFINE_RB_LOOKUP_FUNC2(name, type, keyfld, cmpexp, keyexp, \
253 lookup_param_type, nodefld)
254
255/*
256 * Shorthands for integer keys.
257 */
258#define DEFINE_RB_INSDEL_FUNCS(name, type, keyfld, nodefld) \
259DEFINE_RB_INSDEL_FUNCS2(name, type, keyfld, RB_CMP3WAY, RB_BYVAL, nodefld)
260
261#define DEFINE_RB_LOOKUP_FUNC(name, type, keyfld, nodefld) \
262extern type __lookup_##name##_key; \
263DEFINE_RB_LOOKUP_FUNC2(name, type, keyfld, RB_CMP3WAY, RB_BYVAL, \
264 typeof(__lookup_##name##_key.keyfld), nodefld)
265
241#define DEFINE_RB_FUNCS(name, type, keyfld, nodefld) \ 266#define DEFINE_RB_FUNCS(name, type, keyfld, nodefld) \
242DEFINE_RB_INSDEL_FUNCS(name, type, keyfld, nodefld) \ 267DEFINE_RB_INSDEL_FUNCS(name, type, keyfld, nodefld) \
243DEFINE_RB_LOOKUP_FUNC(name, type, keyfld, nodefld) 268DEFINE_RB_LOOKUP_FUNC(name, type, keyfld, nodefld)