Advertisement
avp210159

symtab.c (part of calculator)

Jan 27th, 2016
174
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 3.20 KB | None | 0 0
  1. // avp 2016 (part of Symtab)
  2.  
  3. #include <stdio.h>
  4. #include <stdlib.h>
  5. #include <string.h>
  6. #include <stdint.h>
  7.  
  8. #ifdef __cplusplus
  9. typedef double (*function)(...);
  10. #else
  11. typedef double (*function)();
  12. #endif
  13.  
  14. typedef struct u_item *Symtab;
  15. static Symtab *calc_fun = 0; // default functions hashtable
  16.  
  17. // hashtables item
  18. struct u_item {
  19.   struct u_item *next;
  20.   union {
  21.     function f;
  22.     double v;
  23.   };
  24.   int len;
  25.   char name[1];
  26. };
  27.  
  28. #define INIT_HTAB_SIZE 5
  29. #define HTAB_REHASH 2
  30.  
  31.  
  32. static struct u_item **
  33. make_htab (int sz)
  34. {
  35.   struct u_item **p = (typeof(p))calloc(sizeof(*p), sz + 2);
  36.  
  37.   if (p)
  38.     p[0] = (typeof(*p))(long)sz;
  39.  
  40.   return p + 2;
  41. }
  42.  
  43. static inline uint32_t
  44. hash32 (const char *s, int len)
  45. {
  46.   uint32_t h = 0;
  47.  
  48.   /* Bernstein */
  49.   while (len--)
  50.     h = h * 33 + (uint8_t)(*s++);
  51.  
  52.   /* Murmur OAAT
  53.   while (len--) {
  54.     h ^= (uint8_t)(*s++);
  55.     h *= 0x5bd1e995;
  56.     h ^= h >> 15;
  57.   }
  58.   */
  59.  
  60.   /* FNV
  61.   h ^= 2166136261U;
  62.   while (len--) {
  63.     h ^= (uint8_t)(*s++);
  64.     h *= 16777619;
  65.   }
  66.   */
  67.  
  68.   return h;
  69. }
  70.  
  71. static void
  72. rehash (struct u_item **htab[])
  73. {
  74.   struct u_item **t = *htab, **newtab;
  75.   long hsize = (long)t[-2], n = (long)t[-1];
  76.  
  77.   if (n > 0) {
  78.     if ((newtab = (typeof(newtab))calloc(sizeof(*newtab), n + 2))) {
  79.       newtab[0] = newtab[1]= (typeof(*newtab))n;
  80.       *htab = newtab + 2;
  81.       //      t += 2;
  82.       long i;
  83.       for (i = 0; i < hsize; i++)
  84.     while (t[i]) {
  85.       struct u_item *p = t[i];
  86.       t[i] = p->next;
  87.       int j = hash32(p->name, p->len) % n;
  88.       p->next = (*htab)[j];
  89.       (*htab)[j] = p;
  90.     }
  91.       free(t - 2);
  92.     }
  93.   }
  94. }
  95.  
  96. static int
  97. check_htab (struct u_item **htab[])
  98. {
  99.   if (htab) {
  100.     if (!*htab)
  101.       if (!(*htab = make_htab(INIT_HTAB_SIZE)))
  102.     return 0;
  103.     if ((long)(*htab)[-1] / (long)(*htab)[-2] >= HTAB_REHASH)
  104.       rehash(htab);
  105.      
  106.     return 1;
  107.   }
  108.   return 0;
  109. }
  110.  
  111. static struct u_item *
  112. get_htab (struct u_item **htab[], const char *s, int len)
  113. {
  114.   struct u_item *p = 0;
  115.  
  116.   if (len > 0 && check_htab(htab)) {
  117.     long hsize = (long)(*htab)[-2];
  118.  
  119.     for (p = (*htab)[hash32(s, len) % hsize]; p; p = p->next)
  120.       if (len == p->len && memcmp(p->name, s, len) == 0)
  121.     break;
  122.   }
  123.   return p;
  124. }
  125.  
  126. static struct u_item *
  127. put_htab (struct u_item **htab[], const char *s, int len)
  128. {
  129.   struct u_item *p = 0;
  130.  
  131.   if (len > 0 && check_htab(htab)) {
  132.     long hsize = (long)(*htab)[-2], j = hash32(s, len) % hsize;
  133.  
  134.     for (p = (*htab)[j]; p; p = p->next)
  135.       if (p->len == len && memcmp(p->name, s, len) == 0)
  136.     break;
  137.     if (!p && (p = (typeof(p))calloc(1, sizeof(*p) + len))) {
  138.       (*(long *)(*htab - 1))++;
  139.       p->next = (*htab)[j];
  140.       (*htab)[j] = p;
  141.       memcpy(p->name, s, p->len = len);
  142.     }
  143.   }
  144.  
  145.   return p;
  146. }
  147.  
  148. static int
  149. del_htab (struct u_item **htab[], const char *s, int len)
  150. {
  151.   struct u_item *p = 0, **pp = 0;
  152.  
  153.   if (len > 0 && check_htab(htab)) {
  154.     long hsize = (long)(*htab)[-2], j = hash32(s, len) % hsize;
  155.  
  156.     for (p = (*htab)[j], pp = *htab + j; p; pp = &p->next, p = p->next)
  157.       if (len == p->len && memcmp(p->name, s, len) == 0) {
  158.     *pp = p->next;
  159.     (*(long *)(*htab - 1))++;
  160.     free(p);
  161.     return 1;
  162.       }
  163.   }
  164.  
  165.   return 0;
  166. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement