symtab.c 1.5 KB

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