|
@@ -21,6 +21,7 @@
|
|
|
* 2006-02-02 created by andrei
|
|
|
* 2006-11-24 added numeric string optimized hash function (andrei)
|
|
|
* 2006-12-13 split into hashes.h (more generic) and str_hash.h (andrei)
|
|
|
+ * 2007-02-22 added case insensitive versions (andrei)
|
|
|
*/
|
|
|
|
|
|
|
|
@@ -48,6 +49,23 @@
|
|
|
(h)+=(v)^((v)>>3); \
|
|
|
}while(0)
|
|
|
|
|
|
+/* like hash_update_str, but case insensitive
|
|
|
+ * params: char* s - string start,
|
|
|
+ * char* end - end
|
|
|
+ * char* p, and unsigned v temporary vars (used)
|
|
|
+ * unsigned h - result
|
|
|
+ * h should be initialized (e.g. set it to 0), the result in h */
|
|
|
+#define hash_update_case_str(s, end, p, v, h) \
|
|
|
+ do{ \
|
|
|
+ for ((p)=(s); (p)<=((end)-4); (p)+=4){ \
|
|
|
+ (v)=((*(p)<<24)+((p)[1]<<16)+((p)[2]<<8)+(p)[3])|0x20202020; \
|
|
|
+ (h)+=(v)^((v)>>3); \
|
|
|
+ } \
|
|
|
+ (v)=0; \
|
|
|
+ for (;(p)<(end); (p)++){ (v)<<=8; (v)+=*(p)|0x20;} \
|
|
|
+ (h)+=(v)^((v)>>3); \
|
|
|
+ }while(0)
|
|
|
+
|
|
|
|
|
|
/* internal use: call it to adjust the h from hash_update_str */
|
|
|
#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)
|
|
|
(h)=16777259*(h)+((v)^((v)<<17)); \
|
|
|
}while(0)
|
|
|
|
|
|
+/* like hash_update_str2 but case insensitive */
|
|
|
+#define hash_update_case_str2(s, end, p, v, h) \
|
|
|
+ do{ \
|
|
|
+ for ((p)=(s); (p)<=((end)-4); (p)+=4){ \
|
|
|
+ (v)=((*(p)|0x20)*16777213)+(((p)[1]|0x20)*65537)+\
|
|
|
+ (((p)[2]|0x20)*257)+((p)[3]|0x20); \
|
|
|
+ (h)=16777259*(h)+((v)^((v)<<17)); \
|
|
|
+ } \
|
|
|
+ (v)=0; \
|
|
|
+ for (;(p)<(end); (p)++){ (v)*=251; (v)+=*(p)|0x20;} \
|
|
|
+ (h)=16777259*(h)+((v)^((v)<<17)); \
|
|
|
+ }while(0)
|
|
|
+
|
|
|
/* internal use: call it to adjust the h from hash_update_str */
|
|
|
#define hash_finish2(h) (((h)+((h)>>7))+(((h)>>13)+((h)>>23)))
|
|
|
|
|
@@ -136,9 +167,80 @@ inline static unsigned int get_hash2_raw2(str* key1, str* key2)
|
|
|
|
|
|
hash_update_str2(key1->s, key1->s+key1->len, p, v, h);
|
|
|
hash_update_str2(key2->s, key2->s+key2->len, p, v, h);
|
|
|
+ return hash_finish2(h);
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+/* "raw" 2 strings case insensitive hash (like get_hash2_raw but case
|
|
|
+ * insensitive)
|
|
|
+ * returns an unsigned int (which you can use modulo table_size as hash value)
|
|
|
+ */
|
|
|
+inline static unsigned int get_hash2_case_raw(str* key1, str* key2)
|
|
|
+{
|
|
|
+ char* p;
|
|
|
+ register unsigned v;
|
|
|
+ register unsigned h;
|
|
|
+
|
|
|
+ h=0;
|
|
|
+
|
|
|
+ hash_update_case_str(key1->s, key1->s+key1->len, p, v, h);
|
|
|
+ hash_update_case_str(key2->s, key2->s+key2->len, p, v, h);
|
|
|
return hash_finish(h);
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
+/* "raw" 1 string case insensitive hash
|
|
|
+ * returns an unsigned int (which you can use modulo table_size as hash value)
|
|
|
+ */
|
|
|
+inline static unsigned int get_hash1_case_raw(char* s, int len)
|
|
|
+{
|
|
|
+ char* p;
|
|
|
+ register unsigned v;
|
|
|
+ register unsigned h;
|
|
|
+
|
|
|
+ h=0;
|
|
|
+
|
|
|
+ hash_update_case_str(s, s+len, p, v, h);
|
|
|
+ return hash_finish(h);
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+/* same as get_hash1_raw2, but case insensitive and slower
|
|
|
+ * returns an unsigned int (which you can use modulo table_size as hash value)
|
|
|
+ */
|
|
|
+inline static unsigned int get_hash1_case_raw2(char* s, int len)
|
|
|
+{
|
|
|
+ char* p;
|
|
|
+ register unsigned v;
|
|
|
+ register unsigned h;
|
|
|
+
|
|
|
+ h=0;
|
|
|
+
|
|
|
+ hash_update_case_str2(s, s+len, p, v, h);
|
|
|
+ return hash_finish2(h);
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+/* "raw" 2 strings hash optimized for numeric strings (see above)
|
|
|
+ * same as get_hash2_raw2 but case insensitive and slower
|
|
|
+ * returns an unsigned int (which you can use modulo table_size as hash value)
|
|
|
+ */
|
|
|
+inline static unsigned int get_hash2_case_raw2(str* key1, str* key2)
|
|
|
+{
|
|
|
+ char* p;
|
|
|
+ register unsigned v;
|
|
|
+ register unsigned h;
|
|
|
+
|
|
|
+ h=0;
|
|
|
+
|
|
|
+ hash_update_case_str2(key1->s, key1->s+key1->len, p, v, h);
|
|
|
+ hash_update_case_str2(key2->s, key2->s+key2->len, p, v, h);
|
|
|
+ return hash_finish2(h);
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
#endif
|