Motr  M0
hash.c
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 #include "lib/bob.h" /* m0_bob_type */
24 #include "lib/hash.h" /* m0_htable */
25 #include "lib/errno.h" /* Include appropriate errno.h header. */
26 #include "motr/magic.h"
27 #include "ut/ut.h" /* M0_UT_ASSERT() */
28 
29 /*
30  * Once upon a time, there was a hash in a bar, which consists of
31  * number of foos!
32  * And all foos shared their keys in order to enroll into the hash.
33  */
34 struct bar {
35  /* Holds BAR_MAGIC. */
36  uint64_t b_magic;
37  int b_rc;
38  struct m0_htable b_hash;
39 };
40 
41 struct foo {
42  /* Holds FOO_MAGIC. */
43  uint64_t f_magic;
44  uint64_t f_hkey;
45  int f_subject;
46  struct m0_hlink f_hlink;
47 };
48 
49 enum {
50  BUCKET_NR = 8,
51  FOO_NR = 19,
52  BAR_MAGIC = 0xa817115ad15ababaULL,
53  FOO_MAGIC = 0x911ea3a7096a96e5ULL,
54 };
55 
56 static struct foo foos[FOO_NR];
57 static struct bar thebar;
58 
59 static uint64_t hash_func(const struct m0_htable *htable, const void *k)
60 {
61  const uint64_t *key = k;
62 
63  return *key % htable->h_bucket_nr;
64 }
65 
66 static bool key_eq(const void *key1, const void *key2)
67 {
68  const uint64_t *k1 = key1;
69  const uint64_t *k2 = key2;
70 
71  return *k1 == *k2;
72 }
73 
74 M0_HT_DESCR_DEFINE(foohash, "Hash of fops", static, struct foo,
75  f_hlink, f_magic, FOO_MAGIC, BAR_MAGIC,
76  f_hkey, hash_func, key_eq);
77 
78 M0_HT_DEFINE(foohash, static, struct foo, uint64_t);
79 
80 void test_hashtable(void)
81 {
82  int i;
83  int rc;
84  uint64_t key;
85  struct foo *f;
86  struct m0_hbucket *hb;
87 
88  for (i = 0; i < FOO_NR; ++i) {
90  foos[i].f_hkey = i;
91  foos[i].f_subject = 0;
92  m0_tlink_init(&foohash_tl, &foos[i]);
93  }
94 
96  thebar.b_rc = 0;
97  rc = foohash_htable_init(&thebar.b_hash, BUCKET_NR);
98  M0_UT_ASSERT(rc == 0);
102 
103  foohash_htable_add(&thebar.b_hash, &foos[0]);
104  M0_UT_ASSERT(foohash_htable_size(&thebar.b_hash) == 1);
105  M0_UT_ASSERT(!foohash_htable_is_empty(&thebar.b_hash));
106  key = 0;
107  M0_UT_ASSERT(foohash_htable_lookup(&thebar.b_hash, &key) == &foos[0]);
108  key = 1;
109  M0_UT_ASSERT(foohash_htable_lookup(&thebar.b_hash, &key) == NULL);
110 
112  h_buckets[0].hb_objects));
113 
114  foohash_htable_del(&thebar.b_hash, &foos[0]);
115  M0_UT_ASSERT(foohash_htable_is_empty(&thebar.b_hash));
116  M0_UT_ASSERT(foohash_htable_size(&thebar.b_hash) == 0);
117  M0_UT_ASSERT(foohash_htable_lookup(&thebar.b_hash, &foos[0].f_hkey) ==
118  NULL);
119 
120  for (i = 0; i < FOO_NR; ++i) {
121  foohash_htable_add(&thebar.b_hash, &foos[i]);
122  M0_UT_ASSERT(m0_tlink_is_in(&foohash_tl, &foos[i]));
123  }
124  M0_UT_ASSERT(foohash_htable_size(&thebar.b_hash) == FOO_NR);
125 
126  for (i = 0; i < BUCKET_NR; ++i) {
127  hb = &thebar.b_hash.h_buckets[i];
128  M0_UT_ASSERT(!m0_tlist_is_empty(&foohash_tl, &hb->hb_objects));
129  M0_UT_ASSERT(m0_hbucket_forall(foohash, f, hb,
130  f->f_hkey % BUCKET_NR == i));
131  }
133  f->f_subject == 0));
134 
135  m0_htable_for(foohash, f, &thebar.b_hash) {
136  f->f_subject = 1;
138 
140  f->f_subject == 1));
141 
142  for (i = 0; i < FOO_NR; ++i) {
143  foohash_htable_del(&thebar.b_hash, &foos[i]);
144  M0_UT_ASSERT(foohash_htable_size(&thebar.b_hash) ==
145  FOO_NR - (i + 1));
146  M0_UT_ASSERT(foohash_htable_lookup(&thebar.b_hash,
147  &foos[i].f_hkey) == NULL);
148  M0_UT_ASSERT(!m0_tlink_is_in(&foohash_tl, &foos[i]));
149  }
150  M0_UT_ASSERT(foohash_htable_size(&thebar.b_hash) == 0);
151  M0_UT_ASSERT(foohash_htable_is_empty(&thebar.b_hash));
152 
153  foohash_htable_fini(&thebar.b_hash);
157 }
158 
159 /*
160  * Local variables:
161  * c-indentation-style: "K&R"
162  * c-basic-offset: 8
163  * tab-width: 8
164  * fill-column: 80
165  * scroll-step: 1
166  * End:
167  */
Definition: hash.c:53
#define m0_htable_for(name, var, htable)
Definition: hash.h:483
static const uint64_t k1
Definition: hash_fnc.c:34
#define NULL
Definition: misc.h:38
#define m0_hbucket_forall(name, var, bucket,...)
Definition: hash.h:454
uint64_t f_hkey
Definition: hash.c:44
Definition: hash.c:52
static uint64_t hash_func(const struct m0_htable *htable, const void *k)
Definition: hash.c:59
static FILE * f
Definition: adieu.c:79
Definition: bob.c:32
struct m0_hlink f_hlink
Definition: hash.c:46
struct m0_htable b_hash
Definition: hash.c:38
static struct foo foos[FOO_NR]
Definition: hash.c:56
M0_INTERNAL bool m0_tlist_is_empty(const struct m0_tl_descr *d, const struct m0_tl *list)
Definition: tlist.c:96
Definition: hash.c:34
int i
Definition: dir.c:1033
static int key
Definition: locality.c:283
struct m0_hbucket * h_buckets
Definition: hash.h:185
void test_hashtable(void)
Definition: hash.c:80
#define m0_htable_forall(name, var, htable,...)
Definition: hash.h:465
static struct bar thebar
Definition: hash.c:57
M0_INTERNAL void m0_tlink_init(const struct m0_tl_descr *d, void *obj)
Definition: tlist.c:63
uint64_t f_magic
Definition: hash.c:43
static const uint64_t k2
Definition: hash_fnc.c:35
static bool key_eq(const void *key1, const void *key2)
Definition: hash.c:66
M0_INTERNAL bool m0_tlink_is_in(const struct m0_tl_descr *d, const void *obj)
Definition: tlist.c:103
Definition: hash.c:51
uint64_t h_magic
Definition: hash.h:175
int b_rc
Definition: hash.c:37
M0_HT_DESCR_DEFINE(foohash, "Hash of fops", static, struct foo, f_hlink, f_magic, FOO_MAGIC, BAR_MAGIC, f_hkey, hash_func, key_eq)
uint64_t b_magic
Definition: hash.c:36
M0_HT_DEFINE(foohash, static, struct foo, uint64_t)
struct m0_tl hb_objects
Definition: hash.h:166
#define m0_htable_endfor
Definition: hash.h:491
int f_subject
Definition: hash.c:45
int32_t rc
Definition: trigger_fop.h:47
uint64_t h_bucket_nr
Definition: hash.h:178
#define M0_UT_ASSERT(a)
Definition: ut.h:46
Definition: hash.c:50
Definition: idx_mock.c:47