IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Changeset 173


Ignore:
Timestamp:
Mar 9, 2004, 3:00:45 PM (22 years ago)
Author:
rhl
Message:

1/ Add psHashRemove
2/ Rename New/Del to Alloc/Free

Location:
trunk/archive/pslib/src/Utils
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/archive/pslib/src/Utils/hash.c

    r145 r173  
    3131 * Con/Destruct buckets
    3232 */
    33 static HashBucket *hashBucketNew(const char *key,
    34                                  void *data,
    35                                  HashBucket *next)
     33static HashBucket *hashBucketAlloc(const char *key,
     34                                   void *data,
     35                                   HashBucket *next)
    3636{
    3737    HashBucket *bucket = psAlloc(sizeof(HashBucket));
     
    4444}
    4545
    46 static void hashBucketDel(
     46static void hashBucketFree(
    4747    HashBucket *bucket,                 // bucket to free
    48     void (*itemDel)(void *item))        // how to free hashed data;
     48    void (*itemFree)(void *item))       // how to free hashed data;
    4949                                        // or NULL
    5050{
     
    5656    psMemDecrRefCounter(bucket->data);
    5757   
    58     if (itemDel != NULL) {
    59         itemDel(bucket->data);
     58    if (itemFree != NULL) {
     59        itemFree(bucket->data);
    6060    }
    6161   
     
    6767 * Con/Destruct psHash tables
    6868 */
    69 psHash *psHashNew(int nbucket)          // initial number of buckets
     69psHash *psHashAlloc(int nbucket)        // initial number of buckets
    7070{
    7171    psHash *table = psAlloc(sizeof(psHash));
     
    8282}
    8383
    84 void psHashDel(psHash *table,           // hash table to be freed
    85                void (*itemDel)(void *item)) // how to free hashed data; or NULL
     84void psHashFree(psHash *table,          // hash table to be freed
     85                void (*itemFree)(void *item)) // how to free hashed data; or NULL
    8686{
    8787    if (table == NULL) {
     
    9696            while (ptr != NULL) {
    9797                HashBucket *tmp = ptr->next;
    98                 hashBucketDel(ptr, itemDel);
     98                hashBucketFree(ptr, itemFree);
    9999                ptr = tmp;
    100100            }
     
    108108/*****************************************************************************/
    109109/*
    110  * Here's the routine to do the work of insertion/retrieval.
     110 * Here's the routine to do the work of insertion/retrieval/removal
    111111 *
    112  * We need itemDel if the key is already in use and we're inserting
     112 * We need itemFree if the key is already in use and we're inserting
    113113 *
    114114 * N.b. this is NOT a good hash function! See Knuth for some better ones
     
    118118    const char *key,                    // key to use
    119119    void *data,                         // data to insert,
    120                                         // or (if NULL) retrieve
    121     void (*itemDel)(void *item))        // how to free hashed data
     120                                        // or (if NULL) retrieve/remove
     121    int remove,                         // remove the item from the list?
     122    void (*itemFree)(void *item))       // how to free hashed data
    122123                                        // or NULL
    123124{
     
    134135     * We've found the correct hash bucket, now we need to know what to do
    135136     */
    136     if (data == NULL) {                 // retrieve
    137         while (ptr != NULL) {
    138             if (strcmp(key, ptr->key) == 0) { // found it!
    139                 return ptr->data;
    140             }
    141 
    142             ptr = ptr->next;
     137    if (data == NULL) {                 // retrieve/remove
     138        if (remove) {
     139            HashBucket *optr = ptr;
     140            while (ptr != NULL) {
     141                if (strcmp(key, ptr->key) == 0) { // found it!
     142                    void *data = ptr->data;
     143                    optr->next = ptr->next;
     144
     145                    if (ptr == table->buckets[hash]) {
     146                        table->buckets[hash] = ptr->next;
     147                    }
     148
     149                    psFree(ptr->key);
     150                    psFree(ptr);
     151
     152                    return psMemDecrRefCounter(data); // return data
     153                }
     154
     155                optr = ptr;
     156                ptr = ptr->next;
     157            }
     158        } else {
     159            while (ptr != NULL) {
     160                if (strcmp(key, ptr->key) == 0) { // found it!
     161                    return ptr->data;
     162                }
     163               
     164                ptr = ptr->next;
     165            }
    143166        }
    144167
     
    147170        while (ptr != NULL) {
    148171            if (strcmp(key, ptr->key) == 0) { // found it!
    149                 if (itemDel == NULL) {
     172                if (itemFree == NULL) {
    150173                    return NULL;        // can't insert
    151174                }                       
     
    154177                        key);
    155178
    156                 itemDel(psMemDecrRefCounter(ptr->data));
     179                itemFree(psMemDecrRefCounter(ptr->data));
    157180                ptr->data = psMemIncrRefCounter(data);
    158181
     
    163186         * Not found, so insert at the front of the list
    164187         */
    165         table->buckets[hash] = hashBucketNew(key, data, table->buckets[hash]);
     188        table->buckets[hash] = hashBucketAlloc(key, data, table->buckets[hash]);
    166189
    167190        return data;
     
    176199                   const char *key,     // key to use
    177200                   void *data,          // data to insert
    178                    void (*itemDel)(void *item)) // how to free hashed data;
     201                   void (*itemFree)(void *item)) // how to free hashed data;
    179202                                        // or NULL
    180203{
    181     return doHashWork(table, key, data, itemDel);
     204    return doHashWork(table, key, data, 0, itemFree);
    182205}
    183206
     
    189212                   const char *key)     // key to lookup
    190213{
    191     return doHashWork(table, key, NULL, NULL);
     214    return doHashWork(table, key, NULL, 0, NULL);
     215}
     216
     217/*****************************************************************************/
     218/*
     219 * Remove and return a value from a hash table
     220 */
     221void *psHashRemove(psHash *table,       // table to lookup key in
     222                   const char *key)     // key to lookup
     223{
     224    return doHashWork(table, key, NULL, 1, NULL);
    192225}
    193226
     
    196229
    197230typedef struct { char *name; } ID;
    198 static ID *IdNew(const char *name)
     231static ID *IdAlloc(const char *name)
    199232{
    200233    ID *id = psAlloc(sizeof(ID));
     
    204237}
    205238
    206 static void IdDel(ID *id) {
     239static void IdFree(ID *id)
     240{
    207241    if (psMemGetRefCounter(id) > 1) {
    208242        psMemDecrRefCounter(id);
     
    219253    long memId0 = psMemGetId();
    220254
    221     psHash *hash = psHashNew(16);
    222 
    223     psHashInsert(hash, "Lynda", IdNew("Lee"), (void (*)(void *))IdDel);
    224     psHashInsert(hash, "Lynda", IdNew("Lee"), (void (*)(void *))IdDel);
    225     psHashInsert(hash, "Robert", IdNew("Lupton"), (void (*)(void *))IdDel);
    226     psHashInsert(hash, "Robert", IdNew("the Good"), (void (*)(void *))IdDel);
     255    psHash *hash = psHashAlloc(16);
     256
     257    psHashInsert(hash, "Lynda", IdAlloc("Lee"), (void (*)(void *))IdFree);
     258    psHashInsert(hash, "Lynda", IdAlloc("Lee"), (void (*)(void *))IdFree);
     259    psHashInsert(hash, "Robert", IdAlloc("Lupton"), (void (*)(void *))IdFree);
     260    psHashInsert(hash, "Robert", IdAlloc("the Good"), (void (*)(void *))IdFree);
    227261
    228262    char *names[] = {"Robert", "Lynda", "Rowan", NULL};
     
    233267    }
    234268
    235     psHashDel(hash, (void (*)(void *))IdDel);
     269    psHashFree(hash, (void (*)(void *))IdFree);
    236270    /*
    237271     * Check for memory leaks
  • trunk/archive/pslib/src/Utils/psHash.h

    r141 r173  
    44typedef struct HashTable psHash;
    55
    6 psHash *psHashNew(int nbucket);         // initial number of buckets
    7 void psHashDel(psHash *table,           // hash table to be freed
    8                void (*itemDel)(void *item)); // how to free hashed data;
     6psHash *psHashAlloc(int nbucket);       // initial number of buckets
     7void psHashFree(psHash *table,          // hash table to be freed
     8                void (*itemFree)(void *item)); // how to free hashed data;
    99                                        // or NULL
    1010
     
    1212                   const char *key,     // key to use
    1313                   void *data,          // data to insert
    14                    void (*itemDel)(void *item)); // how to free hashed data;
     14                   void (*itemFree)(void *item)); // how to free hashed data;
    1515                                        // or NULL
    1616void *psHashLookup(psHash *table,       // table to lookup key in
    1717                   const char *key);    // key to lookup
    1818
     19void *psHashRemove(psHash *table,       // table to lookup key in
     20                   const char *key);    // key to lookup
    1921#endif
Note: See TracChangeset for help on using the changeset viewer.