| 575 | } |
| 576 | |
| 577 | void LIRSCacheShard::EnforceTombstoneLimit(LIRSThreadState* tstate) { |
| 578 | // If there are a large number of entries that haven't been seen before, the number |
| 579 | // of tombstones can grow without bound. This enforces an upper bound on the total |
| 580 | // number of tombstones to limit the metadata size. This is defined as a multiple of |
| 581 | // the total number of entries in the cache. |
| 582 | // TODO: It would help performance to enforce this with some inexactness (i.e. batch |
| 583 | // the removals). |
| 584 | size_t num_elems = num_unprotected_ + num_protected_; |
| 585 | size_t tombstone_limit = |
| 586 | static_cast<size_t>(static_cast<double>(num_elems) * FLAGS_lirs_tombstone_multiple); |
| 587 | if (num_tombstones_ <= tombstone_limit) return; |
| 588 | // Remove the oldest TOMBSTONE entries from the front of unprotected_tombstone_list_ |
| 589 | // until we are back under the limit. |
| 590 | auto it = unprotected_tombstone_list_.begin(); |
| 591 | while (num_tombstones_ > tombstone_limit) { |
| 592 | LIRSHandle* e = &*it; |
| 593 | it = unprotected_tombstone_list_.erase(it); |
| 594 | DCHECK_EQ(e->state(), TOMBSTONE); |
| 595 | // This will remove the entry from the recency_list_. |
| 596 | ToUninitialized(tstate, e); |
| 597 | } |
| 598 | } |
| 599 | |
| 600 | void LIRSCacheShard::EnforceUnprotectedCapacity(LIRSThreadState* tstate) { |
| 601 | while (unprotected_usage_ > unprotected_capacity_) { |