Annotation of libwww/Library/src/HTHash.c, revision 1.2

1.1       frystyk     1: /*
                      2: **     HASH TABLE CLASS
                      3: **
                      4: **     This HashTable class implements a simple hash table to keep
                      5: **     objects associated with key words.
                      6: **
                      7: ** Author:
                      8: **     JP      John Punin
                      9: **
                     10: */
                     11: 
                     12: #include "wwwsys.h"
                     13: #include "HTUtils.h"
                     14: #include "HTString.h"
                     15: #include "HTHash.h"
                     16: 
                     17: /*
                     18: (
                     19:   Creation and Deletion Methods
                     20: )
                     21: 
                     22: These methods create and deletes a Hash Table
                     23: */
                     24: 
                     25: PUBLIC HTHashtable * HTHashtable_new (int size)
                     26: {
                     27:     HTHashtable *newHashtable;
                     28:     int c = size > 0 ? size : HT_L_HASH_SIZE;
                     29:     if ((newHashtable = (HTHashtable  *) HT_CALLOC(1, sizeof (HTHashtable))) == NULL)
                     30:         HT_OUTOFMEM("HTHashtable_new");
                     31: 
                     32:     if((newHashtable->table = (void **) HT_CALLOC(c, sizeof (void *))) == NULL)
                     33:        HT_OUTOFMEM("HTHashtable_new");
                     34: 
                     35:     newHashtable->count = 0;
                     36:     newHashtable->size = c;
                     37:     return newHashtable;
                     38: }
                     39: 
                     40: PUBLIC BOOL HTHashtable_delete (HTHashtable *me)
                     41: {
                     42:     if (me) {
1.2     ! kahan      43:        int i;
1.1       frystyk    44:        for(i = 0; i< me->size; i++) {
                     45:            HTList * l = (HTList *)me->table[i];
                     46:            if (l) {
                     47:                HTList *cur = l;
1.2     ! kahan      48:                keynode *kn;
1.1       frystyk    49:                while ((kn = (keynode *) HTList_nextObject(cur))) {
                     50:                    HT_FREE(kn->key);
                     51:                    HT_FREE(kn);
                     52:                }
                     53:                HTList_delete(l);
                     54:            }
                     55:        }
                     56:         HT_FREE(me->table);
                     57:        HT_FREE(me);
                     58:        return YES;
                     59:     }
                     60:     return NO;
                     61: }
                     62: 
                     63: PRIVATE int hash_number (const char *key, int size)
                     64: {
                     65:     int hash = 0;
                     66: 
                     67:     if (key) {
                     68:        const char * ptr = key;
                     69:        for(; *ptr; ptr++)
                     70:            hash = (int) ((hash*3 + (*(unsigned char*)ptr)) % size);
                     71:     }
                     72:     return hash;
                     73: }
                     74: 
                     75: /*
                     76: (
                     77:   Add an Element to a HashTable
                     78: )
                     79: */
                     80: 
1.2     ! kahan      81: PUBLIC BOOL HTHashtable_addObject (HTHashtable *me, const char *key,
1.1       frystyk    82:                                   void *newObject)
                     83: {
                     84:     if(me) {
                     85:        int size = me->size;
                     86:        int i = hash_number(key,size);
                     87:        HTList *l = (HTList *)me->table[i];
1.2     ! kahan      88:        keynode *kn;
1.1       frystyk    89:        if(!l)
                     90:            l = me->table[i] = HTList_new();
                     91:        if ((kn = (keynode  *) HT_CALLOC(1, sizeof (keynode))) == NULL)
                     92:            HT_OUTOFMEM("HTHashtable_addObject");
                     93:        StrAllocCopy(kn->key,key);
                     94:        kn->object = newObject;
                     95:        HTList_addObject(l,kn);
                     96:        me->count++;
                     97:        return YES;
                     98:     }
                     99:     return NO;
                    100: }
1.2     ! kahan     101: 
        !           102: /*
        !           103: (
        !           104:   Remove an Element from the HashTable
        !           105: )
        !           106: */
        !           107: 
        !           108: PUBLIC BOOL HTHashtable_removeObject (HTHashtable *me, const char *key)
        !           109: {
        !           110:     if(me) {
        !           111:        int size = me->size;
        !           112:        int i = hash_number(key,size);
        !           113:        HTList *l = (HTList *)me->table[i];
        !           114:        if(l) {
        !           115:            HTList *cur = l;
        !           116:            keynode *kn;
        !           117:            while ((kn = (keynode *) HTList_nextObject(cur))) {
        !           118:                if(!strcmp(key,kn->key)) {
        !           119:                    HTList_removeObject(l,kn);
        !           120:                    me->count--;
        !           121:                    return YES;
        !           122:                }
        !           123:            }
        !           124:        }
        !           125:     }
        !           126:     return NO;
        !           127: }
        !           128: 
