| 625 | } |
| 626 | |
| 627 | int |
| 628 | dir_overwrite(const CacheKey *key, StripeSM *stripe, Dir *dir, Dir *overwrite, bool must_overwrite) |
| 629 | { |
| 630 | ink_assert(stripe->mutex->thread_holding == this_ethread()); |
| 631 | int s = key->slice32(0) % stripe->directory.segments, l; |
| 632 | int bi = key->slice32(1) % stripe->directory.buckets; |
| 633 | Dir *seg = stripe->directory.get_segment(s); |
| 634 | Dir *e = nullptr; |
| 635 | Dir *b = dir_bucket(bi, seg); |
| 636 | unsigned int t = DIR_MASK_TAG(key->slice32(2)); |
| 637 | int res = 1; |
| 638 | #ifdef LOOP_CHECK_MODE |
| 639 | int loop_count = 0; |
| 640 | bool loop_possible = true; |
| 641 | #endif |
| 642 | CHECK_DIR(d); |
| 643 | |
| 644 | ink_assert((unsigned int)dir_approx_size(dir) <= (unsigned int)(MAX_FRAG_SIZE + sizeof(Doc))); // XXX - size should be unsigned |
| 645 | Lagain: |
| 646 | // find entry to overwrite |
| 647 | e = b; |
| 648 | if (dir_offset(e)) { |
| 649 | do { |
| 650 | #ifdef LOOP_CHECK_MODE |
| 651 | loop_count++; |
| 652 | if (loop_count > DIR_LOOP_THRESHOLD && loop_possible) { |
| 653 | if (dir_bucket_loop_fix(b, s, vol)) { |
| 654 | loop_possible = false; |
| 655 | goto Lagain; |
| 656 | } |
| 657 | } |
| 658 | #endif |
| 659 | if (dir_tag(e) == t && dir_offset(e) == dir_offset(overwrite)) { |
| 660 | goto Lfill; |
| 661 | } |
| 662 | e = next_dir(e, seg); |
| 663 | } while (e); |
| 664 | } |
| 665 | if (must_overwrite) { |
| 666 | return 0; |
| 667 | } |
| 668 | res = 0; |
| 669 | // get from this row first |
| 670 | e = b; |
| 671 | if (dir_is_empty(e)) { |
| 672 | ts::Metrics::Gauge::increment(cache_rsb.direntries_used); |
| 673 | ts::Metrics::Gauge::increment(stripe->cache_vol->vol_rsb.direntries_used); |
| 674 | goto Lfill; |
| 675 | } |
| 676 | for (l = 1; l < DIR_DEPTH; l++) { |
| 677 | e = dir_bucket_row(b, l); |
| 678 | if (dir_is_empty(e)) { |
| 679 | unlink_from_freelist(e, s, stripe); |
| 680 | goto Llink; |
| 681 | } |
| 682 | } |
| 683 | // get one from the freelist |
| 684 | e = freelist_pop(s, stripe); |