Browse code

- added case-insensitive hash functions - replaced dns case insensitve hash calc. with the version from hashes.h (and fixed a "paste error" in dns hash calculation in the process)

Andrei Pelinescu-Onciul authored on 22/02/2007 20:58:32
Showing 2 changed files
... ...
@@ -299,31 +299,12 @@ error:
299 299
 }
300 300
 
301 301
 
302
-/* hash function, based on get_hash1_raw, but case insensitive
303
- * type is not used (obsolete)
302
+/* hash function, type is not used (obsolete)
303
+ * params: char* s, int len, int type
304 304
  * returns the hash value
305 305
  */
306
-inline static unsigned int dns_hash_no(char* s, int len, int type)
307
-{
308
-	char* p;
309
-	char* end;
310
-	
311
-	register unsigned v;
312
-	register unsigned h;
313
-	
314
-	h=0;
315
-	
316
-	hash_update_str(s, s+len, p, v, h);
317
-	end=s+len;
318
-	for (p=s; p<=(end-4); p+=4){
319
-		v=((p[0]<<24)+(p[1]<<16)+(p[2]<<8)+p[3])|0x20202020;
320
-		h+=v^(v>>3);
321
-	}
322
-	v=0;
323
-	for (;p<end; p++){ v<<=8; v+=*p|0x20;}
324
-	h+=v^(v>>3);
325
-	return hash_finish(h) % DNS_HASH_SIZE;
326
-}
306
+#define dns_hash_no(s, len, type) \
307
+	(get_hash1_case_raw((s),(len)) % DNS_HASH_SIZE)
327 308
 
328 309
 
329 310
 
... ...
@@ -21,6 +21,7 @@
21 21
  *  2006-02-02  created by andrei
22 22
  *  2006-11-24  added numeric string optimized hash function (andrei)
23 23
  *  2006-12-13  split into hashes.h (more generic) and str_hash.h (andrei)
24
+ *  2007-02-22  added case insensitive versions (andrei)
24 25
  */
25 26
 
26 27
 
... ...
@@ -48,6 +49,23 @@
48 49
 		(h)+=(v)^((v)>>3); \
49 50
 	}while(0)
50 51
 
52
+/* like hash_update_str, but case insensitive 
53
+ * params: char* s   - string start,
54
+ *         char* end - end
55
+ *         char* p,  and unsigned v temporary vars (used)
56
+ *         unsigned h - result
57
+ * h should be initialized (e.g. set it to 0), the result in h */
58
+#define hash_update_case_str(s, end, p, v, h) \
59
+	do{ \
60
+		for ((p)=(s); (p)<=((end)-4); (p)+=4){ \
61
+			(v)=((*(p)<<24)+((p)[1]<<16)+((p)[2]<<8)+(p)[3])|0x20202020; \
62
+			(h)+=(v)^((v)>>3); \
63
+		} \
64
+		(v)=0; \
65
+		for (;(p)<(end); (p)++){ (v)<<=8; (v)+=*(p)|0x20;} \
66
+		(h)+=(v)^((v)>>3); \
67
+	}while(0)
68
+
51 69
 
52 70
 /* internal use: call it to adjust the h from hash_update_str */
53 71
 #define hash_finish(h) (((h)+((h)>>11))+(((h)>>13)+((h)>>23)))
... ...
@@ -102,6 +120,19 @@ inline static unsigned int get_hash1_raw(char* s, int len)
102 120
 		(h)=16777259*(h)+((v)^((v)<<17)); \
103 121
 	}while(0)
104 122
 
123
+/*  like hash_update_str2 but case insensitive */
124
+#define hash_update_case_str2(s, end, p, v, h) \
125
+	do{ \
126
+		for ((p)=(s); (p)<=((end)-4); (p)+=4){ \
127
+			(v)=((*(p)|0x20)*16777213)+(((p)[1]|0x20)*65537)+\
128
+				(((p)[2]|0x20)*257)+((p)[3]|0x20); \
129
+			(h)=16777259*(h)+((v)^((v)<<17)); \
130
+		} \
131
+		(v)=0; \
132
+		for (;(p)<(end); (p)++){ (v)*=251; (v)+=*(p)|0x20;} \
133
+		(h)=16777259*(h)+((v)^((v)<<17)); \
134
+	}while(0)
135
+
105 136
 /* internal use: call it to adjust the h from hash_update_str */
106 137
 #define hash_finish2(h) (((h)+((h)>>7))+(((h)>>13)+((h)>>23)))
107 138
 
... ...
@@ -136,9 +167,80 @@ inline static unsigned int get_hash2_raw2(str* key1, str* key2)
136 167
 	
137 168
 	hash_update_str2(key1->s, key1->s+key1->len, p, v, h);
138 169
 	hash_update_str2(key2->s, key2->s+key2->len, p, v, h);
170
+	return hash_finish2(h);
171
+}
172
+
173
+
174
+
175
+/* "raw" 2 strings case insensitive hash (like get_hash2_raw but case 
176
+ * insensitive)
177
+ * returns an unsigned int (which you can use modulo table_size as hash value)
178
+ */
179
+inline static unsigned int get_hash2_case_raw(str* key1, str* key2)
180
+{
181
+	char* p;
182
+	register unsigned v;
183
+	register unsigned h;
184
+	
185
+	h=0;
186
+	
187
+	hash_update_case_str(key1->s, key1->s+key1->len, p, v, h);
188
+	hash_update_case_str(key2->s, key2->s+key2->len, p, v, h);
139 189
 	return hash_finish(h);
140 190
 }
141 191
 
142 192
 
143 193
 
194
+/* "raw" 1 string case insensitive hash
195
+ * returns an unsigned int (which you can use modulo table_size as hash value)
196
+ */
197
+inline static unsigned int get_hash1_case_raw(char* s, int len)
198
+{
199
+	char* p;
200
+	register unsigned v;
201
+	register unsigned h;
202
+	
203
+	h=0;
204
+	
205
+	hash_update_case_str(s, s+len, p, v, h);
206
+	return hash_finish(h);
207
+}
208
+
209
+
210
+/* same as get_hash1_raw2, but case insensitive and slower
211
+ * returns an unsigned int (which you can use modulo table_size as hash value)
212
+ */
213
+inline static unsigned int get_hash1_case_raw2(char* s, int len)
214
+{
215
+	char* p;
216
+	register unsigned v;
217
+	register unsigned h;
218
+	
219
+	h=0;
220
+	
221
+	hash_update_case_str2(s, s+len, p, v, h);
222
+	return hash_finish2(h);
223
+}
224
+
225
+
226
+
227
+/* "raw" 2 strings hash optimized for numeric strings (see above)
228
+ * same as get_hash2_raw2 but case insensitive and slower
229
+ * returns an unsigned int (which you can use modulo table_size as hash value)
230
+ */
231
+inline static unsigned int get_hash2_case_raw2(str* key1, str* key2)
232
+{
233
+	char* p;
234
+	register unsigned v;
235
+	register unsigned h;
236
+	
237
+	h=0;
238
+	
239
+	hash_update_case_str2(key1->s, key1->s+key1->len, p, v, h);
240
+	hash_update_case_str2(key2->s, key2->s+key2->len, p, v, h);
241
+	return hash_finish2(h);
242
+}
243
+
244
+
245
+
144 246
 #endif