hashes.h 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255
  1. /*
  2. * $Id$
  3. *
  4. * Copyright (C) 2006 iptelorg GmbH
  5. *
  6. * Permission to use, copy, modify, and distribute this software for any
  7. * purpose with or without fee is hereby granted, provided that the above
  8. * copyright notice and this permission notice appear in all copies.
  9. *
  10. * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
  11. * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
  12. * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
  13. * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  14. * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
  15. * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
  16. * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  17. */
  18. /*
  19. * History:
  20. * --------
  21. * 2006-02-02 created by andrei
  22. * 2006-11-24 added numeric string optimized hash function (andrei)
  23. * 2006-12-13 split into hashes.h (more generic) and str_hash.h (andrei)
  24. * 2007-02-22 added case insensitive versions (andrei)
  25. */
  26. #ifndef _hashes_h
  27. #define _hashes_h
  28. #include "str.h"
  29. /* internal use: hash update
  30. * params: char* s - string start,
  31. * char* end - end
  32. * char* p, and unsigned v temporary vars (used)
  33. * unsigned h - result
  34. * h should be initialized (e.g. set it to 0), the result in h */
  35. #define hash_update_str(s, end, p, v, h) \
  36. do{ \
  37. for ((p)=(s); (p)<=((end)-4); (p)+=4){ \
  38. (v)=(*(p)<<24)+((p)[1]<<16)+((p)[2]<<8)+(p)[3]; \
  39. (h)+=(v)^((v)>>3); \
  40. } \
  41. switch((end)-(p)){\
  42. case 3: \
  43. (v)=(*(p)<<16)+((p)[1]<<8)+(p)[2]; break; \
  44. case 2: \
  45. (v)=(*(p)<<8)+p[1]; break; \
  46. case 1: \
  47. (v)=*p; break; \
  48. default: \
  49. (v)=0; break; \
  50. } \
  51. (h)+=(v)^((v)>>3); \
  52. }while(0)
  53. /* like hash_update_str, but case insensitive
  54. * params: char* s - string start,
  55. * char* end - end
  56. * char* p, and unsigned v temporary vars (used)
  57. * unsigned h - result
  58. * h should be initialized (e.g. set it to 0), the result in h */
  59. #define hash_update_case_str(s, end, p, v, h) \
  60. do{ \
  61. for ((p)=(s); (p)<=((end)-4); (p)+=4){ \
  62. (v)=((*(p)<<24)+((p)[1]<<16)+((p)[2]<<8)+(p)[3])|0x20202020; \
  63. (h)+=(v)^((v)>>3); \
  64. } \
  65. (v)=0; \
  66. for (;(p)<(end); (p)++){ (v)<<=8; (v)+=*(p)|0x20;} \
  67. (h)+=(v)^((v)>>3); \
  68. }while(0)
  69. /* internal use: call it to adjust the h from hash_update_str */
  70. #define hash_finish(h) (((h)+((h)>>11))+(((h)>>13)+((h)>>23)))
  71. /* "raw" 2 strings hash
  72. * returns an unsigned int (which you can use modulo table_size as hash value)
  73. */
  74. inline static unsigned int get_hash2_raw(const str* key1, const str* key2)
  75. {
  76. char* p;
  77. register unsigned v;
  78. register unsigned h;
  79. h=0;
  80. hash_update_str(key1->s, key1->s+key1->len, p, v, h);
  81. hash_update_str(key2->s, key2->s+key2->len, p, v, h);
  82. return hash_finish(h);
  83. }
  84. /* "raw" 1 string hash
  85. * returns an unsigned int (which you can use modulo table_size as hash value)
  86. */
  87. inline static unsigned int get_hash1_raw(const char* s, int len)
  88. {
  89. const char* p;
  90. register unsigned v;
  91. register unsigned h;
  92. h=0;
  93. hash_update_str(s, s+len, p, v, h);
  94. return hash_finish(h);
  95. }
  96. /* a little slower than hash_* , but better distribution for
  97. * numbers and about the same for strings */
  98. #define hash_update_str2(s, end, p, v, h) \
  99. do{ \
  100. for ((p)=(s); (p)<=((end)-4); (p)+=4){ \
  101. (v)=(*(p)*16777213)+((p)[1]*65537)+((p)[2]*257)+(p)[3]; \
  102. (h)=16777259*(h)+((v)^((v)<<17)); \
  103. } \
  104. (v)=0; \
  105. for (;(p)<(end); (p)++){ (v)*=251; (v)+=*(p);} \
  106. (h)=16777259*(h)+((v)^((v)<<17)); \
  107. }while(0)
  108. /* like hash_update_str2 but case insensitive */
  109. #define hash_update_case_str2(s, end, p, v, h) \
  110. do{ \
  111. for ((p)=(s); (p)<=((end)-4); (p)+=4){ \
  112. (v)=((*(p)|0x20)*16777213)+(((p)[1]|0x20)*65537)+\
  113. (((p)[2]|0x20)*257)+((p)[3]|0x20); \
  114. (h)=16777259*(h)+((v)^((v)<<17)); \
  115. } \
  116. (v)=0; \
  117. for (;(p)<(end); (p)++){ (v)*=251; (v)+=*(p)|0x20;} \
  118. (h)=16777259*(h)+((v)^((v)<<17)); \
  119. }while(0)
  120. /* internal use: call it to adjust the h from hash_update_str */
  121. #define hash_finish2(h) (((h)+((h)>>7))+(((h)>>13)+((h)>>23)))
  122. /* a little slower than get_hash1_raw() , but better distribution for
  123. * numbers and about the same for strings */
  124. inline static unsigned int get_hash1_raw2(const char* s, int len)
  125. {
  126. const char* p;
  127. register unsigned v;
  128. register unsigned h;
  129. h=0;
  130. hash_update_str2(s, s+len, p, v, h);
  131. return hash_finish2(h);
  132. }
  133. /* "raw" 2 strings hash optimized for numeric strings (see above)
  134. * returns an unsigned int (which you can use modulo table_size as hash value)
  135. */
  136. inline static unsigned int get_hash2_raw2(const str* key1, const str* key2)
  137. {
  138. char* p;
  139. register unsigned v;
  140. register unsigned h;
  141. h=0;
  142. hash_update_str2(key1->s, key1->s+key1->len, p, v, h);
  143. hash_update_str2(key2->s, key2->s+key2->len, p, v, h);
  144. return hash_finish2(h);
  145. }
  146. /* "raw" 2 strings case insensitive hash (like get_hash2_raw but case
  147. * insensitive)
  148. * returns an unsigned int (which you can use modulo table_size as hash value)
  149. */
  150. inline static unsigned int get_hash2_case_raw(const str* key1, const str* key2)
  151. {
  152. char* p;
  153. register unsigned v;
  154. register unsigned h;
  155. h=0;
  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);
  158. return hash_finish(h);
  159. }
  160. /* "raw" 1 string case insensitive hash
  161. * returns an unsigned int (which you can use modulo table_size as hash value)
  162. */
  163. inline static unsigned int get_hash1_case_raw(const char* s, int len)
  164. {
  165. const char* p;
  166. register unsigned v;
  167. register unsigned h;
  168. h=0;
  169. hash_update_case_str(s, s+len, p, v, h);
  170. return hash_finish(h);
  171. }
  172. /* same as get_hash1_raw2, but case insensitive and slower
  173. * returns an unsigned int (which you can use modulo table_size as hash value)
  174. */
  175. inline static unsigned int get_hash1_case_raw2(const char* s, int len)
  176. {
  177. const char* p;
  178. register unsigned v;
  179. register unsigned h;
  180. h=0;
  181. hash_update_case_str2(s, s+len, p, v, h);
  182. return hash_finish2(h);
  183. }
  184. /* "raw" 2 strings hash optimized for numeric strings (see above)
  185. * same as get_hash2_raw2 but case insensitive and slower
  186. * returns an unsigned int (which you can use modulo table_size as hash value)
  187. */
  188. inline static unsigned int get_hash2_case_raw2(const str* key1,
  189. const str* key2)
  190. {
  191. char* p;
  192. register unsigned v;
  193. register unsigned h;
  194. h=0;
  195. hash_update_case_str2(key1->s, key1->s+key1->len, p, v, h);
  196. hash_update_case_str2(key2->s, key2->s+key2->len, p, v, h);
  197. return hash_finish2(h);
  198. }
  199. #endif