Annotation of 43BSD/ucb/pascal/src/hash.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * Copyright (c) 1980 Regents of the University of California.
                      3:  * All rights reserved.  The Berkeley software License Agreement
                      4:  * specifies the terms and conditions for redistribution.
                      5:  */
                      6: 
                      7: #ifndef lint
                      8: static char sccsid[] = "@(#)hash.c     5.1 (Berkeley) 6/5/85";
                      9: #endif not lint
                     10: 
                     11: #include "whoami.h"
                     12: #include "0.h"
                     13: #include "tree_ty.h"           /* must be included for yy.h */
                     14: #include "yy.h"
                     15: 
                     16: /*
                     17:  * The definition for the segmented hash tables.
                     18:  */
                     19: struct ht {
                     20:        int     *ht_low;
                     21:        int     *ht_high;
                     22:        int     ht_used;
                     23: } htab[MAXHASH];
                     24: 
                     25: /*
                     26:  * This is the array of keywords and their
                     27:  * token values, which are hashed into the table
                     28:  * by inithash.
                     29:  */
                     30: struct kwtab yykey[] = {
                     31:        "and",          YAND,
                     32:        "array",        YARRAY,
                     33:        "begin",        YBEGIN,
                     34:        "case",         YCASE,
                     35:        "const",        YCONST,
                     36:        "div",          YDIV,
                     37:        "do",           YDO,
                     38:        "downto",       YDOWNTO,
                     39:        "else",         YELSE,
                     40:        "end",          YEND,
                     41:        "file",         YFILE,
                     42:        "for",          YFOR,
                     43:        "forward",      YFORWARD,
                     44:        "function",     YFUNCTION,
                     45:        "goto",         YGOTO,
                     46:        "if",           YIF,
                     47:        "in",           YIN,
                     48:        "label",        YLABEL,
                     49:        "mod",          YMOD,
                     50:        "nil",          YNIL,
                     51:        "not",          YNOT,
                     52:        "of",           YOF,
                     53:        "or",           YOR,
                     54:        "packed",       YPACKED,
                     55:        "procedure",    YPROCEDURE,
                     56:        "program",      YPROG,
                     57:        "record",       YRECORD,
                     58:        "repeat",       YREPEAT,
                     59:        "set",          YSET,
                     60:        "then",         YTHEN,
                     61:        "to",           YTO,
                     62:        "type",         YTYPE,
                     63:        "until",        YUNTIL,
                     64:        "var",          YVAR,
                     65:        "while",        YWHILE,
                     66:        "with",         YWITH,
                     67:        0,              0,       /* the following keywords are non-standard */
                     68:        "oct",          YOCT,
                     69:        "hex",          YHEX,
                     70:        "external",     YEXTERN,
                     71:        0
                     72: };
                     73: 
                     74: char *lastkey;
                     75: 
                     76: /*
                     77:  * Inithash initializes the hash table routines
                     78:  * by allocating the first hash table segment using
                     79:  * an already existing memory slot.
                     80:  */
                     81: #ifndef PI0
                     82: inithash()
                     83: #else
                     84: inithash(hshtab)
                     85:        int *hshtab;
                     86: #endif
                     87: {
                     88:        register int *ip;
                     89: #ifndef PI0
                     90:        static int hshtab[HASHINC];
                     91: #endif
                     92: 
                     93:        htab[0].ht_low = hshtab;
                     94:        htab[0].ht_high = &hshtab[HASHINC];
                     95:        for (ip = ((int *)yykey); *ip; ip += 2)
                     96:                hash((char *) ip[0], 0)[0] = ((int) ip);
                     97:        /*
                     98:         * If we are not running in "standard-only" mode,
                     99:         * we load the non-standard keywords.
                    100:         */
                    101:        if (!opt('s'))
                    102:                for (ip += 2; *ip; ip += 2)
                    103:                        hash((char *) ip[0], 0)[0] = ((int) ip);
                    104:        lastkey = (char *)ip;
                    105: }
                    106: 
                    107: /*
                    108:  * Hash looks up the s(ymbol) argument
                    109:  * in the string table, entering it if
                    110:  * it is not found. If save is 0, then
                    111:  * the argument string is already in
                    112:  * a safe place. Otherwise, if hash is
                    113:  * entering the symbol for the first time
                    114:  * it will save the symbol in the string
                    115:  * table using savestr.
                    116:  */
                    117: int *hash(s, save)
                    118:        char *s;
                    119:        int save;
                    120: {
                    121:        register int *h;
                    122:        register i;
                    123:        register char *cp;
                    124:        int *sym;
                    125:        struct cstruct *temp;
                    126:        struct ht *htp;
                    127:        int sh;
                    128: 
                    129:        /*
                    130:         * The hash function is a modular hash of
                    131:         * the sum of the characters with the sum
                    132:         * doubled before each successive character
                    133:         * is added.
                    134:         */
                    135:        cp = s;
                    136:        if (cp == NIL)
                    137:                cp = token;     /* default symbol to be hashed */
                    138:        i = 0;
                    139:        while (*cp)
                    140:                i = i*2 + *cp++;
                    141:        sh = (i&077777) % HASHINC;
                    142:        cp = s;
                    143:        if (cp == NIL)
                    144:                cp = token;
                    145:        /*
                    146:         * There are as many as MAXHASH active
                    147:         * hash tables at any given point in time.
                    148:         * The search starts with the first table
                    149:         * and continues through the active tables
                    150:         * as necessary.
                    151:         */
                    152:        for (htp = htab; htp < &htab[MAXHASH]; htp++) {
                    153:                if (htp->ht_low == NIL) {
                    154:                        cp = (char *) pcalloc(sizeof ( int * ), HASHINC);
                    155:                        if (cp == 0) {
                    156:                                yerror("Ran out of memory (hash)");
                    157:                                pexit(DIED);
                    158:                        }
                    159:                        htp->ht_low = ((int *)cp);
                    160:                        htp->ht_high = htp->ht_low + HASHINC;
                    161:                        cp = s;
                    162:                        if (cp == NIL)
                    163:                                cp = token;
                    164:                }
                    165:                h = htp->ht_low + sh;
                    166:                /*
                    167:                 * quadratic rehash increment
                    168:                 * starts at 1 and incremented
                    169:                 * by two each rehash.
                    170:                 */
                    171:                i = 1;
                    172:                do {
                    173:                        if (*h == 0) {
                    174:                                if (htp->ht_used > (HASHINC * 3)/4)
                    175:                                        break;
                    176:                                htp->ht_used++;
                    177:                                if (save != 0) {
                    178:                                        *h = (int) savestr(cp);
                    179:                                } else
                    180:                                        *h = ((int) s);
                    181:                                return (h);
                    182:                        }
                    183:                        sym = ((int *) *h);
                    184:                        if (sym < ((int *) lastkey) && sym >= ((int *) yykey))
                    185:                                sym = ((int *) *sym);
                    186:                        temp = ((struct cstruct *) sym);
                    187:                        if (temp->pchar == *cp && pstrcmp((char *) sym, cp) == 0)
                    188:                                return (h);
                    189:                        h += i;
                    190:                        i += 2;
                    191:                        if (h >= htp->ht_high)
                    192:                                h -= HASHINC;
                    193:                } while (i < HASHINC);
                    194:        }
                    195:        yerror("Ran out of hash tables");
                    196:        pexit(DIED);
                    197:        return (NIL);
                    198: 
                    199: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.