]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
lru_map: add find_and_update()
authorYehuda Sadeh <yehuda@inktank.com>
Fri, 4 Oct 2013 17:36:13 +0000 (10:36 -0700)
committerYehuda Sadeh <yehuda@inktank.com>
Fri, 4 Oct 2013 17:36:13 +0000 (10:36 -0700)
A new find_and_update() call to make atomic changes.

Signed-off-by: Yehuda Sadeh <yehuda@inktank.com>
src/common/lru_map.h

index 6e7f7b3786fa2acb0fc33cd82983493027fa1cf9..62182dd26e83d87cc83268c743521e3f9ec6479e 100644 (file)
@@ -20,42 +20,66 @@ class lru_map {
 
   size_t max;
 
+public:
+  class UpdateContext {
+    public:
+      virtual ~UpdateContext() {}
+      virtual void update(V& v) = 0;
+  };
+
+  bool _find(const K& key, V *value, UpdateContext *ctx);
+  void _add(const K& key, V& value);
+
 public:
   lru_map(int _max) : lock("lru_map"), max(_max) {}
   virtual ~lru_map() {}
 
   bool find(const K& key, V& value);
+  bool find_and_update(const K& key, V *value, UpdateContext *ctx);
   void add(const K& key, V& value);
   void erase(const K& key);
 };
 
 template <class K, class V>
-bool lru_map<K, V>::find(const K& key, V& value)
+bool lru_map<K, V>::_find(const K& key, V *value, UpdateContext *ctx)
 {
-  lock.Lock();
   typename std::map<K, entry>::iterator iter = entries.find(key);
   if (iter == entries.end()) {
-    lock.Unlock();
     return false;
   }
 
   entry& e = iter->second;
   entries_lru.erase(e.lru_iter);
 
-  value = e.value;
+  if (ctx)
+    ctx->update(e.value);
+
+  if (value)
+    *value = e.value;
 
   entries_lru.push_front(key);
   e.lru_iter = entries_lru.begin();
 
-  lock.Unlock();
-
   return true;
 }
 
 template <class K, class V>
-void lru_map<K, V>::add(const K& key, V& value)
+bool lru_map<K, V>::find(const K& key, V& value)
+{
+  Mutex::Locker l(lock);
+  return _find(key, &value, NULL);
+}
+
+template <class K, class V>
+bool lru_map<K, V>::find_and_update(const K& key, V *value, UpdateContext *ctx)
+{
+  Mutex::Locker l(lock);
+  return _find(key, value, ctx);
+}
+
+template <class K, class V>
+void lru_map<K, V>::_add(const K& key, V& value)
 {
-  lock.Lock();
   typename std::map<K, entry>::iterator iter = entries.find(key);
   if (iter != entries.end()) {
     entry& e = iter->second;
@@ -74,8 +98,14 @@ void lru_map<K, V>::add(const K& key, V& value)
     entries.erase(iter);
     entries_lru.pop_back();
   }
-  
-  lock.Unlock();
+}
+
+
+template <class K, class V>
+void lru_map<K, V>::add(const K& key, V& value)
+{
+  Mutex::Locker l(lock);
+  _add(key, value);
 }
 
 template <class K, class V>