tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

h_func.c (5923B)


      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 */
     34 
     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 */
     38 
     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" */
     46 
     47 #if 0
     48 static uint32 hash1(const void *, size_t);
     49 static uint32 hash2(const void *, size_t);
     50 static uint32 hash3(const void *, size_t);
     51 #endif
     52 static uint32 hash4(const void *, size_t);
     53 
     54 /* Global default hash function */
     55 uint32 (*dbm_default_hash)(const void *, size_t) = hash4;
     56 
     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 */
     65 
     66 #define PRIME1 37
     67 #define PRIME2 1048583
     68 
     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;
     75 
     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 }
     82 
     83 /*
     84 * Phong's linear congruential hash
     85 */
     86 #define dcharhash(h, c) ((h) = 0x63c63cd9 * (h) + 0x9c39c33d + (c))
     87 
     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;
     94 
     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 }
    105 
    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;
    121 
    122 #define HASHC h = *key++ + 65599 * h
    123 
    124    h = 0;
    125    key = (const uint8 *)keyarg;
    126    if (len > 0) {
    127        loop = (len + 8 - 1) >> 3;
    128 
    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 */
    160 
    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;
    168 
    169 #define HASH4a h = (h << 5) - h + *key++;
    170 #define HASH4b h = (h << 5) + h + *key++;
    171 #define HASH4 HASH4b
    172 
    173    h = 0;
    174    key = (const uint8 *)keyarg;
    175    if (len > 0) {
    176        loop = (len + 8 - 1) >> 3;
    177 
    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 }