hash_func.c
上传用户:tsgydb
上传日期:2007-04-14
资源大小:10674k
文件大小:5k
源码类别:

MySQL数据库

开发平台:

Visual C++

  1. /*-
  2.  * See the file LICENSE for redistribution information.
  3.  *
  4.  * Copyright (c) 1996, 1997, 1998, 1999, 2000
  5.  * Sleepycat Software.  All rights reserved.
  6.  */
  7. /*
  8.  * Copyright (c) 1990, 1993
  9.  * Margo Seltzer.  All rights reserved.
  10.  */
  11. /*
  12.  * Copyright (c) 1990, 1993
  13.  * The Regents of the University of California.  All rights reserved.
  14.  *
  15.  * This code is derived from software contributed to Berkeley by
  16.  * Margo Seltzer.
  17.  *
  18.  * Redistribution and use in source and binary forms, with or without
  19.  * modification, are permitted provided that the following conditions
  20.  * are met:
  21.  * 1. Redistributions of source code must retain the above copyright
  22.  *    notice, this list of conditions and the following disclaimer.
  23.  * 2. Redistributions in binary form must reproduce the above copyright
  24.  *    notice, this list of conditions and the following disclaimer in the
  25.  *    documentation and/or other materials provided with the distribution.
  26.  * 3. Neither the name of the University nor the names of its contributors
  27.  *    may be used to endorse or promote products derived from this software
  28.  *    without specific prior written permission.
  29.  *
  30.  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  31.  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  32.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  33.  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  34.  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  35.  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  36.  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  37.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  38.  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  39.  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  40.  * SUCH DAMAGE.
  41.  */
  42. #include "db_config.h"
  43. #ifndef lint
  44. static const char revid[] = "$Id: hash_func.c,v 11.7 2000/08/16 18:26:19 ubell Exp $";
  45. #endif /* not lint */
  46. #ifndef NO_SYSTEM_INCLUDES
  47. #include <sys/types.h>
  48. #endif
  49. #include "db_int.h"
  50. #include "db_page.h"
  51. #include "hash.h"
  52. /*
  53.  * __ham_func2 --
  54.  * Phong Vo's linear congruential hash.
  55.  *
  56.  * PUBLIC: u_int32_t __ham_func2 __P((DB *, const void *, u_int32_t));
  57.  */
  58. #define DCHARHASH(h, c) ((h) = 0x63c63cd9*(h) + 0x9c39c33d + (c))
  59. u_int32_t
  60. __ham_func2(dbp, key, len)
  61. DB *dbp;
  62. const void *key;
  63. u_int32_t len;
  64. {
  65. const u_int8_t *e, *k;
  66. u_int32_t h;
  67. u_int8_t c;
  68. if (dbp != NULL)
  69. COMPQUIET(dbp, NULL);
  70. k = key;
  71. e = k + len;
  72. for (h = 0; k != e;) {
  73. c = *k++;
  74. if (!c && k > e)
  75. break;
  76. DCHARHASH(h, c);
  77. }
  78. return (h);
  79. }
  80. /*
  81.  * __ham_func3 --
  82.  * Ozan Yigit's original sdbm hash.
  83.  *
  84.  * Ugly, but fast.  Break the string up into 8 byte units.  On the first time
  85.  * through the loop get the "leftover bytes" (strlen % 8).  On every other
  86.  * iteration, perform 8 HASHC's so we handle all 8 bytes.  Essentially, this
  87.  * saves us 7 cmp & branch instructions.
  88.  *
  89.  * PUBLIC: u_int32_t __ham_func3 __P((DB *, const void *, u_int32_t));
  90.  */
  91. u_int32_t
  92. __ham_func3(dbp, key, len)
  93. DB *dbp;
  94. const void *key;
  95. u_int32_t len;
  96. {
  97. const u_int8_t *k;
  98. u_int32_t n, loop;
  99. if (dbp != NULL)
  100. COMPQUIET(dbp, NULL);
  101. if (len == 0)
  102. return (0);
  103. #define HASHC n = *k++ + 65599 * n
  104. n = 0;
  105. k = key;
  106. loop = (len + 8 - 1) >> 3;
  107. switch (len & (8 - 1)) {
  108. case 0:
  109. do {
  110. HASHC;
  111. case 7:
  112. HASHC;
  113. case 6:
  114. HASHC;
  115. case 5:
  116. HASHC;
  117. case 4:
  118. HASHC;
  119. case 3:
  120. HASHC;
  121. case 2:
  122. HASHC;
  123. case 1:
  124. HASHC;
  125. } while (--loop);
  126. }
  127. return (n);
  128. }
  129. /*
  130.  * __ham_func4 --
  131.  * Chris Torek's hash function.  Although this function performs only
  132.  * slightly worse than __ham_func5 on strings, it performs horribly on
  133.  * numbers.
  134.  *
  135.  * PUBLIC: u_int32_t __ham_func4 __P((DB *, const void *, u_int32_t));
  136.  */
  137. u_int32_t
  138. __ham_func4(dbp, key, len)
  139. DB *dbp;
  140. const void *key;
  141. u_int32_t len;
  142. {
  143. const u_int8_t *k;
  144. u_int32_t h, loop;
  145. if (dbp != NULL)
  146. COMPQUIET(dbp, NULL);
  147. if (len == 0)
  148. return (0);
  149. #define HASH4a h = (h << 5) - h + *k++;
  150. #define HASH4b h = (h << 5) + h + *k++;
  151. #define HASH4 HASH4b
  152. h = 0;
  153. k = key;
  154. loop = (len + 8 - 1) >> 3;
  155. switch (len & (8 - 1)) {
  156. case 0:
  157. do {
  158. HASH4;
  159. case 7:
  160. HASH4;
  161. case 6:
  162. HASH4;
  163. case 5:
  164. HASH4;
  165. case 4:
  166. HASH4;
  167. case 3:
  168. HASH4;
  169. case 2:
  170. HASH4;
  171. case 1:
  172. HASH4;
  173. } while (--loop);
  174. }
  175. return (h);
  176. }
  177. /*
  178.  * Fowler/Noll/Vo hash
  179.  *
  180.  * The basis of the hash algorithm was taken from an idea sent by email to the
  181.  * IEEE Posix P1003.2 mailing list from Phong Vo (kpv@research.att.com) and
  182.  * Glenn Fowler (gsf@research.att.com).  Landon Curt Noll (chongo@toad.com)
  183.  * later improved on their algorithm.
  184.  *
  185.  * The magic is in the interesting relationship between the special prime
  186.  * 16777619 (2^24 + 403) and 2^32 and 2^8.
  187.  *
  188.  * This hash produces the fewest collisions of any function that we've seen so
  189.  * far, and works well on both numbers and strings.
  190.  *
  191.  * PUBLIC: u_int32_t __ham_func5 __P((DB *, const void *, u_int32_t));
  192.  */
  193. u_int32_t
  194. __ham_func5(dbp, key, len)
  195. DB *dbp;
  196. const void *key;
  197. u_int32_t len;
  198. {
  199. const u_int8_t *k, *e;
  200. u_int32_t h;
  201. if (dbp != NULL)
  202. COMPQUIET(dbp, NULL);
  203. k = key;
  204. e = k + len;
  205. for (h = 0; k < e; ++k) {
  206. h *= 16777619;
  207. h ^= *k;
  208. }
  209. return (h);
  210. }
  211. u_int32_t
  212. __ham_test(dbp, key, len)
  213. DB *dbp;
  214. const void *key;
  215. u_int32_t len;
  216. {
  217. COMPQUIET(dbp, NULL);
  218. COMPQUIET(len, 0);
  219. return ((u_int32_t)*(char *)key);
  220. }