| #include "mk.h" |
| |
| #define NHASH 4099 |
| #define HASHMUL 79L /* this is a good value */ |
| static Symtab *hash[NHASH]; |
| |
| void |
| syminit(void) |
| { |
| Symtab **s, *ss, *next; |
| |
| for(s = hash; s < &hash[NHASH]; s++){ |
| for(ss = *s; ss; ss = next){ |
| next = ss->next; |
| free((char *)ss); |
| } |
| *s = 0; |
| } |
| } |
| |
| Symtab * |
| symlook(char *sym, int space, void *install) |
| { |
| long h; |
| char *p; |
| Symtab *s; |
| |
| for(p = sym, h = space; *p; h += *p++) |
| h *= HASHMUL; |
| if(h < 0) |
| h = ~h; |
| h %= NHASH; |
| for(s = hash[h]; s; s = s->next) |
| if((s->space == space) && (strcmp(s->name, sym) == 0)) |
| return(s); |
| if(install == 0) |
| return(0); |
| s = (Symtab *)Malloc(sizeof(Symtab)); |
| s->space = space; |
| s->name = sym; |
| s->u.ptr = install; |
| s->next = hash[h]; |
| hash[h] = s; |
| return(s); |
| } |
| |
| void |
| symdel(char *sym, int space) |
| { |
| long h; |
| char *p; |
| Symtab *s, *ls; |
| |
| /* multiple memory leaks */ |
| |
| for(p = sym, h = space; *p; h += *p++) |
| h *= HASHMUL; |
| if(h < 0) |
| h = ~h; |
| h %= NHASH; |
| for(s = hash[h], ls = 0; s; ls = s, s = s->next) |
| if((s->space == space) && (strcmp(s->name, sym) == 0)){ |
| if(ls) |
| ls->next = s->next; |
| else |
| hash[h] = s->next; |
| free((char *)s); |
| } |
| } |
| |
| void |
| symtraverse(int space, void (*fn)(Symtab*)) |
| { |
| Symtab **s, *ss; |
| |
| for(s = hash; s < &hash[NHASH]; s++) |
| for(ss = *s; ss; ss = ss->next) |
| if(ss->space == space) |
| (*fn)(ss); |
| } |
| |
| void |
| symstat(void) |
| { |
| Symtab **s, *ss; |
| int n; |
| int l[1000]; |
| |
| memset((char *)l, 0, sizeof(l)); |
| for(s = hash; s < &hash[NHASH]; s++){ |
| for(ss = *s, n = 0; ss; ss = ss->next) |
| n++; |
| l[n]++; |
| } |
| for(n = 0; n < 1000; n++) |
| if(l[n]) Bprint(&bout, "%ld of length %d\n", l[n], n); |
| } |