diff options
| author | Ilya Dryomov <idryomov@gmail.com> | 2017-06-19 06:18:05 -0400 |
|---|---|---|
| committer | Ilya Dryomov <idryomov@gmail.com> | 2017-07-07 11:25:17 -0400 |
| commit | 76f827a7b1faaaebc53f89d184e95ea3a0b8dd71 (patch) | |
| tree | c37c66afbd422e72ec26e4642193eff4270610fd /include/linux | |
| parent | df28152d53b449a72258000f592472215fc9371e (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.h | 49 |
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) \ | ||
| 191 | static void insert_##name(struct rb_root *root, type *t) \ | 192 | static 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 | /* |
| 221 | extern type __lookup_##name##_key; \ | 224 | * @lookup_param_type is a parameter and not constructed from (@type, |
| 222 | static 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) \ | ||
| 229 | static 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) \ | ||
| 251 | DEFINE_RB_INSDEL_FUNCS2(name, type, keyfld, cmpexp, keyexp, nodefld) \ | ||
| 252 | DEFINE_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) \ | ||
| 259 | DEFINE_RB_INSDEL_FUNCS2(name, type, keyfld, RB_CMP3WAY, RB_BYVAL, nodefld) | ||
| 260 | |||
| 261 | #define DEFINE_RB_LOOKUP_FUNC(name, type, keyfld, nodefld) \ | ||
| 262 | extern type __lookup_##name##_key; \ | ||
| 263 | DEFINE_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) \ |
| 242 | DEFINE_RB_INSDEL_FUNCS(name, type, keyfld, nodefld) \ | 267 | DEFINE_RB_INSDEL_FUNCS(name, type, keyfld, nodefld) \ |
| 243 | DEFINE_RB_LOOKUP_FUNC(name, type, keyfld, nodefld) | 268 | DEFINE_RB_LOOKUP_FUNC(name, type, keyfld, nodefld) |
