summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYehuda Sadeh <yehuda@inktank.com>2013-10-04 10:36:13 -0700
committerYehuda Sadeh <yehuda@inktank.com>2013-10-04 10:36:13 -0700
commit6ce762f6412d2855e8e7f328fc75bf3463ba1fae (patch)
tree627a61472833a2c5fd987d930e64d5dd4ede7f12
parent80659ccea852769ddeabb2ecb34bf6328e2428f5 (diff)
downloadceph-6ce762f6412d2855e8e7f328fc75bf3463ba1fae.tar.gz
lru_map: add find_and_update()
A new find_and_update() call to make atomic changes. Signed-off-by: Yehuda Sadeh <yehuda@inktank.com>
-rw-r--r--src/common/lru_map.h50
1 files changed, 40 insertions, 10 deletions
diff --git a/src/common/lru_map.h b/src/common/lru_map.h
index 6e7f7b3786f..62182dd26e8 100644
--- a/src/common/lru_map.h
+++ b/src/common/lru_map.h
@@ -21,41 +21,65 @@ 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>