hash_func.c 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184
  1. /*
  2. * $Id$
  3. *
  4. * Copyright (C) 2001-2003 Fhg Fokus
  5. *
  6. * This file is part of ser, a free SIP server.
  7. *
  8. * ser is free software; you can redistribute it and/or modify
  9. * it under the terms of the GNU General Public License as published by
  10. * the Free Software Foundation; either version 2 of the License, or
  11. * (at your option) any later version
  12. *
  13. * For a license to use the ser software under conditions
  14. * other than those described here, or to purchase support for this
  15. * software, please contact iptel.org by e-mail at the following addresses:
  16. * [email protected]
  17. *
  18. * ser is distributed in the hope that it will be useful,
  19. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  20. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  21. * GNU General Public License for more details.
  22. *
  23. * You should have received a copy of the GNU General Public License
  24. * along with this program; if not, write to the Free Software
  25. * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  26. */
  27. #ifndef _CRC_H_
  28. #define _CRC_H_
  29. extern unsigned long int crc_32_tab[];
  30. extern unsigned short int ccitt_tab[];
  31. extern unsigned short int crc_16_tab[];
  32. #endif
  33. #include <stdio.h>
  34. #include <string.h>
  35. #include <stdlib.h>
  36. #include "hash_func.h"
  37. #include "dprint.h"
  38. #include "crc.h"
  39. #include "ut.h"
  40. int new_hash( str call_id, str cseq_nr )
  41. {
  42. int hash_code = 0;
  43. int i,j, k, third;
  44. int ci_len, cs_len;
  45. char *ci, *cs;
  46. /* trim EoLs */
  47. /*
  48. ci_len = call_id.len;
  49. while (ci_len && ((c=call_id.s[ci_len-1])==0 || c=='\r' || c=='\n'))
  50. ci_len--;
  51. cs_len = cseq_nr.len;
  52. while (cs_len && ((c=cseq_nr.s[cs_len-1])==0 || c=='\r' || c=='\n'))
  53. cs_len--;
  54. */
  55. trim_len( ci_len, ci, call_id );
  56. trim_len( cs_len, cs, cseq_nr );
  57. /* run the cycle from the end ... we are interested in the
  58. most-right digits ... and just take the %10 value of it
  59. */
  60. third=(ci_len-1)/3;
  61. for ( i=ci_len-1, j=2*third, k=third;
  62. k>0 ; i--, j--, k-- ) {
  63. hash_code+=crc_16_tab[(unsigned char)(*(ci+i)) /*+7*/ ]+
  64. ccitt_tab[*(ci+k)+63]+
  65. ccitt_tab[*(ci+j)+13];
  66. }
  67. for( i=0 ; i<cs_len ; i++ )
  68. //hash_code+=crc_32_tab[(cseq_nr.s[i]+hash_code)%243];
  69. hash_code+=ccitt_tab[*(cs+i)+123];
  70. /* hash_code conditioning */
  71. #ifdef _BUG
  72. /* not flat ... % 111b has shorter period than
  73. & 111b by one and results in different distribution;
  74. ( 7 % 7 == 0, 7 %7 == 1 )
  75. % is used as a part of the hash function too, not only
  76. for rounding; & is not flat; whoever comes up with
  77. a nicer flat hash function which does not take
  78. costly division is welcome; feel free to verify
  79. distribution using hashtest()
  80. */
  81. hash_code &= (TABLE_ENTRIES-1); /* TABLE_ENTRIES = 2^k */
  82. #endif
  83. hash_code=hash_code%(TABLE_ENTRIES-1)+1;
  84. return hash_code;
  85. }
  86. int new_hash2( str call_id, str cseq_nr )
  87. {
  88. #define h_inc h+=v^(v>>3)
  89. char* p;
  90. register unsigned v;
  91. register unsigned h;
  92. h=0;
  93. for (p=call_id.s; p<=(call_id.s+call_id.len-4); p+=4){
  94. v=(*p<<24)+(p[1]<<16)+(p[2]<<8)+p[3];
  95. h_inc;
  96. }
  97. v=0;
  98. for (;p<(call_id.s+call_id.len); p++){ v<<=8; v+=*p;}
  99. h_inc;
  100. for (p=cseq_nr.s; p<=(cseq_nr.s+cseq_nr.len-4); p+=4){
  101. v=(*p<<24)+(p[1]<<16)+(p[2]<<8)+p[3];
  102. h_inc;
  103. }
  104. v=0;
  105. for (;p<(cseq_nr.s+cseq_nr.len); p++){ v<<=8; v+=*p;}
  106. h_inc;
  107. h=((h)+(h>>11))+((h>>13)+(h>>23));
  108. return (h)&(TABLE_ENTRIES-1);
  109. }
  110. void hashtest_cycle( int hits[TABLE_ENTRIES+5], char *ip )
  111. {
  112. long int i,j,k, l;
  113. int hashv;
  114. static char buf1[1024];
  115. static char buf2[1024];
  116. str call_id;
  117. str cseq;
  118. call_id.s=buf1;
  119. cseq.s=buf2;
  120. for (i=987654328;i<987654328+10;i++)
  121. for (j=85296341;j<85296341+10;j++)
  122. for (k=987654;k<=987654+10;k++)
  123. for (l=101;l<201;l++) {
  124. call_id.len=sprintf( buf1, "%d-%d-%d@%s",(int)i,(int)j,
  125. (int)k, ip );
  126. cseq.len=sprintf( buf2, "%d", (int)l );
  127. /* printf("%s\t%s\n", buf1, buf2 ); */
  128. hashv=hash( call_id, cseq );
  129. hits[ hashv ]++;
  130. }
  131. }
  132. int init_hash()
  133. {
  134. if (TABLE_ENTRIES != (1<<10)) {
  135. LOG(L_WARN, "WARNING: hash function optimized for %d entries\n",
  136. 1<<10);
  137. LOG(L_WARN, "WARNING: use of %d entries may lead "
  138. "to unflat distribution\n", TABLE_ENTRIES );
  139. } else {
  140. DBG("DEBUG: hash function initialized with optimum table size\n");
  141. }
  142. return 1;
  143. }
  144. void hashtest()
  145. {
  146. int hits[TABLE_ENTRIES+5];
  147. int i;
  148. init_hash();
  149. memset( hits, 0, sizeof hits );
  150. hashtest_cycle( hits, "192.168.99.100" );
  151. hashtest_cycle( hits, "172.168.99.100" );
  152. hashtest_cycle( hits, "142.168.99.100" );
  153. for (i=0; i<TABLE_ENTRIES+5; i++)
  154. printf("[%d. %d]\n", i, hits[i] );
  155. exit(0);
  156. }