|
|
1.1 root 1: /*
2: * hashing.c 1.3
3: *
4: * Hashing Functions for Spreadsheet Program `vis'
5: *
6: * A. F. Gettier
7: * Bell Laboratories
8: * Update made 11/1/82 11:11:37
9: * Retrieved 11/15/82 13:22:21
10: */
11: #include <stdio.h>
12: #include "vis.h"
13: #include "y.tab.h"
14:
15: struct hashhdr htbl;
16:
17: static struct reswd reswd[]={
18: "PI", PI,
19: "ABS", ABS,
20: "ACOS", ACOS,
21: "ASIN", ASIN,
22: "AT", AT,
23: "ATAN", ATAN,
24: "ATAN2", ATAN2,
25: "COS", COS,
26: "EXP", EXP,
27: "GAMMA", GAMMA,
28: "HYPOT", HYPOT,
29: "INT", INT,
30: "LOG", LOG,
31: "POW", POW,
32: "SIN", SIN,
33: "SQRT", SQRT,
34: "COL", COL,
35: "COPY", COPY,
36: "DEBUG", DEBUG,
37: "DOWN", DOWN,
38: "DUP", DUP,
39: "DUPLICATE", DUPLICATE,
40: "EDIT", EDIT,
41: "HELP", HELP,
42: "LEFT", LEFT,
43: "LIST", LIST,
44: "POSITION", POSITION,
45: "READ", READ,
46: "REDRAW", REDRAW,
47: "REFRESH", REFRESH,
48: "REP", REP,
49: "REPLICATE", REPLICATE,
50: "RIGHT", RIGHT,
51: "ROW", ROW,
52: "SCALE", SCALE,
53: "SHIFT", SHIFT,
54: "SLIDE", SLIDE,
55: "SHELL", SHELL,
56: "SH", SH,
57: "THRU", THRU,
58: "UP", UP,
59: "VER", VER,
60: "WIDTH", WIDTH,
61: "WRITE", WRITE,
62: "ZERO", ZERO,
63: "QUIT", QUIT,
64: 0, 0 };
65:
66: /*
67: * Init a hash table
68: */
69: void hashinit()
70: {
71: int i;
72: int size;
73: struct hashentry *tbl;
74: size = 63; /* default hash table size */
75: htbl.size = size;
76: tbl = htbl.table = multnode( hashentry, size );
77: for ( i=0; i<size; i++ ) (tbl++)->symbol = 0;
78: /*
79: * enter all the keywords
80: */
81: for( i=0; reswd[i].name!=0; i++ )
82: hashenter( reswd[i].name, reswd[i].value );
83: }
84:
85: /*
86: * Search a hash table
87: */
88: hashsearch( symbol )
89: char *symbol;
90: {
91: int key, mkey;
92: struct hashentry *tbl, *start;
93: key = makekey( symbol );
94: mkey = key%(htbl.size - 1);
95: start = tbl = htbl.table + mkey;
96: do {
97: if ( tbl->symbol == 0 ) return( 0 );
98: if ( tbl->symbol != (char *)(-1) && tbl->key == key
99: && strcmp( symbol, tbl->symbol ) == 0 )
100: return(tbl->value);
101: tbl++;
102: if ( tbl >= (htbl.table + htbl.size ) ) tbl = htbl.table;
103: } while ( tbl != start );
104: return( 0 );
105: }
106:
107: /*
108: * Enter into a hash table
109: */
110: void hashenter( symbol, value )
111: char *symbol;
112: int value;
113: {
114: int key, mkey;
115: float a, b;
116: struct hashentry *tbl;
117: a = htbl.size;
118: b = htbl.entry;
119: /*
120: * First try to clean up the table
121: */
122: if ( b/a > .65 ) hashclean( );
123: /*
124: * Now expand
125: */
126: b = htbl.entry;
127: if ( b/a > .65 ) hashexpand( );
128: key = makekey( symbol );
129: mkey = key%(htbl.size - 1);
130: tbl = htbl.table;
131: tbl += mkey;
132: loop {
133: if ( tbl->symbol == 0 || tbl->symbol == (char *)(-1)) {
134: tbl->key = key;
135: tbl->symbol = symbol;
136: (htbl.entry)++;
137: tbl->value = value;
138: return;
139: }
140: if ( tbl->key == key && strcmp( symbol, tbl->symbol ) == 0 ) {
141: tbl->value = value;
142: return;
143: }
144: tbl++;
145: if ( tbl >= (htbl.table + htbl.size ) ) tbl = htbl.table;
146: }
147: }
148:
149: /*
150: * Make the key
151: */
152: static makekey( symbol )
153: char *symbol;
154: {
155: int key, i;
156: key = 0;
157: i = 8;
158: while (*symbol != 0) {
159: key += *symbol + ((*symbol)<<8) + ((*symbol)<<(i++));
160: symbol++;
161: }
162: return( ((key<0)?(-key):(key)) );
163: }
164:
165: /*
166: * Expand the Hash Table
167: */
168: static hashexpand( )
169: {
170: int i, mkey, size;
171: struct hashentry *tbl, *temp, *tbl2;
172: size = htbl.size * 2 + 1;
173: tbl = temp = multnode( hashentry, size );
174: for ( i=0; i<size; i++ ) (temp++)->symbol = 0;
175: tbl2 = htbl.table;
176: for ( i=0; i<htbl.size; i++ ) {
177: if ( tbl2->symbol == 0 || tbl2->symbol == (char *)(-1)) {
178: tbl2++;
179: continue;
180: }
181: mkey = (tbl2->key)%(size - 1);
182: temp = tbl;
183: temp += mkey;
184: loop {
185: if ( temp->symbol == 0 ) {
186: temp->key = tbl2->key;
187: temp->symbol = tbl2->symbol;
188: temp->value = tbl2->value;
189: tbl2++;
190: break;
191: }
192: temp++;
193: if ( temp >= ( tbl+ size ) ) temp = tbl;
194: }
195: }
196: free( (char *)htbl.table );
197: htbl.size = size;
198: htbl.table = tbl;
199: }
200:
201: /*
202: * Clean up the Hash Table
203: */
204: static hashclean( )
205: {
206: int i, mkey, size, entry;
207: struct hashentry *tbl, *temp, *tbl2;
208: size = htbl.size;
209: tbl = temp = multnode( hashentry, size );
210: for ( i=0; i<size; i++ ) (temp++)->symbol = 0;
211: entry = 0;
212: tbl2 = htbl.table;
213: for ( i=0; i<htbl.size; i++ ) {
214: if ( tbl2->symbol == 0 || tbl2->symbol == (char *)(-1)) {
215: tbl2++;
216: continue;
217: }
218: mkey = (tbl2->key)%(size - 1);
219: temp = tbl;
220: temp += mkey;
221: loop {
222: if ( temp->symbol == 0 ) {
223: temp->key = tbl2->key;
224: temp->symbol = tbl2->symbol;
225: temp->value = tbl2->value;
226: tbl2++;
227: entry++;
228: break;
229: }
230: temp++;
231: if ( temp >= ( tbl+ size ) ) temp = tbl;
232: }
233: }
234: free( (char *)htbl.table );
235: htbl.entry = entry;
236: htbl.table = tbl;
237: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.