hashes.h 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341
  1. /*
  2. * Copyright (C) 2006 iptelorg GmbH
  3. *
  4. * Permission to use, copy, modify, and distribute this software for any
  5. * purpose with or without fee is hereby granted, provided that the above
  6. * copyright notice and this permission notice appear in all copies.
  7. *
  8. * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
  9. * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
  10. * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
  11. * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  12. * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
  13. * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
  14. * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  15. */
  16. /*!
  17. * \file
  18. * \brief Kamailio core :: hash support
  19. * \author Andrei
  20. * \ingroup core
  21. * Module: \ref core
  22. */
  23. #ifndef _hashes_h
  24. #define _hashes_h
  25. #include "str.h"
  26. /** internal use: hash update
  27. * params: char* s - string start,
  28. * char* end - end
  29. * char* p, and unsigned v temporary vars (used)
  30. * unsigned h - result
  31. * h should be initialized (e.g. set it to 0), the result in h */
  32. #define hash_update_str(s, end, p, v, h) \
  33. do{ \
  34. for ((p)=(s); (p)<=((end)-4); (p)+=4){ \
  35. (v)=(*(p)<<24)+((p)[1]<<16)+((p)[2]<<8)+(p)[3]; \
  36. (h)+=(v)^((v)>>3); \
  37. } \
  38. switch((end)-(p)){\
  39. case 3: \
  40. (v)=(*(p)<<16)+((p)[1]<<8)+(p)[2]; break; \
  41. case 2: \
  42. (v)=(*(p)<<8)+p[1]; break; \
  43. case 1: \
  44. (v)=*p; break; \
  45. default: \
  46. (v)=0; break; \
  47. } \
  48. (h)+=(v)^((v)>>3); \
  49. }while(0)
  50. /** like hash_update_str, but case insensitive
  51. * params: char* s - string start,
  52. * char* end - end
  53. * char* p, and unsigned v temporary vars (used)
  54. * unsigned h - result
  55. * h should be initialized (e.g. set it to 0), the result in h */
  56. #define hash_update_case_str(s, end, p, v, h) \
  57. do{ \
  58. for ((p)=(s); (p)<=((end)-4); (p)+=4){ \
  59. (v)=((*(p)<<24)+((p)[1]<<16)+((p)[2]<<8)+(p)[3])|0x20202020; \
  60. (h)+=(v)^((v)>>3); \
  61. } \
  62. (v)=0; \
  63. for (;(p)<(end); (p)++){ (v)<<=8; (v)+=*(p)|0x20;} \
  64. (h)+=(v)^((v)>>3); \
  65. }while(0)
  66. /** internal use: call it to adjust the h from hash_update_str */
  67. #define hash_finish(h) (((h)+((h)>>11))+(((h)>>13)+((h)>>23)))
  68. /** "raw" 2 strings hash
  69. * returns an unsigned int (which you can use modulo table_size as hash value)
  70. */
  71. inline static unsigned int get_hash2_raw(const str* key1, const str* key2)
  72. {
  73. char* p;
  74. register unsigned v;
  75. register unsigned h;
  76. h=0;
  77. hash_update_str(key1->s, key1->s+key1->len, p, v, h);
  78. hash_update_str(key2->s, key2->s+key2->len, p, v, h);
  79. return hash_finish(h);
  80. }
  81. /** "raw" 1 string hash
  82. * returns an unsigned int (which you can use modulo table_size as hash value)
  83. */
  84. inline static unsigned int get_hash1_raw(const char* s, int len)
  85. {
  86. const char* p;
  87. register unsigned v;
  88. register unsigned h;
  89. h=0;
  90. hash_update_str(s, s+len, p, v, h);
  91. return hash_finish(h);
  92. }
  93. /** a little slower than hash_* , but better distribution for
  94. * numbers and about the same for strings */
  95. #define hash_update_str2(s, end, p, v, h) \
  96. do{ \
  97. for ((p)=(s); (p)<=((end)-4); (p)+=4){ \
  98. (v)=(*(p)*16777213)+((p)[1]*65537)+((p)[2]*257)+(p)[3]; \
  99. (h)=16777259*(h)+((v)^((v)<<17)); \
  100. } \
  101. (v)=0; \
  102. for (;(p)<(end); (p)++){ (v)*=251; (v)+=*(p);} \
  103. (h)=16777259*(h)+((v)^((v)<<17)); \
  104. }while(0)
  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. /** internal use: call it to adjust the h from hash_update_str */
  118. #define hash_finish2(h) (((h)+((h)>>7))+(((h)>>13)+((h)>>23)))
  119. /** a little slower than get_hash1_raw() , but better distribution for
  120. * numbers and about the same for strings */
  121. inline static unsigned int get_hash1_raw2(const char* s, int len)
  122. {
  123. const char* p;
  124. register unsigned v;
  125. register unsigned h;
  126. h=0;
  127. hash_update_str2(s, s+len, p, v, h);
  128. return hash_finish2(h);
  129. }
  130. /* "raw" 2 strings hash optimized for numeric strings (see above)
  131. * returns an unsigned int (which you can use modulo table_size as hash value)
  132. */
  133. inline static unsigned int get_hash2_raw2(const str* key1, const str* key2)
  134. {
  135. char* p;
  136. register unsigned v;
  137. register unsigned h;
  138. h=0;
  139. hash_update_str2(key1->s, key1->s+key1->len, p, v, h);
  140. hash_update_str2(key2->s, key2->s+key2->len, p, v, h);
  141. return hash_finish2(h);
  142. }
  143. /* "raw" 2 strings case insensitive hash (like get_hash2_raw but case
  144. * insensitive)
  145. * returns an unsigned int (which you can use modulo table_size as hash value)
  146. */
  147. inline static unsigned int get_hash2_case_raw(const str* key1, const str* key2)
  148. {
  149. char* p;
  150. register unsigned v;
  151. register unsigned h;
  152. h=0;
  153. hash_update_case_str(key1->s, key1->s+key1->len, p, v, h);
  154. hash_update_case_str(key2->s, key2->s+key2->len, p, v, h);
  155. return hash_finish(h);
  156. }
  157. /* "raw" 1 string case insensitive hash
  158. * returns an unsigned int (which you can use modulo table_size as hash value)
  159. */
  160. inline static unsigned int get_hash1_case_raw(const char* s, int len)
  161. {
  162. const char* p;
  163. register unsigned v;
  164. register unsigned h;
  165. h=0;
  166. hash_update_case_str(s, s+len, p, v, h);
  167. return hash_finish(h);
  168. }
  169. /* same as get_hash1_raw2, but case insensitive and slower
  170. * returns an unsigned int (which you can use modulo table_size as hash value)
  171. */
  172. inline static unsigned int get_hash1_case_raw2(const char* s, int len)
  173. {
  174. const char* p;
  175. register unsigned v;
  176. register unsigned h;
  177. h=0;
  178. hash_update_case_str2(s, s+len, p, v, h);
  179. return hash_finish2(h);
  180. }
  181. /* "raw" 2 strings hash optimized for numeric strings (see above)
  182. * same as get_hash2_raw2 but case insensitive and slower
  183. * returns an unsigned int (which you can use modulo table_size as hash value)
  184. */
  185. inline static unsigned int get_hash2_case_raw2(const str* key1,
  186. const str* key2)
  187. {
  188. char* p;
  189. register unsigned v;
  190. register unsigned h;
  191. h=0;
  192. hash_update_case_str2(key1->s, key1->s+key1->len, p, v, h);
  193. hash_update_case_str2(key2->s, key2->s+key2->len, p, v, h);
  194. return hash_finish2(h);
  195. }
  196. /*
  197. * generic hashing - from the intial origins of ser
  198. */
  199. #define ch_h_inc h+=v^(v>>3)
  200. #define ch_icase(_c) (((_c)>='A'&&(_c)<='Z')?((_c)|0x20):(_c))
  201. /*
  202. * case sensitive hashing
  203. * - s1 - str to hash
  204. * - s2 - optional - continue hashing over s2
  205. * - size - optional - size of hash table (must be power of 1); if set (!=0),
  206. * instead of hash id, returned value is slot index
  207. * return computed hash id or hash table slot index
  208. */
  209. static inline unsigned int core_hash(const str *s1, const str *s2,
  210. const unsigned int size)
  211. {
  212. char *p, *end;
  213. register unsigned v;
  214. register unsigned h;
  215. h=0;
  216. end=s1->s+s1->len;
  217. for ( p=s1->s ; p<=(end-4) ; p+=4 ){
  218. v=(*p<<24)+(p[1]<<16)+(p[2]<<8)+p[3];
  219. ch_h_inc;
  220. }
  221. v=0;
  222. for (; p<end ; p++){ v<<=8; v+=*p;}
  223. ch_h_inc;
  224. if (s2) {
  225. end=s2->s+s2->len;
  226. for (p=s2->s; p<=(end-4); p+=4){
  227. v=(*p<<24)+(p[1]<<16)+(p[2]<<8)+p[3];
  228. ch_h_inc;
  229. }
  230. v=0;
  231. for (; p<end ; p++){ v<<=8; v+=*p;}
  232. ch_h_inc;
  233. }
  234. h=((h)+(h>>11))+((h>>13)+(h>>23));
  235. return size?((h)&(size-1)):h;
  236. }
  237. /*
  238. * case insensitive hashing
  239. * - s1 - str to hash
  240. * - s2 - optional - continue hashing over s2
  241. * - size - optional - size of hash table (must be power of 1); if set (!=0),
  242. * instead of hash id, returned value is slot index
  243. * return computed hash id or hash table slot index
  244. */
  245. static inline unsigned int core_case_hash( str *s1, str *s2,
  246. unsigned int size)
  247. {
  248. char *p, *end;
  249. register unsigned v;
  250. register unsigned h;
  251. h=0;
  252. end=s1->s+s1->len;
  253. for ( p=s1->s ; p<=(end-4) ; p+=4 ){
  254. v=(ch_icase(*p)<<24)+(ch_icase(p[1])<<16)+(ch_icase(p[2])<<8)
  255. + ch_icase(p[3]);
  256. ch_h_inc;
  257. }
  258. v=0;
  259. for (; p<end ; p++){ v<<=8; v+=ch_icase(*p);}
  260. ch_h_inc;
  261. if (s2) {
  262. end=s2->s+s2->len;
  263. for (p=s2->s; p<=(end-4); p+=4){
  264. v=(ch_icase(*p)<<24)+(ch_icase(p[1])<<16)+(ch_icase(p[2])<<8)
  265. + ch_icase(p[3]);
  266. ch_h_inc;
  267. }
  268. v=0;
  269. for (; p<end ; p++){ v<<=8; v+=ch_icase(*p);}
  270. ch_h_inc;
  271. }
  272. h=((h)+(h>>11))+((h>>13)+(h>>23));
  273. return size?((h)&(size-1)):h;
  274. }
  275. #endif