00001 #ifndef FWCore_Utilities_ThreadSafeIndexedRegistry_h
00002 #define FWCore_Utilities_ThreadSafeIndexedRegistry_h
00003
00004 #include <vector>
00005 #include "boost/thread.hpp"
00006
00007
00008
00016
00017
00018 namespace edm {
00019 namespace detail {
00020 struct Empty { };
00021
00022 template <typename T, typename E=Empty>
00023 class ThreadSafeIndexedRegistry {
00024 public:
00025 typedef T value_type;
00026 typedef E extra_type;
00027 typedef typename std::vector<value_type> collection_type;
00028 typedef typename collection_type::size_type size_type;
00029
00030 typedef typename collection_type::const_iterator const_iterator;
00031
00032 static ThreadSafeIndexedRegistry* instance();
00033
00039 void getMapped(size_type index, value_type& result) const;
00040
00043 bool insertMapped(value_type const& v);
00044
00047 void insertCollection(collection_type const& c);
00048
00050 bool empty() const;
00051
00053 bool notEmpty() const;
00054
00056 size_type size() const;
00057
00060 const_iterator begin() const;
00061 const_iterator end() const;
00062
00064 void print(std::ostream& os) const;
00065
00067 collection_type& data();
00068 collection_type const& data() const;
00069
00073 extra_type& extra();
00074 extra_type const& extra() const;
00075
00076 private:
00077 ThreadSafeIndexedRegistry();
00078 ~ThreadSafeIndexedRegistry();
00079
00080
00081 ThreadSafeIndexedRegistry(ThreadSafeIndexedRegistry<T, E> const&);
00082
00083 ThreadSafeIndexedRegistry<T, E>&
00084 operator= (ThreadSafeIndexedRegistry<T, E> const&);
00085
00086 collection_type data_;
00087 extra_type extra_;
00088
00089 static ThreadSafeIndexedRegistry* instance_;
00090
00091 static boost::mutex registry_mutex;
00092 };
00093
00094 template <typename T, typename E>
00095 inline
00096 std::ostream&
00097 operator<< (std::ostream& os, ThreadSafeIndexedRegistry<T, E> const& reg) {
00098 reg.print(os);
00099 return os;
00100 }
00101
00102
00103
00104
00105
00106 template <typename T, typename E>
00107 ThreadSafeIndexedRegistry<T, E>* ThreadSafeIndexedRegistry<T, E>::instance_ = 0;
00108
00109 template <typename T, typename E>
00110 boost::mutex ThreadSafeIndexedRegistry<T, E>::registry_mutex;
00111
00112
00113
00114 template <typename T, typename E>
00115 ThreadSafeIndexedRegistry<T, E>*
00116 ThreadSafeIndexedRegistry<T, E>::instance() {
00117 if (instance_ == 0) {
00118 boost::mutex::scoped_lock lock(registry_mutex);
00119 if (instance_ == 0) {
00120 static ThreadSafeIndexedRegistry<T, E> me;
00121 instance_ = &me;
00122 }
00123 }
00124 return instance_;
00125 }
00126
00127 template <typename T, typename E>
00128 void
00129 ThreadSafeIndexedRegistry<T, E>::getMapped(size_type k, value_type& result) const {
00130 boost::mutex::scoped_lock lock(registry_mutex);
00131 result = data_[k];
00132 }
00133
00134 template <typename T, typename E>
00135 bool
00136 ThreadSafeIndexedRegistry<T, E>::insertMapped(value_type const& v) {
00137 boost::mutex::scoped_lock lock(registry_mutex);
00138 data_.push_back(v);
00139 return true;
00140 }
00141
00142 template <typename T, typename E>
00143 void
00144 ThreadSafeIndexedRegistry<T, E>::insertCollection(collection_type const& c) {
00145 for (typename collection_type::const_iterator it = c.begin(), itEnd = c.end(); it != itEnd; ++it) {
00146 insertMapped(*it);
00147 }
00148 }
00149
00150 template <typename T, typename E>
00151 inline
00152 bool
00153 ThreadSafeIndexedRegistry<T, E>::empty() const {
00154 return data_.empty();
00155 }
00156
00157 template <typename T, typename E>
00158 inline
00159 bool
00160 ThreadSafeIndexedRegistry<T, E>::notEmpty() const {
00161 return !empty();
00162 }
00163
00164 template <typename T, typename E>
00165 inline
00166 typename ThreadSafeIndexedRegistry<T, E>::size_type
00167 ThreadSafeIndexedRegistry<T, E>::size() const {
00168 return data_.size();
00169 }
00170
00171 template <typename T, typename E>
00172 inline
00173 typename ThreadSafeIndexedRegistry<T, E>::const_iterator
00174 ThreadSafeIndexedRegistry<T, E>::begin() const {
00175 return data_.begin();
00176 }
00177
00178 template <typename T, typename E>
00179 inline
00180 typename ThreadSafeIndexedRegistry<T, E>::const_iterator
00181 ThreadSafeIndexedRegistry<T, E>::end() const {
00182 return data_.end();
00183 }
00184
00185 template <typename T, typename E>
00186 void
00187 ThreadSafeIndexedRegistry<T, E>::print(std::ostream& os) const {
00188 os << "Registry with " << size() << " entries\n";
00189 for (const_iterator i = begin(), e = end(); i != e; ++i) {
00190 os << i - begin() << " " << i << '\n';
00191 }
00192 }
00193
00194 template <typename T, typename E>
00195 inline
00196 typename ThreadSafeIndexedRegistry<T, E>::collection_type&
00197 ThreadSafeIndexedRegistry<T, E>::data() {
00198 return data_;
00199 }
00200
00201 template <typename T, typename E>
00202 inline
00203 typename ThreadSafeIndexedRegistry<T, E>::extra_type&
00204 ThreadSafeIndexedRegistry<T, E>::extra() {
00205 return extra_;
00206 }
00207
00208 template <typename T, typename E>
00209 inline
00210 typename ThreadSafeIndexedRegistry<T, E>::extra_type const&
00211 ThreadSafeIndexedRegistry<T, E>::extra() const {
00212 return extra_;
00213 }
00214
00215 template <typename T, typename E>
00216 inline
00217 typename ThreadSafeIndexedRegistry<T, E>::collection_type const&
00218 ThreadSafeIndexedRegistry<T, E>::data() const {
00219 return data_;
00220 }
00221
00222 template <typename T, typename E>
00223 ThreadSafeIndexedRegistry<T, E>::ThreadSafeIndexedRegistry() :
00224 data_()
00225 { }
00226
00227
00228 template <typename T, typename E>
00229 ThreadSafeIndexedRegistry<T, E>::~ThreadSafeIndexedRegistry()
00230 { }
00231
00232 }
00233 }
00234
00235 #endif // FWCore_Utilities_ThreadSafeIndexedRegistry_h