From 4c2828ed1492beb0fa2c4ec2997dd6b282f2a0e9 Mon Sep 17 00:00:00 2001 From: Greg Farnum Date: Thu, 30 Jan 2014 14:21:52 -0800 Subject: [PATCH] shared_cache: expose prior existence when inserting an element The LRU now handles you attempting to insert multiple values for the same key, by telling you that you've done so and returning the existing value before it manages to muck up existing data. The param 'existed' is not mandatory, default value is NULL. Signed-off-by: Greg Farnum Signed-off-by: Somnath Roy --- src/common/shared_cache.hpp | 27 +++++++++++++++++++++++++-- src/os/FDCache.h | 4 ++-- src/os/FileStore.cc | 4 +++- src/osd/OSD.cc | 6 +++++- 4 files changed, 35 insertions(+), 6 deletions(-) diff --git a/src/common/shared_cache.hpp b/src/common/shared_cache.hpp index 2f5f05a0d6449..6e05a6880a30c 100644 --- a/src/common/shared_cache.hpp +++ b/src/common/shared_cache.hpp @@ -169,12 +169,35 @@ public: return val; } - VPtr add(K key, V *value) { + /*** + * Inserts a key if not present, or bumps it to the front of the LRU if + * it is, and then gives you a reference to the value. If the key already + * existed, you are responsible for deleting the new value you tried to + * insert. + * + * @param key The key to insert + * @param value The value that goes with the key + * @param existed Set to true if the value was already in the + * map, false otherwise + * @return A reference to the map's value for the given key + */ + VPtr add(K key, V *value, bool *existed = NULL) { VPtr val(value, Cleanup(this, key)); list to_release; { Mutex::Locker l(lock); - weak_refs.insert(make_pair(key, val)); + typename map::iterator actual = weak_refs.lower_bound(key); + if (actual != weak_refs.end() && actual->first == key) { + if (existed) + *existed = true; + + return actual->second.lock(); + } + + if (existed) + *existed = false; + + weak_refs.insert(actual, make_pair(key, val)); lru_add(key, val, &to_release); } return val; diff --git a/src/os/FDCache.h b/src/os/FDCache.h index ba11e12073994..712355b48192b 100644 --- a/src/os/FDCache.h +++ b/src/os/FDCache.h @@ -67,8 +67,8 @@ public: return registry.lookup(hoid); } - FDRef add(const ghobject_t &hoid, int fd) { - return registry.add(hoid, new FD(fd)); + FDRef add(const ghobject_t &hoid, int fd, bool *existed) { + return registry.add(hoid, new FD(fd), existed); } /// clear cached fd for hoid, subsequent lookups will get an empty FD diff --git a/src/os/FileStore.cc b/src/os/FileStore.cc index 165412dfab362..b3f06f20d6315 100644 --- a/src/os/FileStore.cc +++ b/src/os/FileStore.cc @@ -293,7 +293,9 @@ int FileStore::lfn_open(coll_t cid, VOID_TEMP_FAILURE_RETRY(::close(fd)); return 0; } else { - *outfd = fdcache.add(oid, fd); + bool existed; + *outfd = fdcache.add(oid, fd, &existed); + assert(!existed); } } else { *outfd = FDRef(new FDCache::FD(fd)); diff --git a/src/osd/OSD.cc b/src/osd/OSD.cc index a6568d0526e72..070c473da3a55 100644 --- a/src/osd/OSD.cc +++ b/src/osd/OSD.cc @@ -1154,7 +1154,11 @@ OSDMapRef OSDService::_add_map(OSDMap *o) OSDMap::dedup(for_dedup.get(), o); } } - OSDMapRef l = map_cache.add(e, o); + bool existed; + OSDMapRef l = map_cache.add(e, o, &existed); + if (existed) { + delete o; + } return l; } -- 2.39.5