| 895 | } |
| 896 | |
| 897 | HandleBase* LIRSCacheShard::Lookup(const Slice& key, uint32_t hash, |
| 898 | bool no_updates) { |
| 899 | DCHECK(initialized_); |
| 900 | LIRSHandle* e; |
| 901 | LIRSThreadState tstate; |
| 902 | { |
| 903 | std::lock_guard<MutexType> l(mutex_); |
| 904 | e = static_cast<LIRSHandle*>(table_.Lookup(key, hash)); |
| 905 | if (e != nullptr) { |
| 906 | CHECK_NE(e->state(), UNINITIALIZED); |
| 907 | // If the handle is a TOMBSTONE, Lookup() should pretend the entry doesn't exist. |
| 908 | // TOMBSTONE has special treatment in Insert(); no other action is necessary here. |
| 909 | if (e->state() == TOMBSTONE) return nullptr; |
| 910 | e->get_reference(); |
| 911 | // If this is a no update lookup, nothing has changed. We can just return the |
| 912 | // entry. |
| 913 | if (no_updates) return e; |
| 914 | switch (e->state()) { |
| 915 | case UNINITIALIZED: |
| 916 | // Needed to keep clang-tidy happy |
| 917 | CHECK(false); |
| 918 | case PROTECTED: |
| 919 | // The PROTECTED entry is in the recency list, and the only action is to make |
| 920 | // it the most recent element in the list. This can result in evictions if it is |
| 921 | // currently the oldest entry. |
| 922 | MoveToRecencyListBack(&tstate, e); |
| 923 | break; |
| 924 | case UNPROTECTED: |
| 925 | if (e->recency_list_hook_.is_linked()) { |
| 926 | // If an UNPROTECTED entry is in the recency list when it is referenced, |
| 927 | // then we know that its new reuse distance is shorter than the last PROTECTED |
| 928 | // entry in the list. So, this entry is upgraded from UNPROTECTED to |
| 929 | // PROTECTED. |
| 930 | UnprotectedToProtected(&tstate, e); |
| 931 | } else { |
| 932 | // If an UNPROTECTED entry is not on the recency list, then its new reuse |
| 933 | // distance is longer than any of the PROTECTED entries. So, it remains |
| 934 | // an UNPROTECTED entry, but it should be added back to the recency list and |
| 935 | // readded as the most recent entry on the unprotected list. |
| 936 | DCHECK_GT(num_unprotected_, 0); |
| 937 | MoveToRecencyListBack(&tstate, e, false); |
| 938 | if (num_unprotected_ != 1) { |
| 939 | RemoveFromUnprotectedList(e); |
| 940 | AddToUnprotectedList(e); |
| 941 | } |
| 942 | } |
| 943 | break; |
| 944 | default: |
| 945 | CHECK(false) << "Unexpected state for Lookup: " << e->state(); |
| 946 | } |
| 947 | } |
| 948 | } |
| 949 | |
| 950 | // This happens when not holding the mutex for performance reasons. |
| 951 | CleanupThreadState(&tstate); |
| 952 | |
| 953 | return e; |
| 954 | } |
nothing calls this directly
no test coverage detected