1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
|
#ifndef _LINUX_JHASH_H
#define _LINUX_JHASH_H
/* jhash.c: Jenkins hash support.
*
* Copyright (C) 2006. Bob Jenkins (bob_jenkins@burtleburtle.net)
*
* http://burtleburtle.net/bob/hash/
*
* These are the credits from Bob's sources:
*
* lookup3.c, by Bob Jenkins, May 2006, Public Domain.
*
* These are functions for producing 32-bit hashes for hash table lookup.
* hashword(), hashlittle(), hashlittle2(), hashbig(), mix(), and final()
* are externally useful functions. Routines to test the hash are included
* if SELF_TEST is defined. You can use this free for any purpose. It's in
* the public domain. It has no warranty.
*
* Copyright (C) 2009-2010 Jozsef Kadlecsik (kadlec@blackhole.kfki.hu)
*
* I've modified Bob's hash to be useful in the Linux kernel, and
* any bugs present are my fault. The generic jhash is left out intentionally.
* Jozsef
*/
#ifdef __KERNEL__
#include <asm/byteorder.h>
/* Best hash sizes are of power of two */
#define jhash_size(n) ((u32)1<<(n))
/* Mask the hash value, i.e (value & jhash_mask(n)) instead of (value % n) */
#define jhash_mask(n) (jhash_size(n)-1)
/* __jhash_rot - rotate 32 bit */
#define __jhash_rot(x,k) (((x)<<(k)) | ((x)>>(32-(k))))
/* __jhash_mix -- mix 3 32-bit values reversibly. */
#define __jhash_mix(a,b,c) \
{ \
a -= c; a ^= __jhash_rot(c, 4); c += b; \
b -= a; b ^= __jhash_rot(a, 6); a += c; \
c -= b; c ^= __jhash_rot(b, 8); b += a; \
a -= c; a ^= __jhash_rot(c,16); c += b; \
b -= a; b ^= __jhash_rot(a,19); a += c; \
c -= b; c ^= __jhash_rot(b, 4); b += a; \
}
/* __jhash_final - final mixing of 3 32-bit values (a,b,c) into c */
#define __jhash_final(a,b,c) \
{ \
c ^= b; c -= __jhash_rot(b,14); \
a ^= c; a -= __jhash_rot(c,11); \
b ^= a; b -= __jhash_rot(a,25); \
c ^= b; c -= __jhash_rot(b,16); \
a ^= c; a -= __jhash_rot(c,4); \
b ^= a; b -= __jhash_rot(a,14); \
c ^= b; c -= __jhash_rot(b,24); \
}
#define JHASH_INITVAL 0xdeadbeef
/* jhash2 - hash an array of u32's
* @k: the key which must be an array of u32's
* @length: the number of u32's in the key
* @initval: the previous hash, or an arbitray value
*
* Returns the hash value of the key.
*/
static inline u32 jhash2(const u32 *k, u32 length, u32 initval)
{
u32 a, b, c;
/* Set up the internal state */
a = b = c = JHASH_INITVAL + (length<<2) + initval;
/* Handle most of the key */
while (length > 3) {
a += k[0];
b += k[1];
c += k[2];
__jhash_mix(a,b,c);
length -= 3;
k += 3;
}
/* Handle the last 3 u32's: all the case statements fall through */
switch(length) {
case 3: c += k[2];
case 2: b += k[1];
case 1: a += k[0];
__jhash_final(a,b,c);
case 0: /* Nothing left to add */
break;
}
return c;
}
/* jhash_3words - hash exactly 3, 2 or 1 word(s) */
static inline u32 jhash_3words(u32 a, u32 b, u32 c, u32 initval)
{
a += JHASH_INITVAL;
b += JHASH_INITVAL;
c += initval;
__jhash_final(a,b,c);
return c;
}
static inline u32 jhash_2words(u32 a, u32 b, u32 initval)
{
return jhash_3words(a, b, 0, initval);
}
static inline u32 jhash_1word(u32 a, u32 initval)
{
return jhash_3words(a, 0, 0, initval);
}
#endif /* __KERNEL__ */
#endif /* _LINUX_JHASH_H */
|