Cleanup of spelling error in option.
[m6w6/libmemcached] / lib / memcached_hash.c
1 #include "common.h"
2
3 /* Defines */
4 static uint64_t FNV_64_INIT= 0xcbf29ce484222325LL;
5 static uint64_t FNV_64_PRIME= 0x100000001b3LL;
6
7 static uint32_t FNV_32_INIT= 2166136261UL;
8 static uint32_t FNV_32_PRIME= 16777619;
9
10 /* Prototypes */
11 static uint64_t internal_generate_hash(char *key, size_t key_length);
12 static uint64_t internal_generate_md5(char *key, size_t key_length);
13 static uint64_t internal_generate_ketama_md5(char *key, size_t key_length);
14
15 unsigned int memcached_generate_hash(memcached_st *ptr, char *key, size_t key_length)
16 {
17 uint64_t hash= 1; /* Just here to remove compile warning */
18 unsigned int x;
19
20 WATCHPOINT_ASSERT(ptr->number_of_hosts);
21
22 switch (ptr->hash)
23 {
24 case MEMCACHED_HASH_DEFAULT:
25 hash= internal_generate_hash(key, key_length);
26 break;
27 case MEMCACHED_HASH_MD5:
28 hash= internal_generate_md5(key, key_length);
29 break;
30 case MEMCACHED_HASH_CRC:
31 hash= ((hash_crc32(key, key_length) >> 16) & 0x7fff);
32 break;
33 /* FNV hash'es lifted from Dustin Sallings work */
34 case MEMCACHED_HASH_FNV1_64:
35 {
36 /* Thanks to pierre@demartines.com for the pointer */
37 hash= FNV_64_INIT;
38 for (x= 0; x < key_length; x++)
39 {
40 hash *= FNV_64_PRIME;
41 hash ^= key[x];
42 }
43 }
44 break;
45 case MEMCACHED_HASH_FNV1A_64:
46 {
47 hash= FNV_64_INIT;
48 for (x= 0; x < key_length; x++)
49 {
50 hash ^= key[x];
51 hash *= FNV_64_PRIME;
52 }
53 }
54 break;
55 case MEMCACHED_HASH_FNV1_32:
56 {
57 hash= FNV_32_INIT;
58 for (x= 0; x < key_length; x++)
59 {
60 hash *= FNV_32_PRIME;
61 hash ^= key[x];
62 }
63 }
64 break;
65 case MEMCACHED_HASH_FNV1A_32:
66 {
67 hash= FNV_32_INIT;
68 for (x= 0; x < key_length; x++)
69 {
70 hash ^= key[x];
71 hash *= FNV_32_PRIME;
72 }
73 }
74 break;
75 case MEMCACHED_HASH_KETAMA:
76 {
77 hash= internal_generate_ketama_md5(key, key_length);
78 break;
79 }
80 case MEMCACHED_HASH_HSIEH:
81 {
82 hash= hsieh_hash(key, key_length);
83 break;
84 }
85 }
86
87 WATCHPOINT_ASSERT(hash);
88
89 if (ptr->distribution == MEMCACHED_DISTRIBUTION_MODULA)
90 {
91 return hash % ptr->number_of_hosts;
92 }
93 else
94 {
95 unsigned int server_key;
96
97 server_key= hash % MEMCACHED_WHEEL_SIZE;
98
99 return ptr->wheel[server_key];
100 }
101 }
102
103 static uint64_t internal_generate_hash(char *key, size_t key_length)
104 {
105 char *ptr= key;
106 uint64_t value= 0;
107
108 while (--key_length)
109 {
110 value += *ptr++;
111 value += (value << 10);
112 value ^= (value >> 6);
113 }
114 value += (value << 3);
115 value ^= (value >> 11);
116 value += (value << 15);
117
118 return value == 0 ? 1 : value;
119 }
120
121 static uint64_t internal_generate_md5(char *key, size_t key_length)
122 {
123 unsigned char results[16];
124
125 md5_signature((unsigned char*)key, (unsigned int)key_length, results);
126
127 return (uint64_t)(( results[3] << 24 )
128 | ( results[2] << 16 )
129 | ( results[1] << 8 )
130 | results[0] );
131 }
132
133 static uint64_t internal_generate_ketama_md5(char *key, size_t key_length)
134 {
135 unsigned char results[16];
136
137 md5_signature((unsigned char*)key, (unsigned int)key_length, results);
138
139 return ((uint32_t) (results[3] & 0xFF) << 24)
140 | ((uint32_t) (results[2] & 0xFF) << 16)
141 | ((uint32_t) (results[1] & 0xFF) << 8)
142 | (results[0] & 0xFF);
143 }