home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / gnu / lucid / xpm-3.2a / hashtable.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-08-16  |  4.9 KB  |  199 lines

  1. /* Copyright 1990,91 GROUPE BULL -- See license conditions in file COPYRIGHT */
  2. /*****************************************************************************\
  3. * hashtable.c:                                                                *
  4. *                                                                             *
  5. *  XPM library                                                                *
  6. *                                                                             *
  7. *  Developed by Arnaud Le Hors                                                *
  8. *  this originaly comes from Colas Nahaboo as a part of Wool                  *
  9. *                                                                             *
  10. \*****************************************************************************/
  11.  
  12. #include "xpmP.h"
  13.  
  14. LFUNC(AtomMake, xpmHashAtom, (char *name, void *data));
  15. LFUNC(HashTableGrows, int, (xpmHashTable *table));
  16.  
  17. static xpmHashAtom
  18. AtomMake(name, data)            /* makes an atom */
  19.     char *name;                /* WARNING: is just pointed to */
  20.     void *data;
  21. {
  22.     xpmHashAtom object = (xpmHashAtom) malloc(sizeof(struct _xpmHashAtom));
  23.     if (object) {
  24.     object->name = name;
  25.     object->data = data;
  26.     }
  27.     return object;
  28. }
  29.  
  30. /************************\
  31. *              *
  32. *  hash table routines      *
  33. *              *
  34. \************************/
  35.  
  36. /*
  37.  * Hash function definition:
  38.  * HASH_FUNCTION: hash function, hash = hashcode, hp = pointer on char,
  39.  *                 hash2 = temporary for hashcode.
  40.  * INITIAL_TABLE_SIZE in slots
  41.  * HASH_TABLE_GROWS how hash table grows.
  42.  */
  43.  
  44. /* Mock lisp function */
  45. #define HASH_FUNCTION       hash = (hash << 5) - hash + *hp++;
  46. /* #define INITIAL_HASH_SIZE 2017 */
  47. #define INITIAL_HASH_SIZE 256        /* should be enough for colors */
  48. #define HASH_TABLE_GROWS  size = size * 2;
  49.  
  50. /* aho-sethi-ullman's HPJ (sizes should be primes)*/
  51. #ifdef notdef
  52. #define HASH_FUNCTION    hash <<= 4; hash += *hp++; \
  53.     if(hash2 = hash & 0xf0000000) hash ^= (hash2 >> 24) ^ hash2;
  54. #define INITIAL_HASH_SIZE 4095        /* should be 2^n - 1 */
  55. #define HASH_TABLE_GROWS  size = size << 1 + 1;
  56. #endif
  57.  
  58. /* GNU emacs function */
  59. /*
  60. #define HASH_FUNCTION       hash = (hash << 3) + (hash >> 28) + *hp++;
  61. #define INITIAL_HASH_SIZE 2017
  62. #define HASH_TABLE_GROWS  size = size * 2;
  63. */
  64.  
  65. /* end of hash functions */
  66.  
  67. /*
  68.  * The hash table is used to store atoms via their NAME:
  69.  *
  70.  * NAME --hash--> ATOM |--name--> "foo"
  71.  *               |--data--> any value which has to be stored
  72.  *
  73.  */
  74.  
  75. /*
  76.  * xpmHashSlot gives the slot (pointer to xpmHashAtom) of a name
  77.  * (slot points to NULL if it is not defined)
  78.  *
  79.  */
  80.  
  81. xpmHashAtom *
  82. xpmHashSlot(table, s)
  83.     xpmHashTable *table;
  84.     char *s;
  85. {
  86.     xpmHashAtom *atomTable = table->atomTable;
  87.     unsigned int hash, hash2;
  88.     xpmHashAtom *p;
  89.     char *hp = s;
  90.     char *ns;
  91.  
  92.     hash = 0;
  93.     while (*hp) {            /* computes hash function */
  94.     HASH_FUNCTION
  95.     }
  96.     p = atomTable + hash % table->size;
  97.     while (*p) {
  98.     ns = (*p)->name;
  99.     if (ns[0] == s[0] && strcmp(ns, s) == 0)
  100.         break;
  101.     p--;
  102.     if (p < atomTable)
  103.         p = atomTable + table->size - 1;
  104.     }
  105.     return p;
  106. }
  107.  
  108. static int
  109. HashTableGrows(table)
  110.     xpmHashTable *table;
  111. {
  112.     xpmHashAtom *atomTable = table->atomTable;
  113.     int size = table->size;
  114.     xpmHashAtom *t, *p;
  115.     int i;
  116.     int oldSize = size;
  117.  
  118.     t = atomTable;
  119.     HASH_TABLE_GROWS
  120.     table->size = size;
  121.     table->limit = size / 3;
  122.     atomTable = (xpmHashAtom *) malloc(size * sizeof(*atomTable));
  123.     table->atomTable = atomTable;
  124.     for (p = atomTable + size; p > atomTable;)
  125.     *--p = NULL;
  126.     for (i = 0, p = t; i < oldSize; i++, p++)
  127.     if (*p) {
  128.         xpmHashAtom *ps = xpmHashSlot(table, (*p)->name);
  129.         *ps = *p;
  130.     }
  131.     free(t);
  132. }
  133.  
  134. /*
  135.  * xpmHashIntern(table, name, data)
  136.  * return an xpmHashAtom, which is the one at the slot, if present,
  137.  * or is created if name didn't exist, with the given data.
  138.  */
  139.  
  140. xpmHashAtom
  141. xpmHashIntern(table, tag, data)
  142.     xpmHashTable *table;
  143.     char *tag;
  144.     void *data;
  145. {
  146.     xpmHashAtom *slot;
  147.  
  148.     if (!*(slot = xpmHashSlot(table, tag))) {
  149.     /* undefined, make a new atom with the given data */
  150.         *slot = AtomMake(tag, data);
  151.  
  152.     if (table->used >= table->limit) {
  153.         xpmHashAtom new = *slot;
  154.  
  155.         HashTableGrows(table);
  156.         table->used++;
  157.         return new;
  158.     }
  159.     table->used++;
  160.     }
  161.     return *slot;
  162. }
  163.  
  164. /*
  165.  *  must be called before allocating any atom
  166.  */
  167.  
  168. xpmHashTableInit(table)
  169.     xpmHashTable *table;
  170. {
  171.     xpmHashAtom *p;
  172.     xpmHashAtom *atomTable;
  173.  
  174.     table->size = INITIAL_HASH_SIZE;
  175.     table->limit = table->size / 3;
  176.     table->used = 0;
  177.     atomTable = (xpmHashAtom *) malloc(table->size * sizeof(*atomTable));
  178.     if (atomTable)
  179.     for (p = atomTable + table->size; p > atomTable;)
  180.         *--p = NULL;
  181.     table->atomTable = atomTable;
  182. }
  183.  
  184. /*
  185.  *   frees a hashtable and all the stored atoms
  186.  */
  187.  
  188. xpmHashTableFree(table)
  189.     xpmHashTable *table;
  190. {
  191.     xpmHashAtom *p;
  192.     xpmHashAtom *atomTable = table->atomTable;
  193.     for (p = atomTable + table->size; p > atomTable;)
  194.     if (*--p)
  195.         free(*p);
  196.     free(atomTable);
  197.     table->atomTable = NULL;
  198. }
  199.