/***********************************************************************/ /* Open Visualization Data Explorer */ /* (C) Copyright IBM Corp. 1989,1999 */ /* ALL RIGHTS RESERVED */ /* This code licensed under the */ /* "IBM PUBLIC LICENSE - Open Visualization Data Explorer" */ /***********************************************************************/ #include #include "dict.h" /* Routines: dicttbl_init, DictInit, DictDelete, DictInsert, DictFind DictSize dicttbl_init() Purpose : Initialize a dictionary table. Output : A pointer to a newly allocated DictTbl returned on success. 0 returned on failure when can't allocate hash array. DictDelete(dict,key) Purpose : Remove user data indicated by key. Output : a pointer equal to the last value of 'def'inserted with key if the item is found. If the key'ed item was inserted with a deleter then the (*deleter)(def) will be called if the item is found. 0 if item is not found. DictInsert(dict,key,def, deleter) Purpose : Add a definition defined by key to the dictionary. if 'deleter' is non-null it will be called as (*deleter)(def) when the item is removed from the dictionary, or the dictionary itself is deleted. Output : None DictFind(dict,key) Purpose : Lookup a key in the specified dictionary. Output : a pointer equal to the last value of 'def'inserted with key if item is found. 0 if item is not found. DictSize(dict) Purpose : Find size of given dictionary. Output : int value equal to number of definitions in dictionary. Notes : Keys should be unique within a table. The last definition inserted with any key is considered the current active definition. This provides for the ability to stack definitions. Warnings: The data at 'datap' is never copied into the hash table. Therefore, if the user alters the data at datap after inserting it, the data will still be on the table but will not be retrievable. */ #include #include "../base/UIConfig.h" #include "../base/defines.h" #include "dict.h" #if defined(MSDOS) || defined(sun4) # include #endif #ifndef NULL #define NULL 0 #endif struct _dictitem_t { struct _dictitem_t *nexti; char *key; void *def; void (*deleter)(void*); }; #define HASH_SIZE 32 static int _dict_hash(const char *str) { char c, *p = (char*)str; int key, i, sum = 0; for (i=0 ; (c = *p) && i<12 ; i++, p++) sum = sum + c; key = sum & (HASH_SIZE -1); return key; } static void DeleteDictItem(DictItem *di) { if (di->deleter) (*di->deleter)(di->def); if (di->key) FREE(di->key); FREE(di); } static DictItem *NewDictItem(const char *key, const void *def, void (*deleter)(void*)) { DictItem *di = (DictItem*)MALLOC(sizeof(DictItem)); if (!di) return NULL; di->nexti = NULL; di->key = strdup(key); di->def = (void*)def; di->deleter = deleter; return di; } void DeleteDictionary(_Dictionary *d) { int i ; for (i=0 ; isize ; i++) { DictItem *di = d->harr[i]; if (di) { DictItem *next; do { next = di->nexti; DeleteDictItem(di); } while (di == next); } } FREE(d->harr); FREE(d); } _Dictionary *NewDictionary() { int i; _Dictionary *dict; dict = (_Dictionary*)MALLOC(sizeof(_Dictionary)); if (!dict) return NULL; if (!(dict->harr = (DictItem**)MALLOC(HASH_SIZE*sizeof(DictItem*)))) return NULL; dict->num_in_dict = 0; dict->size = HASH_SIZE; for (i=0 ; iharr[i] = (DictItem*)NULL; return(dict); } DictDelete(dictionary,key) _Dictionary *dictionary; const char *key; { DictItem *dlist,*next; int found=0; int bucket; bucket = _dict_hash(key); if (dlist = dictionary->harr[bucket]) { found = !strcmp(dlist->key, key); if (found) { /* First item on list */ dictionary->harr[bucket] = dlist->nexti; } else { /* Not first item on list */ while (dlist->nexti && !found) { found = !strcmp(dlist->nexti->key,key); if (!found) dlist = dlist->nexti; else { if (next = dlist->nexti) { dlist->nexti = next->nexti; } else dlist->nexti=(DictItem*)0; dlist = next; dictionary->num_in_dict -= 1; } } } DeleteDictItem(dlist); } #ifdef debug printf("delete: key = %d, found = %d\n",key,found); #endif return(found); } DictInsert(dictionary,key,def, deleter) _Dictionary *dictionary; const char *key; void *def; void (*deleter)(void*); { DictItem *dlist; int bucket; dlist = NewDictItem(key,def,deleter); if (!dlist) return NULL; bucket = _dict_hash(key); dlist->nexti = dictionary->harr[bucket]; dictionary->harr[bucket] = dlist; dictionary->num_in_dict += 1; return 1; } void *DictFind(dictionary,key) _Dictionary *dictionary; const char *key; { DictItem *dlist; int found=0; dlist = dictionary->harr[_dict_hash(key)]; while (dlist && !found) { found = !strcmp(dlist->key,key); if (!found) dlist = dlist->nexti; else return(dlist->def); } return(0); }