security/nss/lib/dbm/src/h_func.c

Thu, 22 Jan 2015 13:21:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 22 Jan 2015 13:21:57 +0100
branch
TOR_BUG_9701
changeset 15
b8a032363ba2
permissions
-rw-r--r--

Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6

     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. ***REMOVED*** - see 
    17  *    ftp://ftp.cs.berkeley.edu/pub/4bsd/README.Impt.License.Change
    18  * 4. Neither the name of the University nor the names of its contributors
    19  *    may be used to endorse or promote products derived from this software
    20  *    without specific prior written permission.
    21  *
    22  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
    23  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
    24  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
    25  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
    26  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
    27  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
    28  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
    29  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
    30  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
    31  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
    32  * SUCH DAMAGE.
    33  */
    35 #if defined(LIBC_SCCS) && !defined(lint)
    36 static char sccsid[] = "@(#)hash_func.c	8.2 (Berkeley) 2/21/94";
    37 #endif /* LIBC_SCCS and not lint */
    39 #ifndef macintosh
    40 #include <sys/types.h>
    41 #endif
    42 #include "mcom_db.h"
    43 #include "hash.h"
    44 #include "page.h"
    45 /* #include "extern.h" */
    47 #if 0
    48 static uint32 hash1 __P((const void *, size_t));
    49 static uint32 hash2 __P((const void *, size_t));
    50 static uint32 hash3 __P((const void *, size_t));
    51 #endif
    52 static uint32 hash4 __P((const void *, size_t));
    54 /* Global default hash function */
    55 uint32 (*__default_hash) __P((const void *, size_t)) = hash4;
    57 /*
    58  * HASH FUNCTIONS
    59  *
    60  * Assume that we've already split the bucket to which this key hashes,
    61  * calculate that bucket, and check that in fact we did already split it.
    62  *
    63  * This came from ejb's hsearch.
    64  */
    66 #define PRIME1		37
    67 #define PRIME2		1048583
    69 #if 0
    70 static uint32
    71 hash1(const void *keyarg, register size_t len)
    72 {
    73 	register const uint8 *key;
    74 	register uint32 h;
    76 	/* Convert string to integer */
    77 	for (key = (const uint8 *)keyarg, h = 0; len--;)
    78 		h = h * PRIME1 ^ (*key++ - ' ');
    79 	h %= PRIME2;
    80 	return (h);
    81 }
    83 /*
    84  * Phong's linear congruential hash
    85  */
    86 #define dcharhash(h, c)	((h) = 0x63c63cd9*(h) + 0x9c39c33d + (c))
    88 static uint32
    89 hash2(const void *keyarg, size_t len)
    90 {
    91 	register const uint8 *e, *key;
    92 	register uint32 h;
    93 	register uint8 c;
    95 	key = (const uint8 *)keyarg;
    96 	e = key + len;
    97 	for (h = 0; key != e;) {
    98 		c = *key++;
    99 		if (!c && key > e)
   100 			break;
   101 		dcharhash(h, c);
   102 	}
   103 	return (h);
   104 }
   106 /*
   107  * This is INCREDIBLY ugly, but fast.  We break the string up into 8 byte
   108  * units.  On the first time through the loop we get the "leftover bytes"
   109  * (strlen % 8).  On every other iteration, we perform 8 HASHC's so we handle
   110  * all 8 bytes.  Essentially, this saves us 7 cmp & branch instructions.  If
   111  * this routine is heavily used enough, it's worth the ugly coding.
   112  *
   113  * OZ's original sdbm hash
   114  */
   115 static uint32
   116 hash3(const void *keyarg, register size_t len)
   117 {
   118 	register const uint8 *key;
   119 	register size_t loop;
   120 	register uint32 h;
   122 #define HASHC   h = *key++ + 65599 * h
   124 	h = 0;
   125 	key = (const uint8 *)keyarg;
   126 	if (len > 0) {
   127 		loop = (len + 8 - 1) >> 3;
   129 		switch (len & (8 - 1)) {
   130 		case 0:
   131 			do {
   132 				HASHC;
   133 				/* FALLTHROUGH */
   134 		case 7:
   135 				HASHC;
   136 				/* FALLTHROUGH */
   137 		case 6:
   138 				HASHC;
   139 				/* FALLTHROUGH */
   140 		case 5:
   141 				HASHC;
   142 				/* FALLTHROUGH */
   143 		case 4:
   144 				HASHC;
   145 				/* FALLTHROUGH */
   146 		case 3:
   147 				HASHC;
   148 				/* FALLTHROUGH */
   149 		case 2:
   150 				HASHC;
   151 				/* FALLTHROUGH */
   152 		case 1:
   153 				HASHC;
   154 			} while (--loop);
   155 		}
   156 	}
   157 	return (h);
   158 }
   159 #endif /* 0 */
   161 /* Hash function from Chris Torek. */
   162 static uint32
   163 hash4(const void *keyarg, register size_t len)
   164 {
   165 	register const uint8 *key;
   166 	register size_t loop;
   167 	register uint32 h;
   169 #define HASH4a   h = (h << 5) - h + *key++;
   170 #define HASH4b   h = (h << 5) + h + *key++;
   171 #define HASH4 HASH4b
   173 	h = 0;
   174 	key = (const uint8 *)keyarg;
   175 	if (len > 0) {
   176 		loop = (len + 8 - 1) >> 3;
   178 		switch (len & (8 - 1)) {
   179 		case 0:
   180 			do {
   181 				HASH4;
   182 				/* FALLTHROUGH */
   183 		case 7:
   184 				HASH4;
   185 				/* FALLTHROUGH */
   186 		case 6:
   187 				HASH4;
   188 				/* FALLTHROUGH */
   189 		case 5:
   190 				HASH4;
   191 				/* FALLTHROUGH */
   192 		case 4:
   193 				HASH4;
   194 				/* FALLTHROUGH */
   195 		case 3:
   196 				HASH4;
   197 				/* FALLTHROUGH */
   198 		case 2:
   199 				HASH4;
   200 				/* FALLTHROUGH */
   201 		case 1:
   202 				HASH4;
   203 			} while (--loop);
   204 		}
   205 	}
   206 	return (h);
   207 }

mercurial