1.1       frystyk   129: /*
                    130: (
                    131:   Search for an Element in a Hash Table
                    132: )
                    133: */
                    134: 
                    135: PUBLIC void *HTHashtable_object (HTHashtable * me, const char *key)
                    136: {
                    137:     if(me) {
                    138:        int size = me->size;
                    139:        int i = hash_number(key,size);
                    140:        HTList * l = (HTList *)me->table[i];
                    141:        if (l) {
                    142:            HTList *cur = l;
1.2     ! kahan     143:            keynode *kn;
1.1       frystyk   144:            while ((kn = (keynode *) HTList_nextObject(cur))) {
                    145:                if(!strcmp(key,kn->key))
                    146:                    return kn->object;
                    147:            }
                    148:        }
                    149:     }
                    150:     return NULL;
                    151: }
                    152: 
                    153: /*
                    154: (
                    155:   Size of a Hash Table
                    156: )
                    157: */
                    158: 
1.2     ! kahan     159: PUBLIC int HTHashtable_count (HTHashtable *me)
1.1       frystyk   160: {
                    161:     if(me)
                    162:        return me->count;
                    163:     return -1;
                    164: }
                    165: 
                    166: /*
                    167: (
1.2     ! kahan     168:    Walk all Elements in the HashTable
        !           169: )
        !           170: */
        !           171: 
        !           172: PUBLIC BOOL HTHashtable_walk (HTHashtable *me,
        !           173:                              int (*walkFunc)(HTHashtable *,char *, void *))
        !           174: {
        !           175:     if(me) {
        !           176:        int i, j;
        !           177:        for(i = 0; i< me->size; i++) {
        !           178:            HTList *l = (HTList *)me->table[i];
        !           179:            if(l) {
        !           180:                HTList *cur = l;
        !           181:                keynode *kn, *nextkn;
        !           182:                for(kn = (keynode *)HTList_nextObject(cur); kn; kn = nextkn) {
        !           183:                    j = walkFunc(me, kn->key, kn->object);
        !           184:                    if(j == 0)
        !           185:                        return YES;
        !           186:                    nextkn = (keynode *)HTList_nextObject(cur);
        !           187:                    if (j < 0) {
        !           188:                        HTList_removeObject(l, kn);
        !           189:                        me->count--;
        !           190:                    }
        !           191:                }
        !           192:            }
        !           193:        }
        !           194:        return YES;
        !           195:     }
        !           196:     return NO;
        !           197: }
        !           198: 
        !           199: /*
        !           200: (
1.1       frystyk   201:    Extract in a dynamic array all keys of the Hash Table
                    202: )
                    203: */
                    204: 
1.2     ! kahan     205: PUBLIC HTArray * HTHashtable_keys (HTHashtable *me)
1.1       frystyk   206: {
                    207:     if(me) {
                    208:        HTArray *keys = HTArray_new(me->count);
                    209:        int i;
                    210:     
                    211:        for(i = 0; i< me->size; i++) {
                    212:            HTList * l = (HTList *)me->table[i];
                    213:            if (l) {
                    214:                HTList *cur = l;
1.2     ! kahan     215:                keynode *kn;
1.1       frystyk   216:                while ((kn = (keynode *) HTList_nextObject(cur))) {
                    217:                    char * nkey = NULL;
                    218:                    StrAllocCopy(nkey,kn->key);
                    219:                    HTArray_addObject(keys,nkey);
                    220:                }
                    221:            }
                    222:        }
                    223:        return keys;
                    224:     }
                    225:     return NULL;
                    226: }
                    227: 
                    228: /*
                    229: (
                    230:    Print the keys of the Hash Table
                    231: )
                    232: */
                    233: 
                    234: PUBLIC void HTHashtable_print (HTHashtable *me)
                    235: {
                    236:     HTArray *keys = HTHashtable_keys(me);
                    237:     int i;
                    238:     HTPrint("Printing Hash Table of size %d\n", HTArray_size(keys));
                    239:     for(i = 0; i< HTArray_size(keys); i++) {
                    240:        HTPrint("Key %d %s\n",i,HTArray_data(keys)[i]);
                    241:     }
                    242:     for(i = 0; i< HTArray_size(keys); i++) {
                    243:        HT_FREE(HTArray_data(keys)[i]);
                    244:     }
                    245:     HTArray_delete(keys);
                    246: }
                    247: 

Webmaster