lruhash.c (302408) | lruhash.c (356345) |
---|---|
1/* 2 * util/storage/lruhash.c - hashtable, hash function, LRU keeping. 3 * 4 * Copyright (c) 2007, NLnet Labs. All rights reserved. 5 * 6 * This software is open source. 7 * 8 * Redistribution and use in source and binary forms, with or without --- 45 unchanged lines hidden (view full) --- 54 for(i=0; i<size; i++) { 55 lock_quick_init(&array[i].lock); 56 lock_protect(&array[i].lock, &array[i], 57 sizeof(struct lruhash_bin)); 58 } 59} 60 61struct lruhash* | 1/* 2 * util/storage/lruhash.c - hashtable, hash function, LRU keeping. 3 * 4 * Copyright (c) 2007, NLnet Labs. All rights reserved. 5 * 6 * This software is open source. 7 * 8 * Redistribution and use in source and binary forms, with or without --- 45 unchanged lines hidden (view full) --- 54 for(i=0; i<size; i++) { 55 lock_quick_init(&array[i].lock); 56 lock_protect(&array[i].lock, &array[i], 57 sizeof(struct lruhash_bin)); 58 } 59} 60 61struct lruhash* |
62lruhash_create(size_t start_size, size_t maxmem, lruhash_sizefunc_t sizefunc, 63 lruhash_compfunc_t compfunc, lruhash_delkeyfunc_t delkeyfunc, 64 lruhash_deldatafunc_t deldatafunc, void* arg) | 62lruhash_create(size_t start_size, size_t maxmem, 63 lruhash_sizefunc_type sizefunc, lruhash_compfunc_type compfunc, 64 lruhash_delkeyfunc_type delkeyfunc, 65 lruhash_deldatafunc_type deldatafunc, void* arg) |
65{ 66 struct lruhash* table = (struct lruhash*)calloc(1, 67 sizeof(struct lruhash)); 68 if(!table) 69 return NULL; 70 lock_quick_init(&table->lock); 71 table->sizefunc = sizefunc; 72 table->compfunc = compfunc; --- 137 unchanged lines hidden (view full) --- 210 (*table->markdelfunc)(d->key); 211 lock_rw_unlock(&d->lock); 212 lock_quick_unlock(&bin->lock); 213 } 214} 215 216struct lruhash_entry* 217bin_find_entry(struct lruhash* table, | 66{ 67 struct lruhash* table = (struct lruhash*)calloc(1, 68 sizeof(struct lruhash)); 69 if(!table) 70 return NULL; 71 lock_quick_init(&table->lock); 72 table->sizefunc = sizefunc; 73 table->compfunc = compfunc; --- 137 unchanged lines hidden (view full) --- 211 (*table->markdelfunc)(d->key); 212 lock_rw_unlock(&d->lock); 213 lock_quick_unlock(&bin->lock); 214 } 215} 216 217struct lruhash_entry* 218bin_find_entry(struct lruhash* table, |
218 struct lruhash_bin* bin, hashvalue_t hash, void* key) | 219 struct lruhash_bin* bin, hashvalue_type hash, void* key) |
219{ 220 struct lruhash_entry* p = bin->overflow_list; 221 while(p) { 222 if(p->hash == hash && table->compfunc(p->key, key) == 0) 223 return p; 224 p = p->overflow_next; 225 } 226 return NULL; --- 64 unchanged lines hidden (view full) --- 291 return; /* nothing to do */ 292 /* remove from current lru position */ 293 lru_remove(table, entry); 294 /* add at front */ 295 lru_front(table, entry); 296} 297 298void | 220{ 221 struct lruhash_entry* p = bin->overflow_list; 222 while(p) { 223 if(p->hash == hash && table->compfunc(p->key, key) == 0) 224 return p; 225 p = p->overflow_next; 226 } 227 return NULL; --- 64 unchanged lines hidden (view full) --- 292 return; /* nothing to do */ 293 /* remove from current lru position */ 294 lru_remove(table, entry); 295 /* add at front */ 296 lru_front(table, entry); 297} 298 299void |
299lruhash_insert(struct lruhash* table, hashvalue_t hash, | 300lruhash_insert(struct lruhash* table, hashvalue_type hash, |
300 struct lruhash_entry* entry, void* data, void* cb_arg) 301{ 302 struct lruhash_bin* bin; 303 struct lruhash_entry* found, *reclaimlist=NULL; 304 size_t need_size; 305 fptr_ok(fptr_whitelist_hash_sizefunc(table->sizefunc)); 306 fptr_ok(fptr_whitelist_hash_delkeyfunc(table->delkeyfunc)); 307 fptr_ok(fptr_whitelist_hash_deldatafunc(table->deldatafunc)); --- 39 unchanged lines hidden (view full) --- 347 void* d = reclaimlist->data; 348 (*table->delkeyfunc)(reclaimlist->key, cb_arg); 349 (*table->deldatafunc)(d, cb_arg); 350 reclaimlist = n; 351 } 352} 353 354struct lruhash_entry* | 301 struct lruhash_entry* entry, void* data, void* cb_arg) 302{ 303 struct lruhash_bin* bin; 304 struct lruhash_entry* found, *reclaimlist=NULL; 305 size_t need_size; 306 fptr_ok(fptr_whitelist_hash_sizefunc(table->sizefunc)); 307 fptr_ok(fptr_whitelist_hash_delkeyfunc(table->delkeyfunc)); 308 fptr_ok(fptr_whitelist_hash_deldatafunc(table->deldatafunc)); --- 39 unchanged lines hidden (view full) --- 348 void* d = reclaimlist->data; 349 (*table->delkeyfunc)(reclaimlist->key, cb_arg); 350 (*table->deldatafunc)(d, cb_arg); 351 reclaimlist = n; 352 } 353} 354 355struct lruhash_entry* |
355lruhash_lookup(struct lruhash* table, hashvalue_t hash, void* key, int wr) | 356lruhash_lookup(struct lruhash* table, hashvalue_type hash, void* key, int wr) |
356{ 357 struct lruhash_entry* entry; 358 struct lruhash_bin* bin; 359 fptr_ok(fptr_whitelist_hash_compfunc(table->compfunc)); 360 361 lock_quick_lock(&table->lock); 362 bin = &table->array[hash & table->size_mask]; 363 lock_quick_lock(&bin->lock); --- 5 unchanged lines hidden (view full) --- 369 if(wr) { lock_rw_wrlock(&entry->lock); } 370 else { lock_rw_rdlock(&entry->lock); } 371 } 372 lock_quick_unlock(&bin->lock); 373 return entry; 374} 375 376void | 357{ 358 struct lruhash_entry* entry; 359 struct lruhash_bin* bin; 360 fptr_ok(fptr_whitelist_hash_compfunc(table->compfunc)); 361 362 lock_quick_lock(&table->lock); 363 bin = &table->array[hash & table->size_mask]; 364 lock_quick_lock(&bin->lock); --- 5 unchanged lines hidden (view full) --- 370 if(wr) { lock_rw_wrlock(&entry->lock); } 371 else { lock_rw_rdlock(&entry->lock); } 372 } 373 lock_quick_unlock(&bin->lock); 374 return entry; 375} 376 377void |
377lruhash_remove(struct lruhash* table, hashvalue_t hash, void* key) | 378lruhash_remove(struct lruhash* table, hashvalue_type hash, void* key) |
378{ 379 struct lruhash_entry* entry; 380 struct lruhash_bin* bin; 381 void *d; 382 fptr_ok(fptr_whitelist_hash_sizefunc(table->sizefunc)); 383 fptr_ok(fptr_whitelist_hash_delkeyfunc(table->delkeyfunc)); 384 fptr_ok(fptr_whitelist_hash_deldatafunc(table->deldatafunc)); 385 fptr_ok(fptr_whitelist_hash_compfunc(table->compfunc)); --- 121 unchanged lines hidden (view full) --- 507 lock_get_mem(&table->array[0].lock)); 508#endif 509 lock_quick_unlock(&table->lock); 510 s += lock_get_mem(&table->lock); 511 return s; 512} 513 514void | 379{ 380 struct lruhash_entry* entry; 381 struct lruhash_bin* bin; 382 void *d; 383 fptr_ok(fptr_whitelist_hash_sizefunc(table->sizefunc)); 384 fptr_ok(fptr_whitelist_hash_delkeyfunc(table->delkeyfunc)); 385 fptr_ok(fptr_whitelist_hash_deldatafunc(table->deldatafunc)); 386 fptr_ok(fptr_whitelist_hash_compfunc(table->compfunc)); --- 121 unchanged lines hidden (view full) --- 508 lock_get_mem(&table->array[0].lock)); 509#endif 510 lock_quick_unlock(&table->lock); 511 s += lock_get_mem(&table->lock); 512 return s; 513} 514 515void |
515lruhash_setmarkdel(struct lruhash* table, lruhash_markdelfunc_t md) | 516lruhash_setmarkdel(struct lruhash* table, lruhash_markdelfunc_type md) |
516{ 517 lock_quick_lock(&table->lock); 518 table->markdelfunc = md; 519 lock_quick_unlock(&table->lock); 520} 521 522void 523lruhash_traverse(struct lruhash* h, int wr, --- 13 unchanged lines hidden (view full) --- 537 } 538 (*func)(e, arg); 539 lock_rw_unlock(&e->lock); 540 } 541 lock_quick_unlock(&h->array[i].lock); 542 } 543 lock_quick_unlock(&h->lock); 544} | 517{ 518 lock_quick_lock(&table->lock); 519 table->markdelfunc = md; 520 lock_quick_unlock(&table->lock); 521} 522 523void 524lruhash_traverse(struct lruhash* h, int wr, --- 13 unchanged lines hidden (view full) --- 538 } 539 (*func)(e, arg); 540 lock_rw_unlock(&e->lock); 541 } 542 lock_quick_unlock(&h->array[i].lock); 543 } 544 lock_quick_unlock(&h->lock); 545} |
546 547/* 548 * Demote: the opposite of touch, move an entry to the bottom 549 * of the LRU pile. 550 */ 551 552void 553lru_demote(struct lruhash* table, struct lruhash_entry* entry) 554{ 555 log_assert(table && entry); 556 if (entry == table->lru_end) 557 return; /* nothing to do */ 558 /* remove from current lru position */ 559 lru_remove(table, entry); 560 /* add at end */ 561 entry->lru_next = NULL; 562 entry->lru_prev = table->lru_end; 563 564 if (table->lru_end == NULL) 565 { 566 table->lru_start = entry; 567 } 568 else 569 { 570 table->lru_end->lru_next = entry; 571 } 572 table->lru_end = entry; 573} 574 575struct lruhash_entry* 576lruhash_insert_or_retrieve(struct lruhash* table, hashvalue_type hash, 577 struct lruhash_entry* entry, void* data, void* cb_arg) 578{ 579 struct lruhash_bin* bin; 580 struct lruhash_entry* found, *reclaimlist = NULL; 581 size_t need_size; 582 fptr_ok(fptr_whitelist_hash_sizefunc(table->sizefunc)); 583 fptr_ok(fptr_whitelist_hash_delkeyfunc(table->delkeyfunc)); 584 fptr_ok(fptr_whitelist_hash_deldatafunc(table->deldatafunc)); 585 fptr_ok(fptr_whitelist_hash_compfunc(table->compfunc)); 586 fptr_ok(fptr_whitelist_hash_markdelfunc(table->markdelfunc)); 587 need_size = table->sizefunc(entry->key, data); 588 if (cb_arg == NULL) cb_arg = table->cb_arg; 589 590 /* find bin */ 591 lock_quick_lock(&table->lock); 592 bin = &table->array[hash & table->size_mask]; 593 lock_quick_lock(&bin->lock); 594 595 /* see if entry exists already */ 596 if ((found = bin_find_entry(table, bin, hash, entry->key)) != NULL) { 597 /* if so: keep the existing data - acquire a writelock */ 598 lock_rw_wrlock(&found->lock); 599 } 600 else 601 { 602 /* if not: add to bin */ 603 entry->overflow_next = bin->overflow_list; 604 bin->overflow_list = entry; 605 lru_front(table, entry); 606 table->num++; 607 table->space_used += need_size; 608 /* return the entry that was presented, and lock it */ 609 found = entry; 610 lock_rw_wrlock(&found->lock); 611 } 612 lock_quick_unlock(&bin->lock); 613 if (table->space_used > table->space_max) 614 reclaim_space(table, &reclaimlist); 615 if (table->num >= table->size) 616 table_grow(table); 617 lock_quick_unlock(&table->lock); 618 619 /* finish reclaim if any (outside of critical region) */ 620 while (reclaimlist) { 621 struct lruhash_entry* n = reclaimlist->overflow_next; 622 void* d = reclaimlist->data; 623 (*table->delkeyfunc)(reclaimlist->key, cb_arg); 624 (*table->deldatafunc)(d, cb_arg); 625 reclaimlist = n; 626 } 627 628 /* return the entry that was selected */ 629 return found; 630} 631 |
|