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<VPtr> to_release;
{
Mutex::Locker l(lock);
- weak_refs.insert(make_pair(key, val));
+ typename map<K, WeakVPtr>::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;
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
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));
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;
}