| 765 | } |
| 766 | |
| 767 | bool LIRSCacheShard::UninitializedToUnprotected(LIRSThreadState* tstate, LIRSHandle* e) { |
| 768 | DCHECK(!e->unprotected_tombstone_list_hook_.is_linked()); |
| 769 | DCHECK(!e->recency_list_hook_.is_linked()); |
| 770 | e->set_state(UNINITIALIZED, UNPROTECTED); |
| 771 | HandleBase* existing = table_.Insert(e); |
| 772 | DCHECK(existing == nullptr); |
| 773 | recency_list_.push_back(*e); |
| 774 | AddToUnprotectedList(e); |
| 775 | // List operations happen before changes to the counts/usage |
| 776 | ++num_unprotected_; |
| 777 | unprotected_usage_ += e->charge(); |
| 778 | // If necessary, evict an entry from the unprotected list |
| 779 | EnforceUnprotectedCapacity(tstate); |
| 780 | // There is exactly one failure case: |
| 781 | // If the new entry is larger than the unprotected capacity, then it will cause all |
| 782 | // unprotected entries to be removed (including itself). |
| 783 | if (e->charge() > unprotected_capacity_) { |
| 784 | DCHECK(e->state() == UNINITIALIZED || e->state() == TOMBSTONE); |
| 785 | DCHECK_EQ(num_unprotected_, 0); |
| 786 | return false; |
| 787 | } |
| 788 | // The entry remains in the cache |
| 789 | DCHECK_EQ(e->state(), UNPROTECTED); |
| 790 | DCHECK(!unprotected_tombstone_list_.empty()); |
| 791 | DCHECK(e->unprotected_tombstone_list_hook_.is_linked()); |
| 792 | return true; |
| 793 | } |
| 794 | |
| 795 | void LIRSCacheShard::ToUninitialized(LIRSThreadState* tstate, LIRSHandle* e, |
| 796 | bool is_trim) { |