25 #ifndef __MOTR_LIB_HASH_H__ 26 #define __MOTR_LIB_HASH_H__ 317 #define M0_HT_DESCR(name, amb_type, key_field, hash_func, key_eq) \ 319 .hd_tldescr = &name ## _tl, \ 320 .hd_key_eq = key_eq, \ 321 .hd_hash_func = hash_func, \ 322 .hd_key_offset = offsetof(amb_type, key_field), \ 326 #define M0_HT_DESCR_DEFINE(name, htname, scope, amb_type, amb_link_field,\ 327 amb_magic_field, amb_magic, head_magic, \ 328 key_field, hash_func, key_eq) \ 330 M0_BASSERT(sizeof(hash_func(NULL, &M0_FIELD_VALUE(amb_type, key_field))) > 0);\ 331 M0_BASSERT(sizeof(key_eq(&M0_FIELD_VALUE(amb_type, key_field), \ 332 &M0_FIELD_VALUE(amb_type, key_field))) > 0); \ 334 M0_TL_DESCR_DEFINE(name, htname, scope, amb_type, amb_link_field.hl_link, \ 335 amb_magic_field, amb_magic, head_magic); \ 337 scope const struct m0_ht_descr name ## _ht = M0_HT_DESCR(name, \ 340 (uint64_t (*)(const struct m0_htable *, const void *))hash_func,\ 341 (bool (*)(const void *, const void *))key_eq) 344 #define M0_HT_DESCR_DECLARE(name, scope) \ 345 scope const struct m0_ht_descr name ## _ht 351 #define M0_HT_DECLARE(name, scope, amb_type, key_type) \ 353 M0_TL_DECLARE(name, scope, amb_type); \ 355 scope int name ## _htable_init(struct m0_htable *htable, \ 356 uint64_t bucket_nr); \ 357 scope void name ## _htable_add(struct m0_htable *htable, amb_type *amb); \ 358 scope void name ## _htable_del(struct m0_htable *htable, amb_type *amb); \ 359 scope amb_type *name ## _htable_lookup(const struct m0_htable *htable, \ 360 const key_type *key); \ 361 scope void name ## _htable_cc_add(struct m0_htable *htable, amb_type *amb); \ 362 scope void name ## _htable_cc_del(struct m0_htable *htable, amb_type *amb); \ 363 scope amb_type *name ## _htable_cc_lookup(struct m0_htable *htable, \ 364 const key_type *key); \ 365 scope void name ## _hbucket_lock(struct m0_htable *htable, \ 366 const key_type *key); \ 367 scope void name ## _hbucket_unlock(struct m0_htable *htable, \ 368 const key_type *key); \ 369 scope void name ## _htable_fini(struct m0_htable *htable); \ 370 scope bool name ## _htable_is_empty(const struct m0_htable *htable); \ 371 scope uint64_t name ## _htable_size(const struct m0_htable *htable); 377 #define M0_HT_DEFINE(name, scope, amb_type, key_type) \ 379 M0_TL_DEFINE(name, scope, amb_type); \ 381 scope __AUN int name ## _htable_init(struct m0_htable *htable, \ 382 uint64_t bucket_nr) \ 384 return m0_htable_init(&name ## _ht, htable, bucket_nr); \ 387 scope __AUN void name ## _htable_add(struct m0_htable *htable, \ 390 m0_htable_add(htable, amb); \ 393 scope __AUN void name ## _htable_del(struct m0_htable *htable, \ 396 m0_htable_del(htable, amb); \ 399 scope __AUN amb_type *name ## _htable_lookup(const struct m0_htable *htable, \ 400 const key_type *key) \ 402 return m0_htable_lookup(htable, key); \ 405 scope __AUN void name ## _hbucket_lock(struct m0_htable *htable, \ 406 const key_type *key) \ 408 m0_hbucket_lock(htable, key); \ 411 scope __AUN void name ## _hbucket_unlock(struct m0_htable *htable, \ 412 const key_type *key) \ 414 m0_hbucket_unlock(htable, key); \ 417 scope __AUN void name ## _htable_cc_add(struct m0_htable *htable, \ 420 m0_htable_cc_add(htable, amb); \ 423 scope __AUN void name ## _htable_cc_del(struct m0_htable *htable, \ 426 m0_htable_cc_del(htable, amb); \ 429 scope __AUN amb_type * name ## _htable_cc_lookup(struct m0_htable *htable, \ 430 const key_type *key) \ 432 return m0_htable_cc_lookup(htable, key); \ 435 scope __AUN void name ## _htable_fini(struct m0_htable *htable) \ 437 m0_htable_fini(htable); \ 440 scope __AUN bool name ## _htable_is_empty(const struct m0_htable *htable) \ 442 return m0_htable_is_empty(htable); \ 445 scope __AUN uint64_t name ## _htable_size(const struct m0_htable *htable) \ 447 return m0_htable_size(htable); \ 454 #define m0_hbucket_forall(name, var, bucket, ...) \ 456 typeof (bucket) __bucket = (bucket); \ 458 m0_tl_forall(name, var, &__bucket->hb_objects, ({ __VA_ARGS__ ; }));\ 465 #define m0_htable_forall(name, var, htable, ...) \ 468 typeof (htable) ht = (htable); \ 470 for (cnt = 0; cnt < ht->h_bucket_nr; ++cnt) { \ 471 if (!(m0_hbucket_forall(name, var, &ht->h_buckets[cnt], \ 472 ({ __VA_ARGS__ ; })))) \ 475 cnt == ht->h_bucket_nr; \ 483 #define m0_htable_for(name, var, htable) \ 486 typeof (htable) ht = (htable); \ 488 for (__cnt = 0; __cnt < ht->h_bucket_nr; ++__cnt) { \ 489 m0_tl_for(name, &ht->h_buckets[__cnt].hb_objects, var) 491 #define m0_htable_endfor m0_tl_endfor; }; }) 498 #define m0_hbucket_for(descr, var, bucket) \ 500 m0_tlist_for (descr, &bucket->hb_objects, var) 502 #define m0_hbucket_endfor m0_tlist_endfor; }) 508 #define m0_hbucket_forall_ol(descr, var, bucket, ...) \ 510 typeof(descr) d = descr; \ 511 m0_hbucket_for (d, var, bucket) { \ 512 if (!({ __VA_ARGS__; })) \ 514 } m0_hbucket_endfor; \ 519 M0_INTERNAL uint64_t
m0_hash(uint64_t
x);
M0_INTERNAL void * m0_htable_lookup(const struct m0_htable *htable, const void *key)
M0_INTERNAL void m0_htable_cc_del(struct m0_htable *htable, void *amb)
M0_INTERNAL bool m0_htable_is_init(const struct m0_htable *htable)
M0_INTERNAL void m0_hbucket_unlock(struct m0_htable *htable, const void *key)
M0_INTERNAL void m0_hbucket_lock(struct m0_htable *htable, const void *key)
struct m0_hbucket * h_buckets
M0_INTERNAL int m0_htable_init(const struct m0_ht_descr *d, struct m0_htable *htable, uint64_t bucket_nr)
M0_INTERNAL void * m0_htable_cc_lookup(struct m0_htable *htable, const void *key)
bool(* hd_key_eq)(const void *key1, const void *key2)
M0_INTERNAL void m0_htable_cc_add(struct m0_htable *htable, void *amb)
const struct m0_ht_descr * h_descr
M0_INTERNAL void m0_htable_add(struct m0_htable *htable, void *amb)
M0_INTERNAL void m0_htable_fini(struct m0_htable *htable)
M0_INTERNAL void m0_htable_del(struct m0_htable *htable, void *amb)
M0_INTERNAL bool m0_htable_is_empty(const struct m0_htable *htable)
const struct m0_tl_descr * hd_tldescr
M0_INTERNAL uint64_t m0_htable_size(const struct m0_htable *htable)
uint64_t(* hd_hash_func)(const struct m0_htable *htable, const void *key)
M0_INTERNAL uint64_t m0_hash(uint64_t x)