| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 1 | #ifndef _LINUX_JHASH_H | 
 | 2 | #define _LINUX_JHASH_H | 
 | 3 |  | 
 | 4 | /* jhash.h: Jenkins hash support. | 
 | 5 |  * | 
| Jozsef Kadlecsik | 60d509c | 2010-12-03 02:39:01 +0000 | [diff] [blame] | 6 |  * Copyright (C) 2006. Bob Jenkins (bob_jenkins@burtleburtle.net) | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 7 |  * | 
 | 8 |  * http://burtleburtle.net/bob/hash/ | 
 | 9 |  * | 
 | 10 |  * These are the credits from Bob's sources: | 
 | 11 |  * | 
| Jozsef Kadlecsik | 60d509c | 2010-12-03 02:39:01 +0000 | [diff] [blame] | 12 |  * lookup3.c, by Bob Jenkins, May 2006, Public Domain. | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 13 |  * | 
| Jozsef Kadlecsik | 60d509c | 2010-12-03 02:39:01 +0000 | [diff] [blame] | 14 |  * These are functions for producing 32-bit hashes for hash table lookup. | 
 | 15 |  * hashword(), hashlittle(), hashlittle2(), hashbig(), mix(), and final() | 
 | 16 |  * are externally useful functions.  Routines to test the hash are included | 
 | 17 |  * if SELF_TEST is defined.  You can use this free for any purpose.  It's in | 
 | 18 |  * the public domain.  It has no warranty. | 
 | 19 |  * | 
 | 20 |  * Copyright (C) 2009-2010 Jozsef Kadlecsik (kadlec@blackhole.kfki.hu) | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 21 |  * | 
 | 22 |  * I've modified Bob's hash to be useful in the Linux kernel, and | 
| Jozsef Kadlecsik | 60d509c | 2010-12-03 02:39:01 +0000 | [diff] [blame] | 23 |  * any bugs present are my fault. | 
 | 24 |  * Jozsef | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 25 |  */ | 
| Jozsef Kadlecsik | 60d509c | 2010-12-03 02:39:01 +0000 | [diff] [blame] | 26 | #include <linux/bitops.h> | 
 | 27 | #include <linux/unaligned/packed_struct.h> | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 28 |  | 
| Jozsef Kadlecsik | 60d509c | 2010-12-03 02:39:01 +0000 | [diff] [blame] | 29 | /* Best hash sizes are of power of two */ | 
 | 30 | #define jhash_size(n)   ((u32)1<<(n)) | 
 | 31 | /* Mask the hash value, i.e (value & jhash_mask(n)) instead of (value % n) */ | 
 | 32 | #define jhash_mask(n)   (jhash_size(n)-1) | 
 | 33 |  | 
 | 34 | /* __jhash_mix -- mix 3 32-bit values reversibly. */ | 
 | 35 | #define __jhash_mix(a, b, c)			\ | 
 | 36 | {						\ | 
 | 37 | 	a -= c;  a ^= rol32(c, 4);  c += b;	\ | 
 | 38 | 	b -= a;  b ^= rol32(a, 6);  a += c;	\ | 
 | 39 | 	c -= b;  c ^= rol32(b, 8);  b += a;	\ | 
 | 40 | 	a -= c;  a ^= rol32(c, 16); c += b;	\ | 
 | 41 | 	b -= a;  b ^= rol32(a, 19); a += c;	\ | 
 | 42 | 	c -= b;  c ^= rol32(b, 4);  b += a;	\ | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 43 | } | 
 | 44 |  | 
| Jozsef Kadlecsik | 60d509c | 2010-12-03 02:39:01 +0000 | [diff] [blame] | 45 | /* __jhash_final - final mixing of 3 32-bit values (a,b,c) into c */ | 
 | 46 | #define __jhash_final(a, b, c)			\ | 
 | 47 | {						\ | 
 | 48 | 	c ^= b; c -= rol32(b, 14);		\ | 
 | 49 | 	a ^= c; a -= rol32(c, 11);		\ | 
 | 50 | 	b ^= a; b -= rol32(a, 25);		\ | 
 | 51 | 	c ^= b; c -= rol32(b, 16);		\ | 
 | 52 | 	a ^= c; a -= rol32(c, 4);		\ | 
 | 53 | 	b ^= a; b -= rol32(a, 14);		\ | 
 | 54 | 	c ^= b; c -= rol32(b, 24);		\ | 
 | 55 | } | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 56 |  | 
