Changeset 875 for trunk/psLib/src/sysUtils/psHash.c
- Timestamp:
- Jun 4, 2004, 1:46:11 PM (22 years ago)
- File:
-
- 1 edited
-
trunk/psLib/src/sysUtils/psHash.c (modified) (9 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/psLib/src/sysUtils/psHash.c
r562 r875 45 45 } 46 46 47 if (bucket->next != NULL) 48 { 49 hashBucketFree(bucket, itemFree); 50 } 51 47 52 psFree(bucket->key); 48 53 psMemDecrRefCounter(bucket->data); … … 88 93 * Release data interned on the list, and delete the buckets 89 94 */ 95 90 96 for (int i = 0; i < table->nbucket; i++) 91 97 { … … 108 114 109 115 We need itemFree if the key is already in use and we're inserting 110 111 N.b. this is NOT a good hash function! See Knuth for some better ones 112 *****************************************************************************/ 116 *****************************************************************************/ 113 117 static void *doHashWork(psHash *table, // table to insert in 114 118 const char *key, // key to use 115 void *data, // data to insert, 116 // or (if NULL) retrieve/remove 119 void *data, // data to insert, or (if NULL) retrieve/remove 117 120 int remove 118 121 , // remove the item from the list? 119 void (*itemFree)(void *item)) 120 // how to free hashed data 121 { 122 long int hash = 1; 123 122 void (*itemFree)(void *item)) // how to free hashed data 123 { 124 long int hash = 1; // This will contained an integer value 125 // "hashed" from the key. 126 psHashBucket *ptr = NULL; // Used to retrieve the requested hash 127 // bucket. 128 psHashBucket *optr = NULL; 129 130 // NOTE: this is NOT a good hash function! See Knuth. 131 // 124 132 for (int i = 0, len = strlen(key); i < len; i++) { 125 133 hash = (hash << 1) ^ key[i]; 126 134 } 127 128 135 hash &= (table->nbucket - 1); 129 136 130 psHashBucket *ptr = table->buckets[hash]; 131 132 // We've found the correct hash bucket, now we need to know what to do 133 if (data == NULL) { // retrieve/remove 137 ptr = table->buckets[hash]; 138 139 // We've found the correct hash bucket, now we need to know what to do. 140 // If the data parameter is NULL, then, by definition, this is a retrieve 141 // or a remove operation on the hash table. 142 if (data == NULL) { 134 143 if (remove 135 144 ) { 136 psHashBucket *optr = ptr; 145 // We search through the linked list for this bucket in 146 // the hash table and look for an entry for this key. 147 148 optr = ptr; 137 149 while (ptr != NULL) { 138 if (strcmp(key, ptr->key) == 0) { // found it!150 if (strcmp(key, ptr->key) == 0) { 139 151 void *data = ptr->data; 140 152 optr->next = ptr->next; … … 143 155 table->buckets[hash] = ptr->next; 144 156 } 157 158 // if (itemFree != NULL) { 159 // printf("Calling itemFree()\n"); 160 // itemFree(psMemDecrRefCounter(ptr->data)); 161 // printf("Called itemFree()\n"); 162 // } 145 163 146 164 psFree(ptr->key); … … 159 177 return ptr->data; 160 178 } 161 162 179 ptr = ptr->next; 163 180 } … … 165 182 166 183 return NULL; // not in hash 167 } else { // insert 184 } else { 185 // We get here if this procedure was called with non-NULL data. 186 // Therefore, we should insert that data into the hash table. 187 // First, we search through the linked list for this bucket in 188 // the hash table and look for a duplicate entry for this key. 189 190 168 191 while (ptr != NULL) { 169 if (strcmp(key, ptr->key) == 0) { // found it! 192 if (strcmp(key, ptr->key) == 0) { 193 // We have found this key in the hash table. 170 194 if (itemFree == NULL) { 171 return NULL; // can't insert 195 // The user has not supplied a routine, so we cannot 196 // insert the data. 197 return NULL; 172 198 } 173 199 … … 182 208 } 183 209 184 // Not found, so insert at the front of the list 185 table->buckets[hash] = hashBucketAlloc(key, data, table->buckets[hash]); 210 // We did not found key in the linked list for this bucket of the hash 211 // table. So, we insert this data at the head of that linked list. 212 table->buckets[hash] = hashBucketAlloc(key, 213 data, 214 table->buckets[hash]); 186 215 187 216 return data; … … 197 226 void (*itemFree)(void *item)) // how to free hashed data; 198 227 { 199 return doHashWork(table, key, data, 0, itemFree); 228 void *tmp; 229 230 tmp = doHashWork(table, key, data, 0, itemFree); 231 return(tmp); 200 232 } 201 233 … … 213 245 *****************************************************************************/ 214 246 void *psHashRemove(psHash *table, // table to lookup key in 215 const char *key) // key to lookup 216 { 217 return doHashWork(table, key, NULL, 1, NULL); 218 } 247 const char *key, // key to lookup 248 void (*itemFree)(void *item)) // how to free hashed data; 249 { 250 return doHashWork(table, key, NULL, 1, itemFree); 251 }
Note:
See TracChangeset
for help on using the changeset viewer.
