Changeset a35b458 in mainline for uspace/lib/c/generic/adt/hash_table.c
- Timestamp:
- 2018-03-02T20:10:49Z (7 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- f1380b7
- Parents:
- 3061bc1
- git-author:
- Jiří Zárevúcky <zarevucky.jiri@…> (2018-02-28 17:38:31)
- git-committer:
- Jiří Zárevúcky <zarevucky.jiri@…> (2018-03-02 20:10:49)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/c/generic/adt/hash_table.c
r3061bc1 ra35b458 96 96 assert(h); 97 97 assert(op && op->hash && op->key_hash && op->key_equal); 98 98 99 99 /* Check for compulsory ops. */ 100 100 if (!op || !op->hash || !op->key_hash || !op->key_equal) 101 101 return false; 102 102 103 103 h->bucket_cnt = round_up_size(init_size); 104 104 105 105 if (!alloc_table(h->bucket_cnt, &h->bucket)) 106 106 return false; 107 107 108 108 h->max_load = (max_load == 0) ? HT_MAX_LOAD : max_load; 109 109 h->item_cnt = 0; … … 115 115 h->op->remove_callback = nop_remove_callback; 116 116 } 117 117 118 118 return true; 119 119 } … … 128 128 assert(h && h->bucket); 129 129 assert(!h->apply_ongoing); 130 130 131 131 clear_items(h); 132 132 133 133 free(h->bucket); 134 134 … … 159 159 assert(h && h->bucket); 160 160 assert(!h->apply_ongoing); 161 161 162 162 clear_items(h); 163 163 164 164 /* Shrink the table to its minimum size if possible. */ 165 165 if (HT_MIN_BUCKETS < h->bucket_cnt) { … … 173 173 if (h->item_cnt == 0) 174 174 return; 175 175 176 176 for (size_t idx = 0; idx < h->bucket_cnt; ++idx) { 177 177 list_foreach_safe(h->bucket[idx], cur, next) { 178 178 assert(cur); 179 179 ht_link_t *cur_link = member_to_inst(cur, ht_link_t, link); 180 180 181 181 list_remove(cur); 182 182 h->op->remove_callback(cur_link); 183 183 } 184 184 } 185 185 186 186 h->item_cnt = 0; 187 187 } … … 197 197 assert(h && h->bucket); 198 198 assert(!h->apply_ongoing); 199 199 200 200 size_t idx = h->op->hash(item) % h->bucket_cnt; 201 201 202 202 list_append(&item->link, &h->bucket[idx]); 203 203 ++h->item_cnt; … … 220 220 assert(h->op && h->op->hash && h->op->equal); 221 221 assert(!h->apply_ongoing); 222 222 223 223 size_t idx = h->op->hash(item) % h->bucket_cnt; 224 224 225 225 /* Check for duplicates. */ 226 226 list_foreach(h->bucket[idx], link, ht_link_t, cur_link) { … … 232 232 return false; 233 233 } 234 234 235 235 list_append(&item->link, &h->bucket[idx]); 236 236 ++h->item_cnt; 237 237 grow_if_needed(h); 238 238 239 239 return true; 240 240 } … … 251 251 { 252 252 assert(h && h->bucket); 253 253 254 254 size_t idx = h->op->key_hash(key) % h->bucket_cnt; 255 255 … … 264 264 } 265 265 } 266 266 267 267 return NULL; 268 268 } … … 306 306 assert(h && h->bucket); 307 307 assert(!h->apply_ongoing); 308 308 309 309 size_t idx = h->op->key_hash(key) % h->bucket_cnt; 310 310 311 311 size_t removed = 0; 312 312 313 313 list_foreach_safe(h->bucket[idx], cur, next) { 314 314 ht_link_t *cur_link = member_to_inst(cur, ht_link_t, link); 315 315 316 316 if (h->op->key_equal(key, cur_link)) { 317 317 ++removed; … … 323 323 h->item_cnt -= removed; 324 324 shrink_if_needed(h); 325 325 326 326 return removed; 327 327 } … … 353 353 assert(f); 354 354 assert(h && h->bucket); 355 355 356 356 if (h->item_cnt == 0) 357 357 return; 358 358 359 359 h->apply_ongoing = true; 360 360 361 361 for (size_t idx = 0; idx < h->bucket_cnt; ++idx) { 362 362 list_foreach_safe(h->bucket[idx], cur, next) { … … 372 372 out: 373 373 h->apply_ongoing = false; 374 374 375 375 shrink_if_needed(h); 376 376 grow_if_needed(h); … … 381 381 { 382 382 size_t rounded_size = HT_MIN_BUCKETS; 383 383 384 384 while (rounded_size < size) { 385 385 rounded_size = 2 * rounded_size + 1; 386 386 } 387 387 388 388 return rounded_size; 389 389 } … … 393 393 { 394 394 assert(pbuckets && HT_MIN_BUCKETS <= bucket_cnt); 395 395 396 396 list_t *buckets = malloc(bucket_cnt * sizeof(list_t)); 397 397 if (!buckets) 398 398 return false; 399 399 400 400 for (size_t i = 0; i < bucket_cnt; i++) 401 401 list_initialize(&buckets[i]); … … 435 435 assert(h && h->bucket); 436 436 assert(HT_MIN_BUCKETS <= new_bucket_cnt); 437 437 438 438 /* We are traversing the table and resizing would mess up the buckets. */ 439 439 if (h->apply_ongoing) 440 440 return; 441 441 442 442 list_t *new_buckets; 443 443 … … 445 445 if (!alloc_table(new_bucket_cnt, &new_buckets)) 446 446 return; 447 447 448 448 if (0 < h->item_cnt) { 449 449 /* Rehash all the items to the new table. */ … … 458 458 } 459 459 } 460 460 461 461 free(h->bucket); 462 462 h->bucket = new_buckets;
Note:
See TracChangeset
for help on using the changeset viewer.