0001
0002 #include <linux/ceph/types.h>
0003 #include <linux/module.h>
0004
0005
0006
0007
0008
0009
0010 #define mix(a, b, c) \
0011 do { \
0012 a = a - b; a = a - c; a = a ^ (c >> 13); \
0013 b = b - c; b = b - a; b = b ^ (a << 8); \
0014 c = c - a; c = c - b; c = c ^ (b >> 13); \
0015 a = a - b; a = a - c; a = a ^ (c >> 12); \
0016 b = b - c; b = b - a; b = b ^ (a << 16); \
0017 c = c - a; c = c - b; c = c ^ (b >> 5); \
0018 a = a - b; a = a - c; a = a ^ (c >> 3); \
0019 b = b - c; b = b - a; b = b ^ (a << 10); \
0020 c = c - a; c = c - b; c = c ^ (b >> 15); \
0021 } while (0)
0022
0023 unsigned int ceph_str_hash_rjenkins(const char *str, unsigned int length)
0024 {
0025 const unsigned char *k = (const unsigned char *)str;
0026 __u32 a, b, c;
0027 __u32 len;
0028
0029
0030 len = length;
0031 a = 0x9e3779b9;
0032 b = a;
0033 c = 0;
0034
0035
0036 while (len >= 12) {
0037 a = a + (k[0] + ((__u32)k[1] << 8) + ((__u32)k[2] << 16) +
0038 ((__u32)k[3] << 24));
0039 b = b + (k[4] + ((__u32)k[5] << 8) + ((__u32)k[6] << 16) +
0040 ((__u32)k[7] << 24));
0041 c = c + (k[8] + ((__u32)k[9] << 8) + ((__u32)k[10] << 16) +
0042 ((__u32)k[11] << 24));
0043 mix(a, b, c);
0044 k = k + 12;
0045 len = len - 12;
0046 }
0047
0048
0049 c = c + length;
0050 switch (len) {
0051 case 11:
0052 c = c + ((__u32)k[10] << 24);
0053 fallthrough;
0054 case 10:
0055 c = c + ((__u32)k[9] << 16);
0056 fallthrough;
0057 case 9:
0058 c = c + ((__u32)k[8] << 8);
0059
0060 fallthrough;
0061 case 8:
0062 b = b + ((__u32)k[7] << 24);
0063 fallthrough;
0064 case 7:
0065 b = b + ((__u32)k[6] << 16);
0066 fallthrough;
0067 case 6:
0068 b = b + ((__u32)k[5] << 8);
0069 fallthrough;
0070 case 5:
0071 b = b + k[4];
0072 fallthrough;
0073 case 4:
0074 a = a + ((__u32)k[3] << 24);
0075 fallthrough;
0076 case 3:
0077 a = a + ((__u32)k[2] << 16);
0078 fallthrough;
0079 case 2:
0080 a = a + ((__u32)k[1] << 8);
0081 fallthrough;
0082 case 1:
0083 a = a + k[0];
0084
0085 }
0086 mix(a, b, c);
0087
0088 return c;
0089 }
0090
0091
0092
0093
0094 unsigned int ceph_str_hash_linux(const char *str, unsigned int length)
0095 {
0096 unsigned long hash = 0;
0097 unsigned char c;
0098
0099 while (length--) {
0100 c = *str++;
0101 hash = (hash + (c << 4) + (c >> 4)) * 11;
0102 }
0103 return hash;
0104 }
0105
0106
0107 unsigned int ceph_str_hash(int type, const char *s, unsigned int len)
0108 {
0109 switch (type) {
0110 case CEPH_STR_HASH_LINUX:
0111 return ceph_str_hash_linux(s, len);
0112 case CEPH_STR_HASH_RJENKINS:
0113 return ceph_str_hash_rjenkins(s, len);
0114 default:
0115 return -1;
0116 }
0117 }
0118 EXPORT_SYMBOL(ceph_str_hash);
0119
0120 const char *ceph_str_hash_name(int type)
0121 {
0122 switch (type) {
0123 case CEPH_STR_HASH_LINUX:
0124 return "linux";
0125 case CEPH_STR_HASH_RJENKINS:
0126 return "rjenkins";
0127 default:
0128 return "unknown";
0129 }
0130 }
0131 EXPORT_SYMBOL(ceph_str_hash_name);