| 
									
										
										
										
											2009-11-06 16:39:26 -08:00
										 |  |  | 
 | 
					
						
							|  |  |  | #include <linux/types.h>
 | 
					
						
							| 
									
										
										
										
											2009-11-07 20:18:22 -08:00
										 |  |  | #include "hash.h"
 | 
					
						
							| 
									
										
										
										
											2009-11-06 16:39:26 -08:00
										 |  |  | 
 | 
					
						
							|  |  |  | /*
 | 
					
						
							|  |  |  |  * Robert Jenkins' function for mixing 32-bit values | 
					
						
							|  |  |  |  * http://burtleburtle.net/bob/hash/evahash.html
 | 
					
						
							|  |  |  |  * a, b = random bits, c = input and output | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | #define crush_hashmix(a, b, c) do {			\
 | 
					
						
							|  |  |  | 		a = a-b;  a = a-c;  a = a^(c>>13);	\ | 
					
						
							|  |  |  | 		b = b-c;  b = b-a;  b = b^(a<<8);	\ | 
					
						
							|  |  |  | 		c = c-a;  c = c-b;  c = c^(b>>13);	\ | 
					
						
							|  |  |  | 		a = a-b;  a = a-c;  a = a^(c>>12);	\ | 
					
						
							|  |  |  | 		b = b-c;  b = b-a;  b = b^(a<<16);	\ | 
					
						
							|  |  |  | 		c = c-a;  c = c-b;  c = c^(b>>5);	\ | 
					
						
							|  |  |  | 		a = a-b;  a = a-c;  a = a^(c>>3);	\ | 
					
						
							|  |  |  | 		b = b-c;  b = b-a;  b = b^(a<<10);	\ | 
					
						
							|  |  |  | 		c = c-a;  c = c-b;  c = c^(b>>15);	\ | 
					
						
							|  |  |  | 	} while (0) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #define crush_hash_seed 1315423911
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-07 20:18:22 -08:00
										 |  |  | static __u32 crush_hash32_rjenkins1(__u32 a) | 
					
						
							| 
									
										
										
										
											2009-11-06 16:39:26 -08:00
										 |  |  | { | 
					
						
							|  |  |  | 	__u32 hash = crush_hash_seed ^ a; | 
					
						
							|  |  |  | 	__u32 b = a; | 
					
						
							|  |  |  | 	__u32 x = 231232; | 
					
						
							|  |  |  | 	__u32 y = 1232; | 
					
						
							|  |  |  | 	crush_hashmix(b, x, hash); | 
					
						
							|  |  |  | 	crush_hashmix(y, a, hash); | 
					
						
							|  |  |  | 	return hash; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-07 20:18:22 -08:00
										 |  |  | static __u32 crush_hash32_rjenkins1_2(__u32 a, __u32 b) | 
					
						
							| 
									
										
										
										
											2009-11-06 16:39:26 -08:00
										 |  |  | { | 
					
						
							|  |  |  | 	__u32 hash = crush_hash_seed ^ a ^ b; | 
					
						
							|  |  |  | 	__u32 x = 231232; | 
					
						
							|  |  |  | 	__u32 y = 1232; | 
					
						
							|  |  |  | 	crush_hashmix(a, b, hash); | 
					
						
							|  |  |  | 	crush_hashmix(x, a, hash); | 
					
						
							|  |  |  | 	crush_hashmix(b, y, hash); | 
					
						
							|  |  |  | 	return hash; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-07 20:18:22 -08:00
										 |  |  | static __u32 crush_hash32_rjenkins1_3(__u32 a, __u32 b, __u32 c) | 
					
						
							| 
									
										
										
										
											2009-11-06 16:39:26 -08:00
										 |  |  | { | 
					
						
							|  |  |  | 	__u32 hash = crush_hash_seed ^ a ^ b ^ c; | 
					
						
							|  |  |  | 	__u32 x = 231232; | 
					
						
							|  |  |  | 	__u32 y = 1232; | 
					
						
							|  |  |  | 	crush_hashmix(a, b, hash); | 
					
						
							|  |  |  | 	crush_hashmix(c, x, hash); | 
					
						
							|  |  |  | 	crush_hashmix(y, a, hash); | 
					
						
							|  |  |  | 	crush_hashmix(b, x, hash); | 
					
						
							|  |  |  | 	crush_hashmix(y, c, hash); | 
					
						
							|  |  |  | 	return hash; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-07 20:18:22 -08:00
										 |  |  | static __u32 crush_hash32_rjenkins1_4(__u32 a, __u32 b, __u32 c, __u32 d) | 
					
						
							| 
									
										
										
										
											2009-11-06 16:39:26 -08:00
										 |  |  | { | 
					
						
							|  |  |  | 	__u32 hash = crush_hash_seed ^ a ^ b ^ c ^ d; | 
					
						
							|  |  |  | 	__u32 x = 231232; | 
					
						
							|  |  |  | 	__u32 y = 1232; | 
					
						
							|  |  |  | 	crush_hashmix(a, b, hash); | 
					
						
							|  |  |  | 	crush_hashmix(c, d, hash); | 
					
						
							|  |  |  | 	crush_hashmix(a, x, hash); | 
					
						
							|  |  |  | 	crush_hashmix(y, b, hash); | 
					
						
							|  |  |  | 	crush_hashmix(c, x, hash); | 
					
						
							|  |  |  | 	crush_hashmix(y, d, hash); | 
					
						
							|  |  |  | 	return hash; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-07 20:18:22 -08:00
										 |  |  | static __u32 crush_hash32_rjenkins1_5(__u32 a, __u32 b, __u32 c, __u32 d, | 
					
						
							|  |  |  | 				      __u32 e) | 
					
						
							| 
									
										
										
										
											2009-11-06 16:39:26 -08:00
										 |  |  | { | 
					
						
							|  |  |  | 	__u32 hash = crush_hash_seed ^ a ^ b ^ c ^ d ^ e; | 
					
						
							|  |  |  | 	__u32 x = 231232; | 
					
						
							|  |  |  | 	__u32 y = 1232; | 
					
						
							|  |  |  | 	crush_hashmix(a, b, hash); | 
					
						
							|  |  |  | 	crush_hashmix(c, d, hash); | 
					
						
							|  |  |  | 	crush_hashmix(e, x, hash); | 
					
						
							|  |  |  | 	crush_hashmix(y, a, hash); | 
					
						
							|  |  |  | 	crush_hashmix(b, x, hash); | 
					
						
							|  |  |  | 	crush_hashmix(y, c, hash); | 
					
						
							|  |  |  | 	crush_hashmix(d, x, hash); | 
					
						
							|  |  |  | 	crush_hashmix(y, e, hash); | 
					
						
							|  |  |  | 	return hash; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2009-11-07 20:18:22 -08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | __u32 crush_hash32(int type, __u32 a) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	switch (type) { | 
					
						
							|  |  |  | 	case CRUSH_HASH_RJENKINS1: | 
					
						
							|  |  |  | 		return crush_hash32_rjenkins1(a); | 
					
						
							|  |  |  | 	default: | 
					
						
							|  |  |  | 		return 0; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | __u32 crush_hash32_2(int type, __u32 a, __u32 b) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	switch (type) { | 
					
						
							|  |  |  | 	case CRUSH_HASH_RJENKINS1: | 
					
						
							|  |  |  | 		return crush_hash32_rjenkins1_2(a, b); | 
					
						
							|  |  |  | 	default: | 
					
						
							|  |  |  | 		return 0; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | __u32 crush_hash32_3(int type, __u32 a, __u32 b, __u32 c) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	switch (type) { | 
					
						
							|  |  |  | 	case CRUSH_HASH_RJENKINS1: | 
					
						
							|  |  |  | 		return crush_hash32_rjenkins1_3(a, b, c); | 
					
						
							|  |  |  | 	default: | 
					
						
							|  |  |  | 		return 0; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | __u32 crush_hash32_4(int type, __u32 a, __u32 b, __u32 c, __u32 d) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	switch (type) { | 
					
						
							|  |  |  | 	case CRUSH_HASH_RJENKINS1: | 
					
						
							|  |  |  | 		return crush_hash32_rjenkins1_4(a, b, c, d); | 
					
						
							|  |  |  | 	default: | 
					
						
							|  |  |  | 		return 0; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | __u32 crush_hash32_5(int type, __u32 a, __u32 b, __u32 c, __u32 d, __u32 e) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	switch (type) { | 
					
						
							|  |  |  | 	case CRUSH_HASH_RJENKINS1: | 
					
						
							|  |  |  | 		return crush_hash32_rjenkins1_5(a, b, c, d, e); | 
					
						
							|  |  |  | 	default: | 
					
						
							|  |  |  | 		return 0; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | const char *crush_hash_name(int type) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	switch (type) { | 
					
						
							|  |  |  | 	case CRUSH_HASH_RJENKINS1: | 
					
						
							|  |  |  | 		return "rjenkins1"; | 
					
						
							|  |  |  | 	default: | 
					
						
							|  |  |  | 		return "unknown"; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } |