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 48
 		(h)+=(v)^((v)>>3); \
49 49
 	}while(0)
50 50
 
51
+/* like hash_update_str, but case insensitive 
52
+ * params: char* s   - string start,
53
+ *         char* end - end
54
+ *         char* p,  and unsigned v temporary vars (used)
55
+ *         unsigned h - result
56
+ * h should be initialized (e.g. set it to 0), the result in h */
57
+#define hash_update_case_str(s, end, p, v, h) \
58
+	do{ \
59
+		for ((p)=(s); (p)<=((end)-4); (p)+=4){ \
60
+			(v)=((*(p)<<24)+((p)[1]<<16)+((p)[2]<<8)+(p)[3])|0x20202020; \
61
+			(h)+=(v)^((v)>>3); \
62
+		} \
63
+		(v)=0; \
64
+		for (;(p)<(end); (p)++){ (v)<<=8; (v)+=*(p)|0x20;} \
65
+		(h)+=(v)^((v)>>3); \
66
+	}while(0)
67
+
51 68
 
52 69
 /* internal use: call it to adjust the h from hash_update_str */
53 70
 #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 102
 		(h)=16777259*(h)+((v)^((v)<<17)); \
103 103
 	}while(0)
104 104
 
105
+/*  like hash_update_str2 but case insensitive */
106
+#define hash_update_case_str2(s, end, p, v, h) \
107
+	do{ \
108
+		for ((p)=(s); (p)<=((end)-4); (p)+=4){ \
109
+			(v)=((*(p)|0x20)*16777213)+(((p)[1]|0x20)*65537)+\
110
+				(((p)[2]|0x20)*257)+((p)[3]|0x20); \
111
+			(h)=16777259*(h)+((v)^((v)<<17)); \
112
+		} \
113
+		(v)=0; \
114
+		for (;(p)<(end); (p)++){ (v)*=251; (v)+=*(p)|0x20;} \
115
+		(h)=16777259*(h)+((v)^((v)<<17)); \
116
+	}while(0)
117
+
105 118
 /* internal use: call it to adjust the h from hash_update_str */
106 119
 #define hash_finish2(h) (((h)+((h)>>7))+(((h)>>13)+((h)>>23)))
107 120
 
... ...
@@ -136,9 +167,80 @@ inline static unsigned int get_hash2_raw2(str* key1, str* key2)
136 136
 	
137 137
 	hash_update_str2(key1->s, key1->s+key1->len, p, v, h);
138 138
 	hash_update_str2(key2->s, key2->s+key2->len, p, v, h);
139
+	return hash_finish2(h);
140
+}
141
+
142
+
143
+
144
+/* "raw" 2 strings case insensitive hash (like get_hash2_raw but case 
145
+ * insensitive)
146
+ * returns an unsigned int (which you can use modulo table_size as hash value)
147
+ */
148
+inline static unsigned int get_hash2_case_raw(str* key1, str* key2)
149
+{
150
+	char* p;
151
+	register unsigned v;
152
+	register unsigned h;
153
+	
154
+	h=0;
155
+	
156
+	hash_update_case_str(key1->s, key1->s+key1->len, p, v, h);
157
+	hash_update_case_str(key2->s, key2->s+key2->len, p, v, h);
139 158
 	return hash_finish(h);
140 159
 }
141 160
 
142 161
 
143 162
 
163
+/* "raw" 1 string case insensitive hash
164
+ * returns an unsigned int (which you can use modulo table_size as hash value)
165
+ */
166
+inline static unsigned int get_hash1_case_raw(char* s, int len)
167
+{
168
+	char* p;
169
+	register unsigned v;
170
+	register unsigned h;
171
+	
172
+	h=0;
173
+	
174
+	hash_update_case_str(s, s+len, p, v, h);
175
+	return hash_finish(h);
176
+}
177
+
178
+
179
+/* same as get_hash1_raw2, but case insensitive and slower
180
+ * returns an unsigned int (which you can use modulo table_size as hash value)
181
+ */
182
+inline static unsigned int get_hash1_case_raw2(char* s, int len)
183
+{
184
+	char* p;
185
+	register unsigned v;
186
+	register unsigned h;
187
+	
188
+	h=0;
189
+	
190
+	hash_update_case_str2(s, s+len, p, v, h);
191
+	return hash_finish2(h);
192
+}
193
+
194
+
195
+
196
+/* "raw" 2 strings hash optimized for numeric strings (see above)
197
+ * same as get_hash2_raw2 but case insensitive and slower
198
+ * returns an unsigned int (which you can use modulo table_size as hash value)
199
+ */
200
+inline static unsigned int get_hash2_case_raw2(str* key1, str* key2)
201
+{
202
+	char* p;
203
+	register unsigned v;
204
+	register unsigned h;
205
+	
206
+	h=0;
207
+	
208
+	hash_update_case_str2(key1->s, key1->s+key1->len, p, v, h);
209
+	hash_update_case_str2(key2->s, key2->s+key2->len, p, v, h);
210
+	return hash_finish2(h);
211
+}
212
+
213
+
214
+
144 215
 #endif