diff options
author | Sage Weil <sage@redhat.com> | 2015-12-18 21:06:14 +0100 |
---|---|---|
committer | Sage Weil <sage@redhat.com> | 2015-12-18 21:06:14 +0100 |
commit | 471164d61a50306d223418ae115b49bdd4da73dd (patch) | |
tree | 577e0f989b0c0a375aebe5783e737ecdbe09418b /src | |
parent | Merge pull request #6968 from xiexingguo/xxg-wip-14118 (diff) | |
parent | common: improve cache efficiency (diff) | |
download | ceph-471164d61a50306d223418ae115b49bdd4da73dd.tar.xz ceph-471164d61a50306d223418ae115b49bdd4da73dd.zip |
Merge pull request #6909 from mslovy/wip-shared-cache
common: improve shared_cache and simple_cache efficiency with hash table
Reviewed-by: Sage Weil <sage@redhat.com>
Diffstat (limited to 'src')
-rw-r--r-- | src/common/shared_cache.hpp | 25 | ||||
-rw-r--r-- | src/common/simple_cache.hpp | 32 |
2 files changed, 34 insertions, 23 deletions
diff --git a/src/common/shared_cache.hpp b/src/common/shared_cache.hpp index c55119c02b7..8ff949084a6 100644 --- a/src/common/shared_cache.hpp +++ b/src/common/shared_cache.hpp @@ -21,8 +21,9 @@ #include <utility> #include "common/Mutex.h" #include "common/Cond.h" +#include "include/unordered_map.h" -template <class K, class V, class C = std::less<K> > +template <class K, class V, class C = std::less<K>, class H = std::hash<K> > class SharedLRU { CephContext *cct; typedef ceph::shared_ptr<V> VPtr; @@ -34,7 +35,7 @@ class SharedLRU { public: int waiting; private: - map<K, typename list<pair<K, VPtr> >::iterator, C> contents; + ceph::unordered_map<K, typename list<pair<K, VPtr> >::iterator, H> contents; list<pair<K, VPtr> > lru; map<K, pair<WeakVPtr, V*>, C> weak_refs; @@ -47,7 +48,7 @@ private: } void lru_remove(const K& key) { - typename map<K, typename list<pair<K, VPtr> >::iterator, C>::iterator i = + typename ceph::unordered_map<K, typename list<pair<K, VPtr> >::iterator, H>::iterator i = contents.find(key); if (i == contents.end()) return; @@ -57,7 +58,7 @@ private: } void lru_add(const K& key, const VPtr& val, list<VPtr> *to_release) { - typename map<K, typename list<pair<K, VPtr> >::iterator, C>::iterator i = + typename ceph::unordered_map<K, typename list<pair<K, VPtr> >::iterator, H>::iterator i = contents.find(key); if (i != contents.end()) { lru.splice(lru.begin(), lru, i->second); @@ -92,7 +93,9 @@ private: public: SharedLRU(CephContext *cct = NULL, size_t max_size = 20) : cct(cct), lock("SharedLRU::lock"), max_size(max_size), - size(0), waiting(0) {} + size(0), waiting(0) { + contents.rehash(max_size); + } ~SharedLRU() { contents.clear(); @@ -161,8 +164,9 @@ public: VPtr val; // release any ref we have after we drop the lock { Mutex::Locker l(lock); - if (weak_refs.count(key)) { - val = weak_refs[key].first.lock(); + typename map<K, pair<WeakVPtr, V*>, C>::iterator i = weak_refs.find(key); + if (i != weak_refs.end()) { + val = i->second.first.lock(); } lru_remove(key); } @@ -172,11 +176,12 @@ public: VPtr val; // release any ref we have after we drop the lock { Mutex::Locker l(lock); - if (weak_refs.count(key)) { - val = weak_refs[key].first.lock(); + typename map<K, pair<WeakVPtr, V*>, C>::iterator i = weak_refs.find(key); + if (i != weak_refs.end()) { + val = i->second.first.lock(); + weak_refs.erase(i); } lru_remove(key); - weak_refs.erase(key); } } diff --git a/src/common/simple_cache.hpp b/src/common/simple_cache.hpp index 8038306adf8..362763253be 100644 --- a/src/common/simple_cache.hpp +++ b/src/common/simple_cache.hpp @@ -20,12 +20,13 @@ #include <memory> #include "common/Mutex.h" #include "common/Cond.h" +#include "include/unordered_map.h" -template <class K, class V, class C = std::less<K> > +template <class K, class V, class C = std::less<K>, class H = std::hash<K> > class SimpleLRU { Mutex lock; size_t max_size; - map<K, typename list<pair<K, V> >::iterator, C> contents; + ceph::unordered_map<K, typename list<pair<K, V> >::iterator, H> contents; list<pair<K, V> > lru; map<K, V, C> pinned; @@ -43,7 +44,9 @@ class SimpleLRU { } public: - SimpleLRU(size_t max_size) : lock("SimpleLRU::lock"), max_size(max_size) {} + SimpleLRU(size_t max_size) : lock("SimpleLRU::lock"), max_size(max_size) { + contents.rehash(max_size); + } void pin(K key, V val) { Mutex::Locker l(lock); @@ -55,16 +58,18 @@ public: for (typename map<K, V, C>::iterator i = pinned.begin(); i != pinned.end() && i->first <= e; pinned.erase(i++)) { - if (!contents.count(i->first)) + typename ceph::unordered_map<K, typename list<pair<K, V> >::iterator, H>::iterator iter = + contents.find(i->first); + if (iter == contents.end()) _add(i->first, i->second); else - lru.splice(lru.begin(), lru, contents[i->first]); + lru.splice(lru.begin(), lru, iter->second); } } void clear(K key) { Mutex::Locker l(lock); - typename map<K, typename list<pair<K, V> >::iterator, C>::iterator i = + typename ceph::unordered_map<K, typename list<pair<K, V> >::iterator, H>::iterator i = contents.find(key); if (i == contents.end()) return; @@ -80,15 +85,16 @@ public: bool lookup(K key, V *out) { Mutex::Locker l(lock); - typename list<pair<K, V> >::iterator loc = contents.count(key) ? - contents[key] : lru.end(); - if (loc != lru.end()) { - *out = loc->second; - lru.splice(lru.begin(), lru, loc); + typename ceph::unordered_map<K, typename list<pair<K, V> >::iterator, H>::iterator i = + contents.find(key); + if (i != contents.end()) { + *out = i->second->second; + lru.splice(lru.begin(), lru, i->second); return true; } - if (pinned.count(key)) { - *out = pinned[key]; + typename map<K, V, C>::iterator i_pinned = pinned.find(key); + if (i_pinned != pinned.end()) { + *out = i_pinned->second; return true; } return false; |