Motr  M0
hash.h
Go to the documentation of this file.
1 /* -*- C -*- */
2 /*
3  * Copyright (c) 2013-2020 Seagate Technology LLC and/or its Affiliates
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  * For any questions about this software or licensing,
18  * please email opensource@seagate.com or cortx-questions@seagate.com.
19  *
20  */
21 
22 
23 #pragma once
24 
25 #ifndef __MOTR_LIB_HASH_H__
26 #define __MOTR_LIB_HASH_H__
27 
28 #include "lib/types.h"
29 #include "lib/tlist.h"
30 #include "lib/mutex.h"
31 
149 struct m0_htable;
150 struct m0_hbucket;
151 struct m0_ht_descr;
152 
156 struct m0_hbucket {
167 };
168 
173 struct m0_htable {
175  uint64_t h_magic;
176 
178  uint64_t h_bucket_nr;
179 
186 
188  const struct m0_ht_descr *h_descr;
189 };
190 
197 struct m0_ht_descr {
199  const struct m0_tl_descr *hd_tldescr;
200 
203 
205  uint64_t (*hd_hash_func) (const struct m0_htable *htable,
206  const void *key);
207 
213  bool (*hd_key_eq) (const void *key1, const void *key2);
214 };
215 
221 struct m0_hlink {
223 };
224 
236 M0_INTERNAL int m0_htable_init(const struct m0_ht_descr *d,
237  struct m0_htable *htable,
238  uint64_t bucket_nr);
239 
240 /* Checks if hash-table is initialised. */
241 M0_INTERNAL bool m0_htable_is_init(const struct m0_htable *htable);
242 
251 M0_INTERNAL void m0_htable_fini(struct m0_htable *htable);
252 
261 M0_INTERNAL void m0_htable_add(struct m0_htable *htable,
262  void *amb);
266 M0_INTERNAL void m0_htable_cc_add(struct m0_htable *htable,
267  void *amb);
276 M0_INTERNAL void m0_htable_del(struct m0_htable *htable,
277  void *amb);
278 
282 M0_INTERNAL void m0_htable_cc_del(struct m0_htable *htable,
283  void *amb);
284 
293 M0_INTERNAL void *m0_htable_lookup(const struct m0_htable *htable,
294  const void *key);
295 
299 M0_INTERNAL void *m0_htable_cc_lookup(struct m0_htable *htable,
300  const void *key);
301 
303 M0_INTERNAL bool m0_htable_is_empty(const struct m0_htable *htable);
304 
306 M0_INTERNAL uint64_t m0_htable_size(const struct m0_htable *htable);
307 
309 M0_INTERNAL void m0_hbucket_lock(struct m0_htable *htable,
310  const void *key);
311 
313 M0_INTERNAL void m0_hbucket_unlock(struct m0_htable *htable,
314  const void *key);
315 
317 #define M0_HT_DESCR(name, amb_type, key_field, hash_func, key_eq) \
318 { \
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), \
323 };
324 
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) \
329  \
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); \
333  \
334 M0_TL_DESCR_DEFINE(name, htname, scope, amb_type, amb_link_field.hl_link, \
335  amb_magic_field, amb_magic, head_magic); \
336  \
337 scope const struct m0_ht_descr name ## _ht = M0_HT_DESCR(name, \
338  amb_type, \
339  key_field, \
340  (uint64_t (*)(const struct m0_htable *, const void *))hash_func,\
341  (bool (*)(const void *, const void *))key_eq)
342 
344 #define M0_HT_DESCR_DECLARE(name, scope) \
345 scope const struct m0_ht_descr name ## _ht
346 
351 #define M0_HT_DECLARE(name, scope, amb_type, key_type) \
352  \
353 M0_TL_DECLARE(name, scope, amb_type); \
354  \
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);
372 
377 #define M0_HT_DEFINE(name, scope, amb_type, key_type) \
378  \
379 M0_TL_DEFINE(name, scope, amb_type); \
380  \
381 scope __AUN int name ## _htable_init(struct m0_htable *htable, \
382  uint64_t bucket_nr) \
383 { \
384  return m0_htable_init(&name ## _ht, htable, bucket_nr); \
385 } \
386  \
387 scope __AUN void name ## _htable_add(struct m0_htable *htable, \
388  amb_type *amb) \
389 { \
390  m0_htable_add(htable, amb); \
391 } \
392  \
393 scope __AUN void name ## _htable_del(struct m0_htable *htable, \
394  amb_type *amb) \
395 { \
396  m0_htable_del(htable, amb); \
397 } \
398  \
399 scope __AUN amb_type *name ## _htable_lookup(const struct m0_htable *htable, \
400  const key_type *key) \
401 { \
402  return m0_htable_lookup(htable, key); \
403 } \
404  \
405 scope __AUN void name ## _hbucket_lock(struct m0_htable *htable, \
406  const key_type *key) \
407 { \
408  m0_hbucket_lock(htable, key); \
409 } \
410  \
411 scope __AUN void name ## _hbucket_unlock(struct m0_htable *htable, \
412  const key_type *key) \
413 { \
414  m0_hbucket_unlock(htable, key); \
415 } \
416  \
417 scope __AUN void name ## _htable_cc_add(struct m0_htable *htable, \
418  amb_type *amb) \
419 { \
420  m0_htable_cc_add(htable, amb); \
421 } \
422  \
423 scope __AUN void name ## _htable_cc_del(struct m0_htable *htable, \
424  amb_type *amb) \
425 { \
426  m0_htable_cc_del(htable, amb); \
427 } \
428  \
429 scope __AUN amb_type * name ## _htable_cc_lookup(struct m0_htable *htable, \
430  const key_type *key) \
431 { \
432  return m0_htable_cc_lookup(htable, key); \
433 } \
434  \
435 scope __AUN void name ## _htable_fini(struct m0_htable *htable) \
436 { \
437  m0_htable_fini(htable); \
438 } \
439  \
440 scope __AUN bool name ## _htable_is_empty(const struct m0_htable *htable) \
441 { \
442  return m0_htable_is_empty(htable); \
443 } \
444  \
445 scope __AUN uint64_t name ## _htable_size(const struct m0_htable *htable) \
446 { \
447  return m0_htable_size(htable); \
448 } \
449 
450 
454 #define m0_hbucket_forall(name, var, bucket, ...) \
455 ({ \
456  typeof (bucket) __bucket = (bucket); \
457  \
458  m0_tl_forall(name, var, &__bucket->hb_objects, ({ __VA_ARGS__ ; }));\
459 })
460 
465 #define m0_htable_forall(name, var, htable, ...) \
466 ({ \
467  uint64_t cnt; \
468  typeof (htable) ht = (htable); \
469  \
470  for (cnt = 0; cnt < ht->h_bucket_nr; ++cnt) { \
471  if (!(m0_hbucket_forall(name, var, &ht->h_buckets[cnt], \
472  ({ __VA_ARGS__ ; })))) \
473  break; \
474  } \
475  cnt == ht->h_bucket_nr; \
476 })
477 
483 #define m0_htable_for(name, var, htable) \
484 ({ \
485  uint64_t __cnt; \
486  typeof (htable) ht = (htable); \
487  \
488  for (__cnt = 0; __cnt < ht->h_bucket_nr; ++__cnt) { \
489  m0_tl_for(name, &ht->h_buckets[__cnt].hb_objects, var)
490 
491 #define m0_htable_endfor m0_tl_endfor; }; })
492 
498 #define m0_hbucket_for(descr, var, bucket) \
499 ({ \
500  m0_tlist_for (descr, &bucket->hb_objects, var)
501 
502 #define m0_hbucket_endfor m0_tlist_endfor; })
503 
508 #define m0_hbucket_forall_ol(descr, var, bucket, ...) \
509 ({ \
510  typeof(descr) d = descr; \
511  m0_hbucket_for (d, var, bucket) { \
512  if (!({ __VA_ARGS__; })) \
513  break; \
514  } m0_hbucket_endfor; \
515  var == NULL; \
516 })
517 
519 M0_INTERNAL uint64_t m0_hash(uint64_t x);
520 
523 #endif /* __MOTR_LIB_HASH_H__ */
524 
525 /*
526  * Local variables:
527  * c-indentation-style: "K&R"
528  * c-basic-offset: 8
529  * tab-width: 8
530  * fill-column: 80
531  * scroll-step: 1
532  * End:
533  */
struct m0_mutex hb_mutex
Definition: hash.h:160
M0_INTERNAL void * m0_htable_lookup(const struct m0_htable *htable, const void *key)
Definition: hash.c:162
Definition: module.c:324
static bool x
Definition: sm.c:168
M0_INTERNAL void m0_htable_cc_del(struct m0_htable *htable, void *amb)
Definition: hash.c:192
M0_INTERNAL bool m0_htable_is_init(const struct m0_htable *htable)
Definition: hash.c:127
M0_INTERNAL void m0_hbucket_unlock(struct m0_htable *htable, const void *key)
Definition: hash.c:226
M0_INTERNAL void m0_hbucket_lock(struct m0_htable *htable, const void *key)
Definition: hash.c:215
static int key
Definition: locality.c:283
struct m0_hbucket * h_buckets
Definition: hash.h:185
M0_INTERNAL int m0_htable_init(const struct m0_ht_descr *d, struct m0_htable *htable, uint64_t bucket_nr)
Definition: hash.c:103
Definition: tlist.h:251
M0_INTERNAL void * m0_htable_cc_lookup(struct m0_htable *htable, const void *key)
Definition: hash.c:202
bool(* hd_key_eq)(const void *key1, const void *key2)
Definition: hash.h:213
M0_INTERNAL void m0_htable_cc_add(struct m0_htable *htable, void *amb)
Definition: hash.c:182
const struct m0_ht_descr * h_descr
Definition: hash.h:188
M0_INTERNAL void m0_htable_add(struct m0_htable *htable, void *amb)
Definition: hash.c:132
M0_INTERNAL void m0_htable_fini(struct m0_htable *htable)
Definition: hash.c:237
uint64_t h_magic
Definition: hash.h:175
M0_INTERNAL void m0_htable_del(struct m0_htable *htable, void *amb)
Definition: hash.c:150
M0_INTERNAL bool m0_htable_is_empty(const struct m0_htable *htable)
Definition: hash.c:252
struct m0_tl hb_objects
Definition: hash.h:166
Definition: mutex.h:47
const struct m0_tl_descr * hd_tldescr
Definition: hash.h:199
M0_INTERNAL uint64_t m0_htable_size(const struct m0_htable *htable)
Definition: hash.c:266
uint64_t h_bucket_nr
Definition: hash.h:178
uint64_t(* hd_hash_func)(const struct m0_htable *htable, const void *key)
Definition: hash.h:205
size_t hd_key_offset
Definition: hash.h:202
Definition: idx_mock.c:47
M0_INTERNAL uint64_t m0_hash(uint64_t x)
Definition: hash.c:279