hash_func.c 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225
  1. /*-
  2. * Copyright (c) 1990, 1993
  3. * The Regents of the University of California. All rights reserved.
  4. *
  5. * This code is derived from software contributed to Berkeley by
  6. * Margo Seltzer.
  7. *
  8. * Redistribution and use in source and binary forms, with or without
  9. * modification, are permitted provided that the following conditions
  10. * are met:
  11. * 1. Redistributions of source code must retain the above copyright
  12. * notice, this list of conditions and the following disclaimer.
  13. * 2. Redistributions in binary form must reproduce the above copyright
  14. * notice, this list of conditions and the following disclaimer in the
  15. * documentation and/or other materials provided with the distribution.
  16. * 3. All advertising materials mentioning features or use of this software
  17. * must display the following acknowledgement:
  18. * This product includes software developed by the University of
  19. * California, Berkeley and its contributors.
  20. * 4. Neither the name of the University nor the names of its contributors
  21. * may be used to endorse or promote products derived from this software
  22. * without specific prior written permission.
  23. *
  24. * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  25. * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  26. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  27. * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  28. * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  29. * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  30. * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  31. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  32. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  33. * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  34. * SUCH DAMAGE.
  35. */
  36. #if defined(LIBC_SCCS) && !defined(lint)
  37. static char sccsid[] = "@(#)hash_func.c 8.2 (Berkeley) 2/21/94";
  38. #endif /* LIBC_SCCS and not lint */
  39. #include <sys/types.h>
  40. #include "../include/db.h"
  41. #include "hash.h"
  42. #include "page.h"
  43. #include "extern.h"
  44. /* only one of these can be defined */
  45. /* #define HASH1_EJB 1 */
  46. /* #define HASH2_PHONG 1 */
  47. /* #define HASH3_SDBM 1 */
  48. #define HASH4_TOREK 1
  49. static u_int32_t hashfunc __P((const void *, size_t));
  50. /* Global default hash function */
  51. u_int32_t (*__default_hash) __P((const void *, size_t)) = hashfunc;
  52. /*
  53. * HASH FUNCTIONS
  54. *
  55. * Assume that we've already split the bucket to which this key hashes,
  56. * calculate that bucket, and check that in fact we did already split it.
  57. *
  58. * This came from ejb's hsearch.
  59. */
  60. #ifdef HASH1_EJB
  61. #define PRIME1 37
  62. #define PRIME2 1048583
  63. static u_int32_t
  64. hashfunc(keyarg, len)
  65. const void *keyarg;
  66. register size_t len;
  67. {
  68. register const u_char *key;
  69. register u_int32_t h;
  70. /* Convert string to integer */
  71. for (key = keyarg, h = 0; len--;)
  72. h = h * PRIME1 ^ (*key++ - ' ');
  73. h %= PRIME2;
  74. return (h);
  75. }
  76. #endif
  77. #ifdef HASH2_PHONG
  78. /*
  79. * Phong's linear congruential hash
  80. */
  81. #define dcharhash(h, c) ((h) = 0x63c63cd9*(h) + 0x9c39c33d + (c))
  82. static u_int32_t
  83. hashfunc(keyarg, len)
  84. const void *keyarg;
  85. size_t len;
  86. {
  87. register const u_char *e, *key;
  88. register u_int32_t h;
  89. register u_char c;
  90. key = keyarg;
  91. e = key + len;
  92. for (h = 0; key != e;) {
  93. c = *key++;
  94. if (!c && key > e)
  95. break;
  96. dcharhash(h, c);
  97. }
  98. return (h);
  99. }
  100. #endif
  101. #ifdef HASH3_SDBM
  102. /*
  103. * This is INCREDIBLY ugly, but fast. We break the string up into 8 byte
  104. * units. On the first time through the loop we get the "leftover bytes"
  105. * (strlen % 8). On every other iteration, we perform 8 HASHC's so we handle
  106. * all 8 bytes. Essentially, this saves us 7 cmp & branch instructions. If
  107. * this routine is heavily used enough, it's worth the ugly coding.
  108. *
  109. * OZ's original sdbm hash
  110. */
  111. static u_int32_t
  112. hashfunc(keyarg, len)
  113. const void *keyarg;
  114. register size_t len;
  115. {
  116. register const u_char *key;
  117. register size_t loop;
  118. register u_int32_t h;
  119. #define HASHC h = *key++ + 65599 * h
  120. h = 0;
  121. key = keyarg;
  122. if (len > 0) {
  123. loop = (len + 8 - 1) >> 3;
  124. switch (len & (8 - 1)) {
  125. case 0:
  126. do {
  127. HASHC;
  128. /* FALLTHROUGH */
  129. case 7:
  130. HASHC;
  131. /* FALLTHROUGH */
  132. case 6:
  133. HASHC;
  134. /* FALLTHROUGH */
  135. case 5:
  136. HASHC;
  137. /* FALLTHROUGH */
  138. case 4:
  139. HASHC;
  140. /* FALLTHROUGH */
  141. case 3:
  142. HASHC;
  143. /* FALLTHROUGH */
  144. case 2:
  145. HASHC;
  146. /* FALLTHROUGH */
  147. case 1:
  148. HASHC;
  149. } while (--loop);
  150. }
  151. }
  152. return (h);
  153. }
  154. #endif
  155. #ifdef HASH4_TOREK
  156. /* Hash function from Chris Torek. */
  157. static u_int32_t
  158. hashfunc(keyarg, len)
  159. const void *keyarg;
  160. register size_t len;
  161. {
  162. register const u_char *key;
  163. register size_t loop;
  164. register u_int32_t h;
  165. #define HASH4a h = (h << 5) - h + *key++;
  166. #define HASH4b h = (h << 5) + h + *key++;
  167. #define HASH4 HASH4b
  168. h = 0;
  169. key = keyarg;
  170. if (len > 0) {
  171. loop = (len + 8 - 1) >> 3;
  172. switch (len & (8 - 1)) {
  173. case 0:
  174. do {
  175. HASH4;
  176. /* FALLTHROUGH */
  177. case 7:
  178. HASH4;
  179. /* FALLTHROUGH */
  180. case 6:
  181. HASH4;
  182. /* FALLTHROUGH */
  183. case 5:
  184. HASH4;
  185. /* FALLTHROUGH */
  186. case 4:
  187. HASH4;
  188. /* FALLTHROUGH */
  189. case 3:
  190. HASH4;
  191. /* FALLTHROUGH */
  192. case 2:
  193. HASH4;
  194. /* FALLTHROUGH */
  195. case 1:
  196. HASH4;
  197. } while (--loop);
  198. }
  199. }
  200. return (h);
  201. }
  202. #endif