1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
4 * Ceph - scalable distributed file system
6 * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net>
8 * This is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License version 2.1, as published by the Free Software
11 * Foundation. See file COPYING.
15 #ifndef CEPH_SHAREDPTR_REGISTRY_H
16 #define CEPH_SHAREDPTR_REGISTRY_H
20 #include "common/Mutex.h"
21 #include "common/Cond.h"
24 * Provides a registry of shared_ptr<V> indexed by K while
25 * the references are alive.
27 template <class K, class V, class C = std::less<K> >
28 class SharedPtrRegistry {
30 typedef ceph::shared_ptr<V> VPtr;
31 typedef ceph::weak_ptr<V> WeakVPtr;
36 map<K, pair<WeakVPtr, V*>, C> contents;
39 SharedPtrRegistry<K,V,C> *parent;
42 OnRemoval(SharedPtrRegistry<K,V,C> *parent, K key) :
43 parent(parent), key(key) {}
44 void operator()(V *to_remove) {
46 Mutex::Locker l(parent->lock);
47 typename map<K, pair<WeakVPtr, V*>, C>::iterator i =
48 parent->contents.find(key);
49 if (i != parent->contents.end() &&
50 i->second.second == to_remove) {
51 parent->contents.erase(i);
52 parent->cond.Signal();
58 friend class OnRemoval;
63 lock("SharedPtrRegistry::lock")
67 Mutex::Locker l(lock);
68 return contents.empty();
71 bool get_next(const K &key, pair<K, VPtr> *next) {
74 Mutex::Locker l(lock);
76 typename map<K, pair<WeakVPtr, V*>, C>::iterator i =
77 contents.upper_bound(key);
78 while (i != contents.end() &&
79 !(next_val = i->second.first.lock()))
81 if (i == contents.end())
84 r = make_pair(i->first, next_val);
92 bool get_next(const K &key, pair<K, V> *next) {
94 Mutex::Locker l(lock);
95 typename map<K, pair<WeakVPtr, V*>, C>::iterator i =
96 contents.upper_bound(key);
97 while (i != contents.end() &&
98 !(next_val = i->second.first.lock()))
100 if (i == contents.end())
103 *next = make_pair(i->first, *next_val);
107 VPtr lookup(const K &key) {
108 Mutex::Locker l(lock);
111 typename map<K, pair<WeakVPtr, V*>, C>::iterator i =
113 if (i != contents.end()) {
114 VPtr retval = i->second.first.lock();
128 VPtr lookup_or_create(const K &key) {
129 Mutex::Locker l(lock);
132 typename map<K, pair<WeakVPtr, V*>, C>::iterator i =
134 if (i != contents.end()) {
135 VPtr retval = i->second.first.lock();
146 VPtr retval(ptr, OnRemoval(this, key));
147 contents.insert(make_pair(key, make_pair(retval, ptr)));
153 Mutex::Locker l(lock);
154 return contents.size();
157 void remove(const K &key) {
158 Mutex::Locker l(lock);
164 VPtr lookup_or_create(const K &key, const A &arg) {
165 Mutex::Locker l(lock);
168 typename map<K, pair<WeakVPtr, V*>, C>::iterator i =
170 if (i != contents.end()) {
171 VPtr retval = i->second.first.lock();
182 VPtr retval(ptr, OnRemoval(this, key));
183 contents.insert(make_pair(key, make_pair(retval, ptr)));
188 friend class SharedPtrRegistryTest;