From 94a0c32e7354ab44328b1e2d65c5a1283b5b21b8 Mon Sep 17 00:00:00 2001 From: Andrew Kryczka Date: Thu, 26 Jan 2017 10:41:30 -0800 Subject: [PATCH] Fix LRU Ref() for handles with external references only Summary: For case !handle->InCache() && handle->refs >= 1 (the third case mentioned in lru_cache.h), the key was overwritten by Insert(). In this case, the refcount can still be incremented, and the cache handle will never enter LRU list. Fix Ref() logic for this case. Closes https://github.com/facebook/rocksdb/pull/1808 Differential Revision: D4467656 Pulled By: ajkr fbshipit-source-id: c0784d8 --- util/lru_cache.cc | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/util/lru_cache.cc b/util/lru_cache.cc index 83094266c..58ec02fb4 100644 --- a/util/lru_cache.cc +++ b/util/lru_cache.cc @@ -259,14 +259,11 @@ Cache::Handle* LRUCacheShard::Lookup(const Slice& key, uint32_t hash) { bool LRUCacheShard::Ref(Cache::Handle* h) { LRUHandle* handle = reinterpret_cast(h); MutexLock l(&mutex_); - if (handle->InCache()) { - if (handle->refs == 1) { - LRU_Remove(handle); - } - handle->refs++; - return true; + if (handle->InCache() && handle->refs == 1) { + LRU_Remove(handle); } - return false; + handle->refs++; + return true; } void LRUCacheShard::SetHighPriorityPoolRatio(double high_pri_pool_ratio) {