This commit was manufactured by cvs2svn to create branch 'vserver'.
[linux-2.6.git] / include / linux / netfilter_ipv4 / ip_set_jhash.h
1 #ifndef _LINUX_IPSET_JHASH_H
2 #define _LINUX_IPSET_JHASH_H
3
4 /* This is a copy of linux/jhash.h but the types u32/u8 are changed
5  * to __u32/__u8 so that the header file can be included into
6  * userspace code as well. Jozsef Kadlecsik (kadlec@blackhole.kfki.hu)
7  */
8
9 /* jhash.h: Jenkins hash support.
10  *
11  * Copyright (C) 1996 Bob Jenkins (bob_jenkins@burtleburtle.net)
12  *
13  * http://burtleburtle.net/bob/hash/
14  *
15  * These are the credits from Bob's sources:
16  *
17  * lookup2.c, by Bob Jenkins, December 1996, Public Domain.
18  * hash(), hash2(), hash3, and mix() are externally useful functions.
19  * Routines to test the hash are included if SELF_TEST is defined.
20  * You can use this free for any purpose.  It has no warranty.
21  *
22  * Copyright (C) 2003 David S. Miller (davem@redhat.com)
23  *
24  * I've modified Bob's hash to be useful in the Linux kernel, and
25  * any bugs present are surely my fault.  -DaveM
26  */
27
28 /* NOTE: Arguments are modified. */
29 #define __jhash_mix(a, b, c) \
30 { \
31   a -= b; a -= c; a ^= (c>>13); \
32   b -= c; b -= a; b ^= (a<<8); \
33   c -= a; c -= b; c ^= (b>>13); \
34   a -= b; a -= c; a ^= (c>>12);  \
35   b -= c; b -= a; b ^= (a<<16); \
36   c -= a; c -= b; c ^= (b>>5); \
37   a -= b; a -= c; a ^= (c>>3);  \
38   b -= c; b -= a; b ^= (a<<10); \
39   c -= a; c -= b; c ^= (b>>15); \
40 }
41
42 /* The golden ration: an arbitrary value */
43 #define JHASH_GOLDEN_RATIO      0x9e3779b9
44
45 /* The most generic version, hashes an arbitrary sequence
46  * of bytes.  No alignment or length assumptions are made about
47  * the input key.
48  */
49 static inline __u32 jhash(void *key, __u32 length, __u32 initval)
50 {
51         __u32 a, b, c, len;
52         __u8 *k = key;
53
54         len = length;
55         a = b = JHASH_GOLDEN_RATIO;
56         c = initval;
57
58         while (len >= 12) {
59                 a += (k[0] +((__u32)k[1]<<8) +((__u32)k[2]<<16) +((__u32)k[3]<<24));
60                 b += (k[4] +((__u32)k[5]<<8) +((__u32)k[6]<<16) +((__u32)k[7]<<24));
61                 c += (k[8] +((__u32)k[9]<<8) +((__u32)k[10]<<16)+((__u32)k[11]<<24));
62
63                 __jhash_mix(a,b,c);
64
65                 k += 12;
66                 len -= 12;
67         }
68
69         c += length;
70         switch (len) {
71         case 11: c += ((__u32)k[10]<<24);
72         case 10: c += ((__u32)k[9]<<16);
73         case 9 : c += ((__u32)k[8]<<8);
74         case 8 : b += ((__u32)k[7]<<24);
75         case 7 : b += ((__u32)k[6]<<16);
76         case 6 : b += ((__u32)k[5]<<8);
77         case 5 : b += k[4];
78         case 4 : a += ((__u32)k[3]<<24);
79         case 3 : a += ((__u32)k[2]<<16);
80         case 2 : a += ((__u32)k[1]<<8);
81         case 1 : a += k[0];
82         };
83
84         __jhash_mix(a,b,c);
85
86         return c;
87 }
88
89 /* A special optimized version that handles 1 or more of __u32s.
90  * The length parameter here is the number of __u32s in the key.
91  */
92 static inline __u32 jhash2(__u32 *k, __u32 length, __u32 initval)
93 {
94         __u32 a, b, c, len;
95
96         a = b = JHASH_GOLDEN_RATIO;
97         c = initval;
98         len = length;
99
100         while (len >= 3) {
101                 a += k[0];
102                 b += k[1];
103                 c += k[2];
104                 __jhash_mix(a, b, c);
105                 k += 3; len -= 3;
106         }
107
108         c += length * 4;
109
110         switch (len) {
111         case 2 : b += k[1];
112         case 1 : a += k[0];
113         };
114
115         __jhash_mix(a,b,c);
116
117         return c;
118 }
119
120
121 /* A special ultra-optimized versions that knows they are hashing exactly
122  * 3, 2 or 1 word(s).
123  *
124  * NOTE: In partilar the "c += length; __jhash_mix(a,b,c);" normally
125  *       done at the end is not done here.
126  */
127 static inline __u32 jhash_3words(__u32 a, __u32 b, __u32 c, __u32 initval)
128 {
129         a += JHASH_GOLDEN_RATIO;
130         b += JHASH_GOLDEN_RATIO;
131         c += initval;
132
133         __jhash_mix(a, b, c);
134
135         return c;
136 }
137
138 static inline __u32 jhash_2words(__u32 a, __u32 b, __u32 initval)
139 {
140         return jhash_3words(a, b, 0, initval);
141 }
142
143 static inline __u32 jhash_1word(__u32 a, __u32 initval)
144 {
145         return jhash_3words(a, 0, 0, initval);
146 }
147
148 #endif /* _LINUX_IPSET_JHASH_H */