1 #include "mk.h" 2 3 #define NHASH 4099 4 #define HASHMUL 79L /* this is a good value */ 5 static Symtab *hash[NHASH]; 6 7 void 8 syminit(void) 9 { 10 Symtab **s, *ss; 11 12 for(s = hash; s < &hash[NHASH]; s++){ 13 for(ss = *s; ss; ss = ss->next) 14 free((char *)ss); 15 *s = 0; 16 } 17 } 18 19 Symtab * 20 symlook(char *sym, int space, char *install) 21 { 22 long h; 23 char *p; 24 Symtab *s; 25 26 for(p = sym, h = space; *p; h += *p++) 27 h *= HASHMUL; 28 if(h < 0) 29 h = ~h; 30 h %= NHASH; 31 for(s = hash[h]; s; s = s->next) 32 if((s->space == space) && (strcmp(s->name, sym) == 0)) 33 return(s); 34 if(install == 0) 35 return((Symtab *)0); 36 s = (Symtab *)Malloc(sizeof(Symtab)); 37 s->space = space; 38 s->name = sym; 39 s->value = install; 40 s->next = hash[h]; 41 hash[h] = s; 42 return(s); 43 } 44 45 void 46 symdel(char *sym, int space) 47 { 48 long h; 49 char *p; 50 Symtab *s, *ls; 51 52 /* multiple memory leaks */ 53 54 for(p = sym, h = space; *p; h += *p++) 55 h *= HASHMUL; 56 if(h < 0) 57 h = ~h; 58 h %= NHASH; 59 for(s = hash[h], ls = 0; s; ls = s, s = s->next) 60 if((s->space == space) && (strcmp(s->name, sym) == 0)){ 61 if(ls) 62 ls->next = s->next; 63 else 64 hash[h] = s->next; 65 free((char *)s); 66 } 67 } 68 69 void 70 symtraverse(int space, void (*fn)(Symtab*)) 71 { 72 Symtab **s, *ss; 73 74 for(s = hash; s < &hash[NHASH]; s++) 75 for(ss = *s; ss; ss = ss->next) 76 if(ss->space == space) 77 (*fn)(ss); 78 } 79 80 void 81 symstat(void) 82 { 83 Symtab **s, *ss; 84 int n; 85 int l[1000]; 86 87 memset((char *)l, 0, sizeof(l)); 88 for(s = hash; s < &hash[NHASH]; s++){ 89 for(ss = *s, n = 0; ss; ss = ss->next) 90 n++; 91 l[n]++; 92 } 93 for(n = 0; n < 1000; n++) 94 if(l[n]) Bprint(&stdout, "%ld of length %d\n", l[n], n); 95 } 96