plan9port

fork of plan9port with libvec, libstr and libsdb
Log | Files | Refs | README | LICENSE

symtab.c (1587B)


      1 #include	"mk.h"
      2 
      3 #define	NHASH	4099
      4 #define	HASHMUL	79UL	/* this is a good value */
      5 static Symtab *hash[NHASH];
      6 
      7 void
      8 syminit(void)
      9 {
     10 	Symtab **s, *ss, *next;
     11 
     12 	for(s = hash; s < &hash[NHASH]; s++){
     13 		for(ss = *s; ss; ss = next){
     14 			next = ss->next;
     15 			free((char *)ss);
     16 		}
     17 		*s = 0;
     18 	}
     19 }
     20 
     21 Symtab *
     22 symlook(char *sym, int space, void *install)
     23 {
     24 	unsigned long h;
     25 	char *p;
     26 	Symtab *s;
     27 
     28 	for(p = sym, h = space; *p; h += *p++)
     29 		h *= HASHMUL;
     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(0);
     36 	s = (Symtab *)Malloc(sizeof(Symtab));
     37 	s->space = space;
     38 	s->name = sym;
     39 	s->u.ptr = 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 	unsigned 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 	h %= NHASH;
     57 	for(s = hash[h], ls = 0; s; ls = s, s = s->next)
     58 		if((s->space == space) && (strcmp(s->name, sym) == 0)){
     59 			if(ls)
     60 				ls->next = s->next;
     61 			else
     62 				hash[h] = s->next;
     63 			free((char *)s);
     64 		}
     65 }
     66 
     67 void
     68 symtraverse(int space, void (*fn)(Symtab*))
     69 {
     70 	Symtab **s, *ss;
     71 
     72 	for(s = hash; s < &hash[NHASH]; s++)
     73 		for(ss = *s; ss; ss = ss->next)
     74 			if(ss->space == space)
     75 				(*fn)(ss);
     76 }
     77 
     78 void
     79 symstat(void)
     80 {
     81 	Symtab **s, *ss;
     82 	int n;
     83 	int l[1000];
     84 
     85 	memset((char *)l, 0, sizeof(l));
     86 	for(s = hash; s < &hash[NHASH]; s++){
     87 		for(ss = *s, n = 0; ss; ss = ss->next)
     88 			n++;
     89 		l[n]++;
     90 	}
     91 	for(n = 0; n < 1000; n++)
     92 		if(l[n]) Bprint(&bout, "%ld of length %d\n", l[n], n);
     93 }