| Jozsef Kadlecsik | 60d509c | 2010-12-03 02:39:01 +0000 | [diff] [blame] | 57 | /* An arbitrary initial parameter */ | 
 | 58 | #define JHASH_INITVAL		0xdeadbeef | 
 | 59 |  | 
 | 60 | /* jhash - hash an arbitrary key | 
 | 61 |  * @k: sequence of bytes as key | 
 | 62 |  * @length: the length of the key | 
 | 63 |  * @initval: the previous hash, or an arbitray value | 
 | 64 |  * | 
 | 65 |  * The generic version, hashes an arbitrary sequence of bytes. | 
 | 66 |  * No alignment or length assumptions are made about the input key. | 
 | 67 |  * | 
 | 68 |  * Returns the hash value of the key. The result depends on endianness. | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 69 |  */ | 
 | 70 | static inline u32 jhash(const void *key, u32 length, u32 initval) | 
 | 71 | { | 
| Jozsef Kadlecsik | 60d509c | 2010-12-03 02:39:01 +0000 | [diff] [blame] | 72 | 	u32 a, b, c; | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 73 | 	const u8 *k = key; | 
 | 74 |  | 
| Jozsef Kadlecsik | 60d509c | 2010-12-03 02:39:01 +0000 | [diff] [blame] | 75 | 	/* Set up the internal state */ | 
 | 76 | 	a = b = c = JHASH_INITVAL + length + initval; | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 77 |  | 
| Jozsef Kadlecsik | 60d509c | 2010-12-03 02:39:01 +0000 | [diff] [blame] | 78 | 	/* All but the last block: affect some 32 bits of (a,b,c) */ | 
 | 79 | 	while (length > 12) { | 
 | 80 | 		a += __get_unaligned_cpu32(k); | 
 | 81 | 		b += __get_unaligned_cpu32(k + 4); | 
 | 82 | 		c += __get_unaligned_cpu32(k + 8); | 
 | 83 | 		__jhash_mix(a, b, c); | 
 | 84 | 		length -= 12; | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 85 | 		k += 12; | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 86 | 	} | 
| Jozsef Kadlecsik | 60d509c | 2010-12-03 02:39:01 +0000 | [diff] [blame] | 87 | 	/* Last block: affect all 32 bits of (c) */ | 
 | 88 | 	/* All the case statements fall through */ | 
 | 89 | 	switch (length) { | 
 | 90 | 	case 12: c += (u32)k[11]<<24; | 
 | 91 | 	case 11: c += (u32)k[10]<<16; | 
 | 92 | 	case 10: c += (u32)k[9]<<8; | 
 | 93 | 	case 9:  c += k[8]; | 
 | 94 | 	case 8:  b += (u32)k[7]<<24; | 
 | 95 | 	case 7:  b += (u32)k[6]<<16; | 
 | 96 | 	case 6:  b += (u32)k[5]<<8; | 
 | 97 | 	case 5:  b += k[4]; | 
 | 98 | 	case 4:  a += (u32)k[3]<<24; | 
 | 99 | 	case 3:  a += (u32)k[2]<<16; | 
 | 100 | 	case 2:  a += (u32)k[1]<<8; | 
 | 101 | 	case 1:  a += k[0]; | 
 | 102 | 		 __jhash_final(a, b, c); | 
 | 103 | 	case 0: /* Nothing left to add */ | 
 | 104 | 		break; | 
 | 105 | 	} | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 106 |  | 
 | 107 | 	return c; | 
 | 108 | } | 
 | 109 |  | 
