| 517 | } |
| 518 | |
| 519 | void |
| 520 | build_vol_hash_table(CacheHostRecord *cp) |
| 521 | { |
| 522 | int num_vols = cp->num_vols; |
| 523 | unsigned int *mapping = static_cast<unsigned int *>(ats_malloc(sizeof(unsigned int) * num_vols)); |
| 524 | StripeSM **p = static_cast<StripeSM **>(ats_malloc(sizeof(StripeSM *) * num_vols)); |
| 525 | |
| 526 | memset(mapping, 0, num_vols * sizeof(unsigned int)); |
| 527 | memset(p, 0, num_vols * sizeof(StripeSM *)); |
| 528 | uint64_t total = 0; |
| 529 | int bad_vols = 0; |
| 530 | int map = 0; |
| 531 | uint64_t used = 0; |
| 532 | // initialize number of elements per vol |
| 533 | for (int i = 0; i < num_vols; i++) { |
| 534 | if (DISK_BAD(cp->stripes[i]->disk)) { |
| 535 | bad_vols++; |
| 536 | continue; |
| 537 | } |
| 538 | mapping[map] = i; |
| 539 | p[map++] = cp->stripes[i]; |
| 540 | total += (cp->stripes[i]->len >> STORE_BLOCK_SHIFT); |
| 541 | } |
| 542 | |
| 543 | num_vols -= bad_vols; |
| 544 | |
| 545 | if (!num_vols || !total) { |
| 546 | // all the disks are corrupt, |
| 547 | if (cp->vol_hash_table) { |
| 548 | new_Freer(cp->vol_hash_table, CACHE_MEM_FREE_TIMEOUT); |
| 549 | } |
| 550 | cp->vol_hash_table = nullptr; |
| 551 | ats_free(mapping); |
| 552 | ats_free(p); |
| 553 | return; |
| 554 | } |
| 555 | |
| 556 | unsigned int *forvol = static_cast<unsigned int *>(ats_malloc(sizeof(unsigned int) * num_vols)); |
| 557 | unsigned int *gotvol = static_cast<unsigned int *>(ats_malloc(sizeof(unsigned int) * num_vols)); |
| 558 | unsigned int *rnd = static_cast<unsigned int *>(ats_malloc(sizeof(unsigned int) * num_vols)); |
| 559 | unsigned short *ttable = static_cast<unsigned short *>(ats_malloc(sizeof(unsigned short) * STRIPE_HASH_TABLE_SIZE)); |
| 560 | unsigned short *old_table; |
| 561 | unsigned int *rtable_entries = static_cast<unsigned int *>(ats_malloc(sizeof(unsigned int) * num_vols)); |
| 562 | unsigned int rtable_size = 0; |
| 563 | |
| 564 | // estimate allocation |
| 565 | for (int i = 0; i < num_vols; i++) { |
| 566 | forvol[i] = (STRIPE_HASH_TABLE_SIZE * (p[i]->len >> STORE_BLOCK_SHIFT)) / total; |
| 567 | used += forvol[i]; |
| 568 | rtable_entries[i] = p[i]->len / STRIPE_HASH_ALLOC_SIZE; |
| 569 | rtable_size += rtable_entries[i]; |
| 570 | gotvol[i] = 0; |
| 571 | } |
| 572 | // spread around the excess |
| 573 | int extra = STRIPE_HASH_TABLE_SIZE - used; |
| 574 | for (int i = 0; i < extra; i++) { |
| 575 | forvol[i % num_vols]++; |
| 576 | } |