Whamcloud - gitweb
Update copyrights on source files changed since 2010-02-15.
[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 (c) 2008, 2010, Oracle and/or its affiliates. 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
69 #define cfs_hash_long(val, bits)    hash_long(val, bits)
70 #else
71 /* Fast hashing routine for a long.
72    (C) 2002 William Lee Irwin III, IBM */
73
74 #if BITS_PER_LONG == 32
75 /* 2^31 + 2^29 - 2^25 + 2^22 - 2^19 - 2^16 + 1 */
76 #define CFS_GOLDEN_RATIO_PRIME          CFS_GOLDEN_RATIO_PRIME_32
77 #elif BITS_PER_LONG == 64
78 /*  2^63 + 2^61 - 2^57 + 2^54 - 2^51 - 2^18 + 1 */
79 #define CFS_GOLDEN_RATIO_PRIME          CFS_GOLDEN_RATIO_PRIME_64
80 #else
81 #error Define CFS_GOLDEN_RATIO_PRIME for your wordsize.
82 #endif
83
84 static inline unsigned long cfs_hash_long(unsigned long val, unsigned int bits)
85 {
86         unsigned long hash = val;
87
88 #if BITS_PER_LONG == 64
89         /*  Sigh, gcc can't optimise this alone like it does for 32 bits. */
90         unsigned long n = hash;
91         n <<= 18;
92         hash -= n;
93         n <<= 33;
94         hash -= n;
95         n <<= 3;
96         hash += n;
97         n <<= 3;
98         hash -= n;
99         n <<= 4;
100         hash += n;
101         n <<= 2;
102         hash += n;
103 #else
104         /* On some cpus multiply is faster, on others gcc will do shifts */
105         hash *= CFS_GOLDEN_RATIO_PRIME;
106 #endif
107
108         /* High bits are more random, so use them. */
109         return hash >> (BITS_PER_LONG - bits);
110 }
111 #if 0
112 static inline unsigned long hash_ptr(void *ptr, unsigned int bits)
113 {
114         return cfs_hash_long((unsigned long)ptr, bits);
115 }
116 #endif
117
118 /* !(__linux__ && __KERNEL__) */
119 #endif
120
121 struct cfs_hash_ops;
122
123 typedef struct cfs_hash_bucket {
124         cfs_hlist_head_t            hsb_head;       /* entries list */
125         cfs_atomic_t                hsb_count;      /* current entries */
126         cfs_rwlock_t                hsb_rwlock;     /* cfs_hash_bucket */
127 } cfs_hash_bucket_t;
128
129 #define CFS_MAX_HASH_NAME 16
130
131 typedef struct cfs_hash {
132         int                         hs_cur_bits;    /* current hash bits */
133         int                         hs_cur_mask;    /* current hash mask */
134         int                         hs_min_bits;    /* min hash bits */
135         int                         hs_max_bits;    /* max hash bits */
136         int                         hs_min_theta;   /* resize min threshold */
137         int                         hs_max_theta;   /* resize max threshold */
138         int                         hs_flags;       /* hash flags */
139         cfs_atomic_t                hs_count;       /* current entries */
140         cfs_atomic_t                hs_rehash_count;/* resize count */
141         struct cfs_hash_bucket    **hs_buckets;     /* hash buckets */
142         struct cfs_hash_ops        *hs_ops;         /* hash operations */
143         cfs_rwlock_t                hs_rwlock;      /* cfs_hash */
144         cfs_atomic_t                hs_refcount;
145         char                        hs_name[CFS_MAX_HASH_NAME];
146 } cfs_hash_t;
147
148 typedef struct cfs_hash_ops {
149         unsigned (*hs_hash)(cfs_hash_t *hs, void *key, unsigned mask);
150         void *   (*hs_key)(cfs_hlist_node_t *hnode);
151         int      (*hs_compare)(void *key, cfs_hlist_node_t *hnode);
152         void *   (*hs_get)(cfs_hlist_node_t *hnode);
153         void *   (*hs_put)(cfs_hlist_node_t *hnode);
154         void     (*hs_exit)(cfs_hlist_node_t *hnode);
155 } cfs_hash_ops_t;
156
157 #define CFS_HASH_DEBUG          0x0001  /* Enable expensive debug checks */
158 #define CFS_HASH_REHASH         0x0002  /* Enable dynamic hash resizing */
159
160 #define CFS_HOP(hs, op)        (hs)->hs_ops->hs_ ## op
161
162 static inline unsigned
163 cfs_hash_id(cfs_hash_t *hs, void *key, unsigned mask)
164 {
165         return CFS_HOP(hs, hash)(hs, key, mask);
166 }
167
168 static inline void *
169 cfs_hash_key(cfs_hash_t *hs, cfs_hlist_node_t *hnode)
170 {
171         return CFS_HOP(hs, key)(hnode);
172 }
173
174 /* Returns TRUE on a match. */
175 static inline int
176 cfs_hash_compare(cfs_hash_t *hs, void *key, cfs_hlist_node_t *hnode)
177 {
178         return CFS_HOP(hs, compare)(key, hnode);
179 }
180
181 static inline void *
182 cfs_hash_get(cfs_hash_t *hs, cfs_hlist_node_t *hnode)
183 {
184         return CFS_HOP(hs, get)(hnode);
185 }
186
187 static inline void *
188 cfs_hash_put(cfs_hash_t *hs, cfs_hlist_node_t *hnode)
189 {
190         return CFS_HOP(hs, put)(hnode);
191 }
192
193 static inline void
194 cfs_hash_exit(cfs_hash_t *hs, cfs_hlist_node_t *hnode)
195 {
196         /* This is allowed to be a NOOP */
197         if (CFS_HOP(hs, exit) != NULL)
198                 return CFS_HOP(hs, exit)(hnode);
199 }
200
201 /* Validate hnode references the correct key */
202 static inline void
203 __cfs_hash_key_validate(cfs_hash_t *hs, void *key,
204                         cfs_hlist_node_t *hnode)
205 {
206         if (unlikely(hs->hs_flags & CFS_HASH_DEBUG))
207                 LASSERT(cfs_hash_compare(hs, key, hnode));
208 }
209
210 /* Validate hnode is in the correct bucket */
211 static inline void
212 __cfs_hash_bucket_validate(cfs_hash_t *hs, cfs_hash_bucket_t *hsb,
213                            cfs_hlist_node_t *hnode)
214 {
215         unsigned i;
216
217         if (unlikely(hs->hs_flags & CFS_HASH_DEBUG)) {
218                 i = cfs_hash_id(hs, cfs_hash_key(hs, hnode), hs->hs_cur_mask);
219                 LASSERT(hs->hs_buckets[i] == hsb);
220         }
221 }
222
223 static inline cfs_hlist_node_t *
224 __cfs_hash_bucket_lookup(cfs_hash_t *hs,
225                          cfs_hash_bucket_t *hsb, void *key)
226 {
227         cfs_hlist_node_t *hnode;
228
229         cfs_hlist_for_each(hnode, &hsb->hsb_head)
230                 if (cfs_hash_compare(hs, key, hnode))
231                         return hnode;
232
233         return NULL;
234 }
235
236 static inline void *
237 __cfs_hash_bucket_add(cfs_hash_t *hs,
238                       cfs_hash_bucket_t *hsb,
239                       cfs_hlist_node_t *hnode)
240 {
241         cfs_hlist_add_head(hnode, &(hsb->hsb_head));
242         cfs_atomic_inc(&hsb->hsb_count);
243         cfs_atomic_inc(&hs->hs_count);
244
245         return cfs_hash_get(hs, hnode);
246 }
247
248 static inline void *
249 __cfs_hash_bucket_del(cfs_hash_t *hs,
250                       cfs_hash_bucket_t *hsb,
251                       cfs_hlist_node_t *hnode)
252 {
253         cfs_hlist_del_init(hnode);
254         LASSERT(cfs_atomic_read(&hsb->hsb_count) > 0);
255         cfs_atomic_dec(&hsb->hsb_count);
256         LASSERT(cfs_atomic_read(&hs->hs_count) > 0);
257         cfs_atomic_dec(&hs->hs_count);
258
259         return cfs_hash_put(hs, hnode);
260 }
261
262 /* Hash init/cleanup functions */
263 cfs_hash_t *cfs_hash_create(char *name, unsigned int cur_bits,
264                             unsigned int max_bits,
265                             cfs_hash_ops_t *ops, int flags);
266 cfs_hash_t *cfs_hash_getref(cfs_hash_t *hs);
267 void cfs_hash_putref(cfs_hash_t *hs);
268
269 /* Hash addition functions */
270 void cfs_hash_add(cfs_hash_t *hs, void *key,
271                   cfs_hlist_node_t *hnode);
272 int cfs_hash_add_unique(cfs_hash_t *hs, void *key,
273                         cfs_hlist_node_t *hnode);
274 void *cfs_hash_findadd_unique(cfs_hash_t *hs, void *key,
275                               cfs_hlist_node_t *hnode);
276
277 /* Hash deletion functions */
278 void *cfs_hash_del(cfs_hash_t *hs, void *key, cfs_hlist_node_t *hnode);
279 void *cfs_hash_del_key(cfs_hash_t *hs, void *key);
280
281 /* Hash lookup/for_each functions */
282 void *cfs_hash_lookup(cfs_hash_t *hs, void *key);
283 typedef void (*cfs_hash_for_each_cb_t)(void *obj, void *data);
284 void cfs_hash_for_each(cfs_hash_t *hs, cfs_hash_for_each_cb_t, void *data);
285 void cfs_hash_for_each_safe(cfs_hash_t *hs, cfs_hash_for_each_cb_t, void *data);
286 void cfs_hash_for_each_empty(cfs_hash_t *hs, cfs_hash_for_each_cb_t, void *data);
287 void cfs_hash_for_each_key(cfs_hash_t *hs, void *key,
288                            cfs_hash_for_each_cb_t, void *data);
289 typedef int (*cfs_hash_cond_opt_cb_t)(void *obj, void *data);
290 void cfs_hash_cond_del(cfs_hash_t *hs, cfs_hash_cond_opt_cb_t, void *data);
291
292 /*
293  * Rehash - Theta is calculated to be the average chained
294  * hash depth assuming a perfectly uniform hash funcion.
295  */
296 int cfs_hash_rehash(cfs_hash_t *hs, int bits);
297 void cfs_hash_rehash_key(cfs_hash_t *hs, void *old_key,
298                          void *new_key, cfs_hlist_node_t *hnode);
299
300
301 #define CFS_HASH_THETA_BITS  10
302
303 /* Return integer component of theta */
304 static inline int __cfs_hash_theta_int(int theta)
305 {
306         return (theta >> CFS_HASH_THETA_BITS);
307 }
308
309 /* Return a fractional value between 0 and 999 */
310 static inline int __cfs_hash_theta_frac(int theta)
311 {
312         return ((theta * 1000) >> CFS_HASH_THETA_BITS) -
313                (__cfs_hash_theta_int(theta) * 1000);
314 }
315
316 static inline int __cfs_hash_theta(cfs_hash_t *hs)
317 {
318         return (cfs_atomic_read(&hs->hs_count) <<
319                 CFS_HASH_THETA_BITS) >> hs->hs_cur_bits;
320 }
321
322 static inline void __cfs_hash_set_theta(cfs_hash_t *hs, int min, int max)
323 {
324         LASSERT(min < max);
325         hs->hs_min_theta = min;
326         hs->hs_max_theta = max;
327 }
328
329 /* Generic debug formatting routines mainly for proc handler */
330 int cfs_hash_debug_header(char *str, int size);
331 int cfs_hash_debug_str(cfs_hash_t *hs, char *str, int size);
332
333 /*
334  * Generic djb2 hash algorithm for character arrays.
335  */
336 static inline unsigned
337 cfs_hash_djb2_hash(void *key, size_t size, unsigned mask)
338 {
339         unsigned i, hash = 5381;
340
341         LASSERT(key != NULL);
342
343         for (i = 0; i < size; i++)
344                 hash = hash * 33 + ((char *)key)[i];
345
346         return (hash & mask);
347 }
348
349 /*
350  * Generic u32 hash algorithm.
351  */
352 static inline unsigned
353 cfs_hash_u32_hash(__u32 key, unsigned mask)
354 {
355         return ((key * CFS_GOLDEN_RATIO_PRIME_32) & mask);
356 }
357
358 /*
359  * Generic u64 hash algorithm.
360  */
361 static inline unsigned
362 cfs_hash_u64_hash(__u64 key, unsigned mask)
363 {
364         return ((unsigned)(key * CFS_GOLDEN_RATIO_PRIME_64) & mask);
365 }
366
367 #define cfs_hash_for_each_bucket(hs, hsb, pos)   \
368         for (pos = 0;                            \
369              pos <= hs->hs_cur_mask &&           \
370              (hsb = hs->hs_buckets[pos]);       \
371              pos++)
372
373 #define cfs_hash_for_each_bucket_restart(hs, hsb, pos)  \
374         for (/* pos=0 done once by caller */;           \
375              pos <= hs->hs_cur_mask &&                  \
376              (hsb = hs->hs_buckets[pos]);              \
377              pos++)
378 /* !__LIBCFS__HASH_H__ */
379 #endif