Annotation of 3BSD/cmd/pxp/hash.c, revision 1.1.1.1

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

unix.superglobalmegacorp.com

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