| Jozsef Kadlecsik | 60d509c | 2010-12-03 02:39:01 +0000 | [diff] [blame] | 110 | /* jhash2 - hash an array of u32's | 
 | 111 |  * @k: the key which must be an array of u32's | 
 | 112 |  * @length: the number of u32's in the key | 
 | 113 |  * @initval: the previous hash, or an arbitray value | 
 | 114 |  * | 
 | 115 |  * Returns the hash value of the key. | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 116 |  */ | 
| Patrick McHardy | 8e87e01 | 2007-03-14 16:42:29 -0700 | [diff] [blame] | 117 | static inline u32 jhash2(const u32 *k, u32 length, u32 initval) | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 118 | { | 
| Jozsef Kadlecsik | 60d509c | 2010-12-03 02:39:01 +0000 | [diff] [blame] | 119 | 	u32 a, b, c; | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 120 |  | 
| Jozsef Kadlecsik | 60d509c | 2010-12-03 02:39:01 +0000 | [diff] [blame] | 121 | 	/* Set up the internal state */ | 
 | 122 | 	a = b = c = JHASH_INITVAL + (length<<2) + initval; | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 123 |  | 
| Jozsef Kadlecsik | 60d509c | 2010-12-03 02:39:01 +0000 | [diff] [blame] | 124 | 	/* Handle most of the key */ | 
 | 125 | 	while (length > 3) { | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 126 | 		a += k[0]; | 
 | 127 | 		b += k[1]; | 
 | 128 | 		c += k[2]; | 
 | 129 | 		__jhash_mix(a, b, c); | 
| Jozsef Kadlecsik | 60d509c | 2010-12-03 02:39:01 +0000 | [diff] [blame] | 130 | 		length -= 3; | 
 | 131 | 		k += 3; | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 132 | 	} | 
 | 133 |  | 
| Jozsef Kadlecsik | 60d509c | 2010-12-03 02:39:01 +0000 | [diff] [blame] | 134 | 	/* Handle the last 3 u32's: all the case statements fall through */ | 
 | 135 | 	switch (length) { | 
 | 136 | 	case 3: c += k[2]; | 
 | 137 | 	case 2: b += k[1]; | 
 | 138 | 	case 1: a += k[0]; | 
 | 139 | 		__jhash_final(a, b, c); | 
 | 140 | 	case 0:	/* Nothing left to add */ | 
 | 141 | 		break; | 
 | 142 | 	} | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 143 |  | 
 | 144 | 	return c; | 
 | 145 | } | 
 | 146 |  | 
 | 147 |  | 
| Jozsef Kadlecsik | 60d509c | 2010-12-03 02:39:01 +0000 | [diff] [blame] | 148 | /* jhash_3words - hash exactly 3, 2 or 1 word(s) */ | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 149 | static inline u32 jhash_3words(u32 a, u32 b, u32 c, u32 initval) | 
 | 150 | { | 
| Jozsef Kadlecsik | 60d509c | 2010-12-03 02:39:01 +0000 | [diff] [blame] | 151 | 	a += JHASH_INITVAL; | 
 | 152 | 	b += JHASH_INITVAL; | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 153 | 	c += initval; | 
 | 154 |  | 
| Jozsef Kadlecsik | 60d509c | 2010-12-03 02:39:01 +0000 | [diff] [blame] | 155 | 	__jhash_final(a, b, c); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 156 |  | 
 | 157 | 	return c; | 
 | 158 | } | 
 | 159 |  | 
 | 160 | static inline u32 jhash_2words(u32 a, u32 b, u32 initval) | 
 | 161 | { | 
 | 162 | 	return jhash_3words(a, b, 0, initval); | 
 | 163 | } | 
 | 164 |  | 
 | 165 | static inline u32 jhash_1word(u32 a, u32 initval) | 
 | 166 | { | 
 | 167 | 	return jhash_3words(a, 0, 0, initval); | 
 | 168 | } | 
 | 169 |  | 
 | 170 | #endif /* _LINUX_JHASH_H */ |