浏览代码

- 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 18 年之前
父节点
当前提交
57ff54fee8
共有 2 个文件被更改,包括 106 次插入23 次删除
  1. 4 23
      dns_cache.c
  2. 102 0
      hashes.h

+ 4 - 23
dns_cache.c

@@ -299,31 +299,12 @@ error:
 }
 
 
-/* hash function, based on get_hash1_raw, but case insensitive
- * type is not used (obsolete)
+/* hash function, type is not used (obsolete)
+ * params: char* s, int len, int type
  * returns the hash value
  */
-inline static unsigned int dns_hash_no(char* s, int len, int type)
-{
-	char* p;
-	char* end;
-	
-	register unsigned v;
-	register unsigned h;
-	
-	h=0;
-	
-	hash_update_str(s, s+len, p, v, h);
-	end=s+len;
-	for (p=s; p<=(end-4); p+=4){
-		v=((p[0]<<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);
-	return hash_finish(h) % DNS_HASH_SIZE;
-}
+#define dns_hash_no(s, len, type) \
+	(get_hash1_case_raw((s),(len)) % DNS_HASH_SIZE)
 
 
 

+ 102 - 0
hashes.h

@@ -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