49
49
static hashEntry **getHashTable (void)
51
static boolean allocated = FALSE;
57
HashTable = xMalloc (TableSize, hashEntry*);
59
for (i = 0 ; i < TableSize ; ++i)
51
static boolean allocated = FALSE;
57
HashTable = xMalloc (TableSize, hashEntry*);
59
for (i = 0 ; i < TableSize ; ++i)
67
67
static hashEntry *getHashTableEntry (unsigned long hashedValue)
69
hashEntry **const table = getHashTable ();
72
Assert (hashedValue < TableSize);
73
entry = table [hashedValue];
69
hashEntry **const table = getHashTable ();
72
Assert (hashedValue < TableSize);
73
entry = table [hashedValue];
78
78
static unsigned long hashValue (const char *const string)
80
unsigned long value = 0;
81
const unsigned char *p;
83
Assert (string != NULL);
85
/* We combine the various words of the multiword key using the method
86
* described on page 512 of Vol. 3 of "The Art of Computer Programming".
88
for (p = (const unsigned char *) string ; *p != '\0' ; ++p)
91
if (value & 0x00000100L)
92
value = (value & 0x000000ffL) + 1L;
95
/* Algorithm from page 509 of Vol. 3 of "The Art of Computer Programming"
96
* Treats "value" as a 16-bit integer plus 16-bit fraction.
98
value *= 40503L; /* = 2^16 * 0.6180339887 ("golden ratio") */
99
value &= 0x0000ffffL; /* keep fractional part */
100
value >>= 16 - HASH_EXPONENT; /* scale up by hash size and move down */
80
unsigned long value = 0;
81
const unsigned char *p;
83
Assert (string != NULL);
85
/* We combine the various words of the multiword key using the method
86
* described on page 512 of Vol. 3 of "The Art of Computer Programming".
88
for (p = (const unsigned char *) string ; *p != '\0' ; ++p)
91
if (value & 0x00000100L)
92
value = (value & 0x000000ffL) + 1L;
95
/* Algorithm from page 509 of Vol. 3 of "The Art of Computer Programming"
96
* Treats "value" as a 16-bit integer plus 16-bit fraction.
98
value *= 40503L; /* = 2^16 * 0.6180339887 ("golden ratio") */
99
value &= 0x0000ffffL; /* keep fractional part */
100
value >>= 16 - HASH_EXPONENT; /* scale up by hash size and move down */
105
static hashEntry *newEntry (const char *const string,
106
langType language, int value)
105
static hashEntry *newEntry (
106
const char *const string, langType language, int value)
108
hashEntry *const entry = xMalloc (1, hashEntry);
111
entry->string = string;
112
entry->language = language;
113
entry->value = value;
108
hashEntry *const entry = xMalloc (1, hashEntry);
111
entry->string = string;
112
entry->language = language;
113
entry->value = value;
118
118
/* Note that it is assumed that a "value" of zero means an undefined keyword
123
123
extern void addKeyword (const char *const string, langType language, int value)
125
const unsigned long hashedValue = hashValue (string);
126
hashEntry *tableEntry = getHashTableEntry (hashedValue);
127
hashEntry *entry = tableEntry;
131
hashEntry **const table = getHashTable ();
132
table [hashedValue] = newEntry (string, language, value);
136
hashEntry *prev = NULL;
125
const unsigned long hashedValue = hashValue (string);
126
hashEntry *tableEntry = getHashTableEntry (hashedValue);
127
hashEntry *entry = tableEntry;
131
hashEntry **const table = getHashTable ();
132
table [hashedValue] = newEntry (string, language, value);
136
hashEntry *prev = NULL;
138
while (entry != NULL)
140
if (language == entry->language &&
141
strcmp (string, entry->string) == 0)
143
Assert (("Already in table" == NULL));
150
Assert (prev != NULL);
151
prev->next = newEntry (string, language, value);
156
extern int lookupKeyword (const char *const string, langType language)
158
const unsigned long hashedValue = hashValue (string);
159
hashEntry *entry = getHashTableEntry (hashedValue);
138
162
while (entry != NULL)
140
if (language == entry->language &&
141
strcmp (string, entry->string) == 0)
143
Assert (("Already in table" == NULL));
150
Assert (prev != NULL);
151
prev->next = newEntry (string, language, value);
156
extern int lookupKeyword (const char *const string, langType language)
158
const unsigned long hashedValue = hashValue (string);
159
hashEntry *entry = getHashTableEntry (hashedValue);
162
while (entry != NULL)
164
if (language == entry->language && strcmp (string, entry->string) == 0)
166
result = entry->value;
164
if (language == entry->language && strcmp (string, entry->string) == 0)
166
result = entry->value;
174
174
extern void freeKeywordTable (void)
176
if (HashTable != NULL)
180
for (i = 0 ; i < TableSize ; ++i)
176
if (HashTable != NULL)
182
hashEntry *entry = HashTable [i];
184
while (entry != NULL)
186
hashEntry *next = entry->next;
180
for (i = 0 ; i < TableSize ; ++i)
182
hashEntry *entry = HashTable [i];
184
while (entry != NULL)
186
hashEntry *next = entry->next;
197
197
static void printEntry (const hashEntry *const entry)
199
printf (" %-15s %-7s\n", entry->string, getLanguageName (entry->language));
199
printf (" %-15s %-7s\n", entry->string, getLanguageName (entry->language));
202
202
static unsigned int printBucket (const unsigned int i)
204
hashEntry **const table = getHashTable ();
205
hashEntry *entry = table [i];
206
unsigned int measure = 1;
207
boolean first = TRUE;
204
hashEntry **const table = getHashTable ();
205
hashEntry *entry = table [i];
206
unsigned int measure = 1;
207
boolean first = TRUE;
212
else while (entry != NULL)
212
else while (entry != NULL)
223
measure = 2 * measure;
223
measure = 2 * measure;
228
228
extern void printKeywordTable (void)
230
unsigned long emptyBucketCount = 0;
231
unsigned long measure = 0;
234
for (i = 0 ; i < TableSize ; ++i)
236
const unsigned int pass = printBucket (i);
243
printf ("spread measure = %ld\n", measure);
244
printf ("%ld empty buckets\n", emptyBucketCount);
230
unsigned long emptyBucketCount = 0;
231
unsigned long measure = 0;
234
for (i = 0 ; i < TableSize ; ++i)
236
const unsigned int pass = printBucket (i);
243
printf ("spread measure = %ld\n", measure);
244
printf ("%ld empty buckets\n", emptyBucketCount);
249
/* vi:set tabstop=8 shiftwidth=4: */
249
/* vi:set tabstop=4 shiftwidth=4: */