summaryrefslogtreecommitdiff
path: root/src/hash.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/hash.c')
-rw-r--r--src/hash.c134
1 files changed, 68 insertions, 66 deletions
diff --git a/src/hash.c b/src/hash.c
index c18f9a2..70ffd07 100644
--- a/src/hash.c
+++ b/src/hash.c
@@ -26,8 +26,8 @@ the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
#endif
#include "hash.h"
-unsigned long (*hashfunc)(char *) = NULL;
-int (*matchfunc)(char *, char *) = NULL;
+unsigned long (*hashfunc)(char *, int) = hash;
+int (*matchfunc)(char *, char *) = match;
int (*matchintfunc)(char *, char *, int, int) = NULL;
/* Add match functions: These are just strcmp() and */
@@ -45,13 +45,17 @@ int matchnocase(char *st1, char *st2)
else return 0;
}
-void InitializeHashTable(struct hashlist **tab)
+void InitializeHashTable(struct hashtable *table, int hashsize)
{
int i;
- for (i = 0; i < OBJHASHSIZE; i++) tab[i] = NULL;
+ table->hashsize = hashsize;
+ table->hashfirstindex = 0;
+ table->hashfirstptr = NULL;
+ table->hashtab = (struct hashlist **)malloc(hashsize * sizeof(struct hashlist *));
+ for (i = 0; i < hashsize; i++) table->hashtab[i] = NULL;
}
-int RecurseHashTable(struct hashlist **hashtab,
+int RecurseHashTable(struct hashtable *table,
int (*func)(struct hashlist *elem))
/* returns the sum of the return values of (*func) */
{
@@ -59,8 +63,8 @@ int RecurseHashTable(struct hashlist **hashtab,
struct hashlist *p;
sum = 0;
- for (i = 0; i < OBJHASHSIZE; i++)
- for (p = hashtab[i]; p != NULL; p = p->next)
+ for (i = 0; i < table->hashsize; i++)
+ for (p = table->hashtab[i]; p != NULL; p = p->next)
sum += (*func)(p);
return(sum);
}
@@ -69,15 +73,15 @@ int RecurseHashTable(struct hashlist **hashtab,
* type int value to the function.
*/
-int RecurseHashTableValue(struct hashlist **hashtab,
+int RecurseHashTableValue(struct hashtable *table,
int (*func)(struct hashlist *elem, int), int value)
{
int i, sum;
struct hashlist *p;
sum = 0;
- for (i = 0; i < OBJHASHSIZE; i++)
- for (p = hashtab[i]; p != NULL; p = p->next)
+ for (i = 0; i < table->hashsize; i++)
+ for (p = table->hashtab[i]; p != NULL; p = p->next)
sum += (*func)(p, value);
return(sum);
}
@@ -88,7 +92,7 @@ int RecurseHashTableValue(struct hashlist **hashtab,
* function through that structure.
*/
-struct nlist *RecurseHashTablePointer(struct hashlist **hashtab,
+struct nlist *RecurseHashTablePointer(struct hashtable *table,
struct nlist *(*func)(struct hashlist *elem, void *),
void *pointer)
{
@@ -96,8 +100,8 @@ struct nlist *RecurseHashTablePointer(struct hashlist **hashtab,
struct hashlist *p;
struct nlist *tp;
- for (i = 0; i < OBJHASHSIZE; i++) {
- for (p = hashtab[i]; p != NULL; p = p->next) {
+ for (i = 0; i < table->hashsize; i++) {
+ for (p = table->hashtab[i]; p != NULL; p = p->next) {
tp = (*func)(p, pointer);
if (tp != NULL) return tp;
}
@@ -142,23 +146,23 @@ static unsigned char uppercase[] = {
// have exactly the same hash result. Lousy for binning and even
// lousier for generating class magic numbers.
-unsigned long hashnocase(char *s)
+unsigned long hashnocase(char *s, int hashsize)
{
unsigned long hashval;
for (hashval = 0; *s != '\0'; )
hashval = uppercase[*s++]
+ (hashval << 6) + (hashval << 16) - hashval;
- return (hashval % OBJHASHSIZE);
+ return (hashval % hashsize);
}
-unsigned long hash(char *s)
+unsigned long hash(char *s, int hashsize)
{
unsigned long hashval;
for (hashval = 0; *s != '\0'; )
hashval = (*s++) + (hashval << 6) + (hashval << 16) - hashval;
- return (hashval % OBJHASHSIZE);
+ return (hashval % hashsize);
}
/*----------------------------------------------------------------------*/
@@ -166,14 +170,14 @@ unsigned long hash(char *s)
/* return the 'ptr' field of the hash table entry, or NULL if not found */
/*----------------------------------------------------------------------*/
-void *HashLookup(char *s, struct hashlist **hashtab)
+void *HashLookup(char *s, struct hashtable *table)
{
struct hashlist *np;
unsigned long hashval;
- hashval = (*hashfunc)(s);
+ hashval = (*hashfunc)(s, table->hashsize);
- for (np = hashtab[hashval]; np != NULL; np = np->next)
+ for (np = table->hashtab[hashval]; np != NULL; np = np->next)
if ((*matchfunc)(s, np->name))
return (np->ptr); /* correct match */
return (NULL); /* not found */
@@ -186,14 +190,14 @@ void *HashLookup(char *s, struct hashlist **hashtab)
/* passed integer value i */
/*----------------------------------------------------------------------*/
-void *HashIntLookup(char *s, int i, struct hashlist **hashtab)
+void *HashIntLookup(char *s, int i, struct hashtable *table)
{
struct hashlist *np;
unsigned long hashval;
- hashval = (*hashfunc)(s);
+ hashval = (*hashfunc)(s, table->hashsize);
- for (np = hashtab[hashval]; np != NULL; np = np->next) {
+ for (np = table->hashtab[hashval]; np != NULL; np = np->next) {
if (np->ptr == NULL) {
if ((*matchintfunc)(s, np->name, i, -1))
return NULL;
@@ -210,14 +214,13 @@ void *HashIntLookup(char *s, int i, struct hashlist **hashtab)
/* return the hashlist entry, after (re)initializing its 'ptr' field */
/*----------------------------------------------------------------------*/
-struct hashlist *HashPtrInstall(char *name, void *ptr,
- struct hashlist **hashtab)
+struct hashlist *HashPtrInstall(char *name, void *ptr, struct hashtable *table)
{
struct hashlist *np;
unsigned long hashval;
- hashval = (*hashfunc)(name);
- for (np = hashtab[hashval]; np != NULL; np = np->next)
+ hashval = (*hashfunc)(name, table->hashsize);
+ for (np = table->hashtab[hashval]; np != NULL; np = np->next)
if ((*matchfunc)(name, np->name)) {
np->ptr = ptr;
return (np); /* match found in hash table */
@@ -229,8 +232,8 @@ struct hashlist *HashPtrInstall(char *name, void *ptr,
if ((np->name = strdup(name)) == NULL)
return (NULL);
np->ptr = ptr;
- np->next = hashtab[hashval];
- return(hashtab[hashval] = np);
+ np->next = table->hashtab[hashval];
+ return(table->hashtab[hashval] = np);
}
/*----------------------------------------------------------------------*/
@@ -239,13 +242,13 @@ struct hashlist *HashPtrInstall(char *name, void *ptr,
/*----------------------------------------------------------------------*/
struct hashlist *HashIntPtrInstall(char *name, int value, void *ptr,
- struct hashlist **hashtab)
+ struct hashtable *table)
{
struct hashlist *np;
unsigned long hashval;
- hashval = (*hashfunc)(name);
- for (np = hashtab[hashval]; np != NULL; np = np->next)
+ hashval = (*hashfunc)(name, table->hashsize);
+ for (np = table->hashtab[hashval]; np != NULL; np = np->next)
if ((*matchintfunc)(name, np->name, value, (int)(*((int *)np->ptr)))) {
np->ptr = ptr;
return (np); /* match found in hash table */
@@ -256,27 +259,29 @@ struct hashlist *HashIntPtrInstall(char *name, int value, void *ptr,
return (NULL);
if ((np->name = strdup(name)) == NULL) return (NULL);
np->ptr = ptr;
- np->next = hashtab[hashval];
- return(hashtab[hashval] = np);
+ np->next = table->hashtab[hashval];
+ return(table->hashtab[hashval] = np);
}
/*----------------------------------------------------------------------*/
/* destroy a hash table, freeing associated memory */
/*----------------------------------------------------------------------*/
-void HashKill(struct hashlist **hashtab)
+void HashKill(struct hashtable *table)
{
struct hashlist *np, *p;
int i;
- for (i = 0; i < OBJHASHSIZE; i++) {
- for (p = hashtab[i]; p != NULL; ) {
+ for (i = 0; i < table->hashsize; i++) {
+ for (p = table->hashtab[i]; p != NULL; ) {
np = p->next;
free(p->name);
free(p);
p = np;
}
}
+ free(table->hashtab);
+ table->hashtab = NULL;
}
/*----------------------------------------------------------------------*/
@@ -284,13 +289,13 @@ void HashKill(struct hashlist **hashtab)
/* to the new hash entry. */
/*----------------------------------------------------------------------*/
-struct hashlist *HashInstall(char *name, struct hashlist **hashtab)
+struct hashlist *HashInstall(char *name, struct hashtable *table)
{
struct hashlist *np;
unsigned long hashval;
- hashval = (*hashfunc)(name);
- for (np = hashtab[hashval]; np != NULL; np = np->next)
+ hashval = (*hashfunc)(name, table->hashsize);
+ for (np = table->hashtab[hashval]; np != NULL; np = np->next)
if ((*matchfunc)(name, np->name)) return (np); /* match found in hash table */
/* not in table, so install it */
@@ -298,27 +303,27 @@ struct hashlist *HashInstall(char *name, struct hashlist **hashtab)
return (NULL);
if ((np->name = strdup(name)) == NULL) return (NULL);
np->ptr = NULL;
- np->next = hashtab[hashval];
- return(hashtab[hashval] = np);
+ np->next = table->hashtab[hashval];
+ return(table->hashtab[hashval] = np);
}
/*----------------------------------------------------------------------*/
/* frees a hash table entry, (but not the 'ptr' field) */
/*----------------------------------------------------------------------*/
-void HashDelete(char *name, struct hashlist **hashtab)
+void HashDelete(char *name, struct hashtable *table)
{
unsigned long hashval;
struct hashlist *np;
struct hashlist *np2;
- hashval = (*hashfunc)(name);
- np = hashtab[hashval];
+ hashval = (*hashfunc)(name, table->hashsize);
+ np = table->hashtab[hashval];
if (np == NULL) return;
if ((*matchfunc)(name, np->name)) {
/* it is the first element in the list */
- hashtab[hashval] = np->next;
+ table->hashtab[hashval] = np->next;
free(np->name);
free(np);
return;
@@ -341,19 +346,19 @@ void HashDelete(char *name, struct hashlist **hashtab)
/* HashDelete with additional integer value matching */
/*----------------------------------------------------------------------*/
-void HashIntDelete(char *name, int value, struct hashlist **hashtab)
+void HashIntDelete(char *name, int value, struct hashtable *table)
{
unsigned long hashval;
struct hashlist *np;
struct hashlist *np2;
- hashval = (*hashfunc)(name);
- np = hashtab[hashval];
+ hashval = (*hashfunc)(name, table->hashsize);
+ np = table->hashtab[hashval];
if (np == NULL) return;
if ((*matchintfunc)(name, np->name, value, (int)(*((int *)np->ptr)))) {
/* it is the first element in the list */
- hashtab[hashval] = np->next;
+ table->hashtab[hashval] = np->next;
free(np->name);
free(np);
return;
@@ -375,31 +380,28 @@ void HashIntDelete(char *name, int value, struct hashlist **hashtab)
/*----------------------------------------------------------------------*/
-static int hashfirstindex; /* was long */
-static struct hashlist *hashfirstptr;
-
-void *HashNext(struct hashlist **hashtab)
+void *HashNext(struct hashtable *table)
/* returns 'ptr' field of next element, NULL when done */
{
- if (hashfirstptr != NULL && hashfirstptr->next != NULL) {
- hashfirstptr = hashfirstptr->next;
- return(hashfirstptr->ptr);
+ if (table->hashfirstptr != NULL && table->hashfirstptr->next != NULL) {
+ table->hashfirstptr = table->hashfirstptr->next;
+ return(table->hashfirstptr->ptr);
}
- while (hashfirstindex < OBJHASHSIZE) {
- if ((hashfirstptr = hashtab[hashfirstindex++]) != NULL) {
- return(hashfirstptr->ptr);
+ while (table->hashfirstindex < table->hashsize) {
+ if ((table->hashfirstptr = table->hashtab[table->hashfirstindex++]) != NULL) {
+ return(table->hashfirstptr->ptr);
}
}
- hashfirstindex = 0;
- hashfirstptr = NULL;
+ table->hashfirstindex = 0;
+ table->hashfirstptr = NULL;
return(NULL);
}
-void *HashFirst(struct hashlist **hashtab)
+void *HashFirst(struct hashtable *table)
{
- hashfirstindex = 0;
- hashfirstptr = NULL;
- return(HashNext(hashtab));
+ table->hashfirstindex = 0;
+ table->hashfirstptr = NULL;
+ return(HashNext(table));
}