Whamcloud - gitweb
Branch HEAD
[fs/lustre-release.git] / libcfs / include / libcfs / libcfs_hash.h
1 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
2  * vim:expandtab:shiftwidth=8:tabstop=8:
3  *
4  * GPL HEADER START
5  *
6  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License version 2 only,
10  * as published by the Free Software Foundation.
11  *
12  * This program is distributed in the hope that it will be useful, but
13  * WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * General Public License version 2 for more details (a copy is included
16  * in the LICENSE file that accompanied this code).
17  *
18  * You should have received a copy of the GNU General Public License
19  * version 2 along with this program; If not, see
20  * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
21  *
22  * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
23  * CA 95054 USA or visit www.sun.com if you need additional information or
24  * have any questions.
25  *
26  * GPL HEADER END
27  */
28 /*
29  * Copyright  2008 Sun Microsystems, Inc. All rights reserved
30  * Use is subject to license terms.
31  */
32 /*
33  * This file is part of Lustre, http://www.lustre.org/
34  * Lustre is a trademark of Sun Microsystems, Inc.
35  *
36  * libcfs/include/libcfs/libcfs_hash.h
37  *
38  * Hashing routines
39  *
40  */
41
42 #ifndef __LIBCFS_HASH_H__
43 #define __LIBCFS_HASH_H__
44 /*
45  * Knuth recommends primes in approximately golden ratio to the maximum
46  * integer representable by a machine word for multiplicative hashing.
47  * Chuck Lever verified the effectiveness of this technique:
48  * http://www.citi.umich.edu/techreports/reports/citi-tr-00-1.pdf
49  *
50  * These primes are chosen to be bit-sparse, that is operations on
51  * them can use shifts and additions instead of multiplications for
52  * machines where multiplications are slow.
53  */
54 /* 2^31 + 2^29 - 2^25 + 2^22 - 2^19 - 2^16 + 1 */
55 #define CFS_GOLDEN_RATIO_PRIME_32 0x9e370001UL
56 /*  2^63 + 2^61 - 2^57 + 2^54 - 2^51 - 2^18 + 1 */
57 #define CFS_GOLDEN_RATIO_PRIME_64 0x9e37fffffffc0001ULL
58
59 /*
60  * Ideally we would use HAVE_HASH_LONG for this, but on linux we configure
61  * the linux kernel and user space at the same time, so we need to differentiate
62  * between them explicitely. If this is not needed on other architectures, then
63  * we'll need to move the functions to archi specific headers.
64  */
65
66 #if (defined __linux__ && defined __KERNEL__)
67 #include <linux/hash.h>
68 #else
69 /* Fast hashing routine for a long.
70    (C) 2002 William Lee Irwin III, IBM */
71
72 #if BITS_PER_LONG == 32
73 /* 2^31 + 2^29 - 2^25 + 2^22 - 2^19 - 2^16 + 1 */
74 #define CFS_GOLDEN_RATIO_PRIME          CFS_GOLDEN_RATIO_PRIME_32
75 #elif BITS_PER_LONG == 64
76 /*  2^63 + 2^61 - 2^57 + 2^54 - 2^51 - 2^18 + 1 */
77 #define CFS_GOLDEN_RATIO_PRIME          CFS_GOLDEN_RATIO_PRIME_64
78 #else
79 #error Define CFS_GOLDEN_RATIO_PRIME for your wordsize.
80 #endif
81
82 static inline unsigned long hash_long(unsigned long val, unsigned int bits)
83 {
84         unsigned long hash = val;
85
86 #if BITS_PER_LONG == 64
87         /*  Sigh, gcc can't optimise this alone like it does for 32 bits. */
88         unsigned long n = hash;
89         n <<= 18;
90         hash -= n;
91         n <<= 33;
92         hash -= n;
93         n <<= 3;
94         hash += n;
95         n <<= 3;
96         hash -= n;
97         n <<= 4;
98         hash += n;
99         n <<= 2;
100         hash += n;
101 #else
102         /* On some cpus multiply is faster, on others gcc will do shifts */
103         hash *= CFS_GOLDEN_RATIO_PRIME;
104 #endif
105
106         /* High bits are more random, so use them. */
107         return hash >> (BITS_PER_LONG - bits);
108 }
109 #if 0
110 static inline unsigned long hash_ptr(void *ptr, unsigned int bits)
111 {
112         return hash_long((unsigned long)ptr, bits);
113 }
114 #endif
115
116 /* !(__linux__ && __KERNEL__) */
117 #endif
118
119 struct cfs_hash_ops;
120
121 typedef struct cfs_hash_bucket {
122         struct hlist_head           hsb_head;       /* entries list */
123         atomic_t                    hsb_count;      /* current entries */
124         rwlock_t                    hsb_rwlock;     /* cfs_hash_bucket */
125 } cfs_hash_bucket_t;
126
127 #define CFS_MAX_HASH_NAME 16
128
129 typedef struct cfs_hash {
130         int                         hs_cur_bits;    /* current hash bits */
131         int                         hs_cur_mask;    /* current hash mask */
132         int                         hs_min_bits;    /* min hash bits */
133         int                         hs_max_bits;    /* max hash bits */
134         int                         hs_min_theta;   /* resize min threshold */
135         int                         hs_max_theta;   /* resize max threshold */
136         int                         hs_flags;       /* hash flags */
137         atomic_t                    hs_count;       /* current entries */
138         atomic_t                    hs_rehash_count;/* resize count */
139         struct cfs_hash_bucket    **hs_buckets;     /* hash buckets */
140         struct cfs_hash_ops        *hs_ops;         /* hash operations */
141         rwlock_t                    hs_rwlock;      /* cfs_hash */
142         char                        hs_name[CFS_MAX_HASH_NAME];
143 } cfs_hash_t;
144
145 typedef struct cfs_hash_ops {
146         unsigned (*hs_hash)(cfs_hash_t *hs, void *key, unsigned mask);
147         void *   (*hs_key)(struct hlist_node *hnode);
148         int      (*hs_compare)(void *key, struct hlist_node *hnode);
149         void *   (*hs_get)(struct hlist_node *hnode);
150         void *   (*hs_put)(struct hlist_node *hnode);
151         void     (*hs_exit)(struct hlist_node *hnode);
152 } cfs_hash_ops_t;
153
154 #define CFS_HASH_DEBUG          0x0001  /* Enable expensive debug checks */
155 #define CFS_HASH_REHASH         0x0002  /* Enable dynamic hash resizing */
156
157 #define CFS_HO(hs)             (hs)->hs_ops
158 #define CFS_HOP(hs, op)        (hs)->hs_ops->hs_ ## op
159
160 static inline unsigned
161 cfs_hash_id(cfs_hash_t *hs, void *key, unsigned mask)
162 {
163         LASSERT(hs);
164         LASSERT(CFS_HO(hs));
165         LASSERT(CFS_HOP(hs, hash));
166
167         return CFS_HOP(hs, hash)(hs, key, mask);
168 }
169
170 static inline void *
171 cfs_hash_key(cfs_hash_t *hs, struct hlist_node *hnode)
172 {
173         LASSERT(hs);
174         LASSERT(hnode);
175         LASSERT(CFS_HO(hs));
176
177         if (CFS_HOP(hs, key))
178                 return CFS_HOP(hs, key)(hnode);
179
180         return NULL;
181 }
182
183 /* Returns 1 on a match,
184  * XXX: This would be better if it returned, -1, 0, or 1 for
185  *      <, =, > respectivly.  It could then be used to implement
186  *      a CFS_HASH_SORT feature flags which could keep each hash
187  *      bucket in order.  This would increase insertion times
188  *      but could reduce lookup times for deep chains.  Ideally,
189  *      the rehash should keep chain depth short but if that
190  *      ends up not being the case this would be a nice feature.
191  */
192 static inline int
193 cfs_hash_compare(cfs_hash_t *hs, void *key, struct hlist_node *hnode)
194 {
195         LASSERT(hs);
196         LASSERT(hnode);
197         LASSERT(CFS_HO(hs));
198
199         if (CFS_HOP(hs, compare))
200                 return CFS_HOP(hs, compare)(key, hnode);
201
202         return -EOPNOTSUPP;
203 }
204
205 static inline void *
206 cfs_hash_get(cfs_hash_t *hs, struct hlist_node *hnode)
207 {
208         LASSERT(hs);
209         LASSERT(hnode);
210         LASSERT(CFS_HO(hs));
211
212         if (CFS_HOP(hs, get))
213                 return CFS_HOP(hs, get)(hnode);
214
215         return NULL;
216 }
217
218 static inline void *
219 cfs_hash_put(cfs_hash_t *hs, struct hlist_node *hnode)
220 {
221         LASSERT(hs);
222         LASSERT(hnode);
223         LASSERT(CFS_HO(hs));
224
225         if (CFS_HOP(hs, put))
226                 return CFS_HOP(hs, put)(hnode);
227
228         return NULL;
229 }
230
231 static inline void
232 cfs_hash_exit(cfs_hash_t *hs, struct hlist_node *hnode)
233 {
234         LASSERT(hs);
235         LASSERT(hnode);
236         LASSERT(CFS_HO(hs));
237
238         if (CFS_HOP(hs, exit))
239                 return CFS_HOP(hs, exit)(hnode);
240 }
241
242 /* Validate hnode references the correct key */
243 static inline void
244 __cfs_hash_key_validate(cfs_hash_t *hs, void *key,
245                         struct hlist_node *hnode)
246 {
247         if (unlikely(hs->hs_flags & CFS_HASH_DEBUG))
248                 LASSERT(cfs_hash_compare(hs, key, hnode) > 0);
249 }
250
251 /* Validate hnode is in the correct bucket */
252 static inline void
253 __cfs_hash_bucket_validate(cfs_hash_t *hs, cfs_hash_bucket_t *hsb,
254                            struct hlist_node *hnode)
255 {
256         unsigned i;
257
258         if (unlikely(hs->hs_flags & CFS_HASH_DEBUG)) {
259                 i = cfs_hash_id(hs, cfs_hash_key(hs, hnode), hs->hs_cur_mask);
260                 LASSERT(hs->hs_buckets[i] == hsb);
261         }
262 }
263
264 static inline struct hlist_node *
265 __cfs_hash_bucket_lookup(cfs_hash_t *hs,
266                          cfs_hash_bucket_t *hsb, void *key)
267 {
268         struct hlist_node *hnode;
269
270         hlist_for_each(hnode, &hsb->hsb_head)
271                 if (cfs_hash_compare(hs, key, hnode) > 0)
272                         return hnode;
273
274         return NULL;
275 }
276
277 static inline void *
278 __cfs_hash_bucket_add(cfs_hash_t *hs,
279                       cfs_hash_bucket_t *hsb,
280                       struct hlist_node *hnode)
281 {
282         hlist_add_head(hnode, &(hsb->hsb_head));
283         atomic_inc(&hsb->hsb_count);
284         atomic_inc(&hs->hs_count);
285
286         return cfs_hash_get(hs, hnode);
287 }
288
289 static inline void *
290 __cfs_hash_bucket_del(cfs_hash_t *hs,
291                       cfs_hash_bucket_t *hsb,
292                       struct hlist_node *hnode)
293 {
294         hlist_del_init(hnode);
295         LASSERT(atomic_read(&hsb->hsb_count) > 0);
296         atomic_dec(&hsb->hsb_count);
297         LASSERT(atomic_read(&hs->hs_count) > 0);
298         atomic_dec(&hs->hs_count);
299
300         return cfs_hash_put(hs, hnode);
301 }
302
303 /* Hash init/cleanup functions */
304 cfs_hash_t *cfs_hash_create(char *name, unsigned int cur_bits,
305                             unsigned int max_bits,
306                             cfs_hash_ops_t *ops, int flags);
307 void cfs_hash_destroy(cfs_hash_t *hs);
308
309 /* Hash addition functions */
310 void cfs_hash_add(cfs_hash_t *hs, void *key,
311                   struct hlist_node *hnode);
312 int cfs_hash_add_unique(cfs_hash_t *hs, void *key,
313                         struct hlist_node *hnode);
314 void *cfs_hash_findadd_unique(cfs_hash_t *hs, void *key,
315                               struct hlist_node *hnode);
316
317 /* Hash deletion functions */
318 void *cfs_hash_del(cfs_hash_t *hs, void *key, struct hlist_node *hnode);
319 void *cfs_hash_del_key(cfs_hash_t *hs, void *key);
320
321 /* Hash lookup/for_each functions */
322 void *cfs_hash_lookup(cfs_hash_t *hs, void *key);
323 typedef void (*cfs_hash_for_each_cb_t)(void *obj, void *data);
324 void cfs_hash_for_each(cfs_hash_t *hs, cfs_hash_for_each_cb_t, void *data);
325 void cfs_hash_for_each_safe(cfs_hash_t *hs, cfs_hash_for_each_cb_t, void *data);
326 void cfs_hash_for_each_empty(cfs_hash_t *hs, cfs_hash_for_each_cb_t, void *data);
327 void cfs_hash_for_each_key(cfs_hash_t *hs, void *key,
328                            cfs_hash_for_each_cb_t, void *data);
329
330 /*
331  * Rehash - Theta is calculated to be the average chained
332  * hash depth assuming a perfectly uniform hash funcion.
333  */
334 int cfs_hash_rehash(cfs_hash_t *hs, int bits);
335 void cfs_hash_rehash_key(cfs_hash_t *hs, void *old_key,
336                          void *new_key, struct hlist_node *hnode);
337
338
339 #define CFS_HASH_THETA_BITS  10
340
341 /* Return integer component of theta */
342 static inline int __cfs_hash_theta_int(int theta)
343 {
344         return (theta >> CFS_HASH_THETA_BITS);
345 }
346
347 /* Return a fractional value between 0 and 999 */
348 static inline int __cfs_hash_theta_frac(int theta)
349 {
350         return ((theta * 1000) >> CFS_HASH_THETA_BITS) -
351                (__cfs_hash_theta_int(theta) * 1000);
352 }
353
354 static inline int __cfs_hash_theta(cfs_hash_t *hs)
355 {
356         return (atomic_read(&hs->hs_count) <<
357                 CFS_HASH_THETA_BITS) >> hs->hs_cur_bits;
358 }
359
360 static inline void __cfs_hash_set_theta(cfs_hash_t *hs, int min, int max)
361 {
362         LASSERT(min < max);
363         hs->hs_min_theta = min;
364         hs->hs_max_theta = max;
365 }
366
367 /* Generic debug formatting routines mainly for proc handler */
368 int cfs_hash_debug_header(char *str, int size);
369 int cfs_hash_debug_str(cfs_hash_t *hs, char *str, int size);
370
371 /*
372  * Generic djb2 hash algorithm for character arrays.
373  */
374 static inline unsigned
375 cfs_hash_djb2_hash(void *key, size_t size, unsigned mask)
376 {
377         unsigned i, hash = 5381;
378
379         LASSERT(key != NULL);
380
381         for (i = 0; i < size; i++)
382                 hash = hash * 33 + ((char *)key)[i];
383
384         return (hash & mask);
385 }
386
387 /*
388  * Generic u32 hash algorithm.
389  */
390 static inline unsigned
391 cfs_hash_u32_hash(__u32 key, unsigned mask)
392 {
393         return ((key * CFS_GOLDEN_RATIO_PRIME_32) & mask);
394 }
395
396 /*
397  * Generic u64 hash algorithm.
398  */
399 static inline unsigned
400 cfs_hash_u64_hash(__u64 key, unsigned mask)
401 {
402         return ((unsigned)(key * CFS_GOLDEN_RATIO_PRIME_64) & mask);
403 }
404
405 #define cfs_hash_for_each_bucket(hs, hsb, pos)   \
406         for (pos = 0;                            \
407              pos <= hs->hs_cur_mask &&           \
408              ({ hsb = hs->hs_buckets[i]; 1; });  \
409              pos++)
410
411 /* !__LIBCFS__HASH_H__ */
412 #endif