CMS 3D CMS Logo

ThreadSafeRegistry.h

Go to the documentation of this file.
00001 #ifndef FWCoreUtilities_ThreadSafeRegistry_h
00002 #define FWCoreUtilities_ThreadSafeRegistry_h
00003 
00004 #include <map>
00005 #include "boost/thread.hpp"
00006 
00007 // ----------------------------------------------------------------------
00008 // $Id: ThreadSafeRegistry.h,v 1.5 2007/02/21 16:21:28 paterno Exp $
00009 
00026 // ----------------------------------------------------------------------
00027 
00028 namespace edm
00029 {
00030   namespace detail
00031   {
00032     struct empty { };
00033 
00034     template <class KEY, class T, class E=empty>
00035     class ThreadSafeRegistry
00036     {
00037     public:
00038       typedef KEY   key_type;
00039       typedef T     mapped_type;
00040       typedef E     extra_type;
00041       typedef typename std::map<key_type, mapped_type> collection_type;
00042       typedef typename collection_type::size_type      size_type;
00043 
00044       typedef typename collection_type::const_iterator const_iterator;
00045 
00046       static ThreadSafeRegistry* instance();
00047 
00053       bool getMapped(key_type const& k, mapped_type& result) const;
00054 
00062 
00063       bool insertMapped(mapped_type const& v);
00064 
00066       bool empty() const;
00067 
00069       bool notEmpty() const;
00070 
00072       size_type size() const;
00073 
00076       const_iterator begin() const;
00077       const_iterator end() const;
00078 
00080       void print(std::ostream& os) const;
00081 
00083       collection_type& data();
00084       collection_type const& data() const;
00085 
00089       extra_type& extra();
00090       extra_type const& extra() const;      
00091 
00092     private:
00093       ThreadSafeRegistry();
00094       ~ThreadSafeRegistry();
00095 
00096       // The following two are not implemented.
00097       ThreadSafeRegistry(ThreadSafeRegistry<KEY,T,E> const&); 
00098     
00099       ThreadSafeRegistry<KEY,T,E>& 
00100       operator= (ThreadSafeRegistry<KEY,T,E> const&);
00101 
00102       collection_type data_;
00103       extra_type      extra_;
00104 
00105       static ThreadSafeRegistry* instance_;
00106 
00107       static boost::mutex registry_mutex;
00108     };
00109 
00110     template <class KEY, class T, class E>
00111     inline
00112     std::ostream&
00113     operator<< (std::ostream& os, ThreadSafeRegistry<KEY,T,E> const& reg)
00114     {
00115       reg.print(os);
00116       return os;
00117     }
00118 
00119     // ----------------------------------------------------------------------
00120     // Declarations of static data for classes instantiated from the
00121     // class template.
00122 
00123     template <class KEY, class T, class E>
00124     ThreadSafeRegistry<KEY,T,E>* ThreadSafeRegistry<KEY,T,E>::instance_ = 0;
00125 
00126     template <class KEY, class T, class E>
00127     boost::mutex ThreadSafeRegistry<KEY,T,E>::registry_mutex;
00128 
00129     // ----------------------------------------------------------------------
00130 
00131     template <class KEY, class T, class E>
00132     ThreadSafeRegistry<KEY,T,E>*
00133     ThreadSafeRegistry<KEY,T,E>::instance()
00134     {
00135       if (instance_ == 0)
00136         {
00137           boost::mutex::scoped_lock lock(registry_mutex);
00138           if (instance_ == 0)
00139             {
00140               static ThreadSafeRegistry<KEY,T,E> me;
00141               instance_ = &me;
00142             }
00143         }
00144       return instance_;      
00145     }
00146 
00147     template <class KEY, class T, class E>
00148     bool 
00149     ThreadSafeRegistry<KEY,T,E>::getMapped(key_type const& k, 
00150                                          mapped_type& result) const
00151     {
00152       bool found;
00153       const_iterator i;
00154       {
00155         // This scope limits the lifetime of the lock to the shorted
00156         // required interval.
00157         boost::mutex::scoped_lock lock(registry_mutex);
00158         i = data_.find(k);
00159         found = (i != data_.end());
00160       }
00161       if (found) result = i->second;
00162       return found;
00163     }
00164 
00165     template <class KEY, class T, class E>
00166     bool 
00167     ThreadSafeRegistry<KEY,T,E>::insertMapped(mapped_type const& v)
00168     {
00169       bool newly_added = false;
00170       boost::mutex::scoped_lock lock(registry_mutex);
00171 
00172       key_type id = v.id();
00173       if (data_.find(id) == data_.end())
00174         {
00175           data_[id] = v;
00176           newly_added = true;
00177         }
00178       return newly_added;
00179     }
00180 
00181     template <class KEY, class T, class E>
00182     inline
00183     bool
00184     ThreadSafeRegistry<KEY,T,E>::empty() const
00185     {
00186       return data_.empty();
00187     }
00188     
00189     template <class KEY, class T, class E>
00190     inline
00191     bool
00192     ThreadSafeRegistry<KEY,T,E>::notEmpty() const
00193     {
00194       return !empty();
00195     }
00196 
00197     template <class KEY, class T, class E>
00198     inline
00199     typename ThreadSafeRegistry<KEY,T,E>::size_type
00200     ThreadSafeRegistry<KEY,T,E>::size() const
00201     {
00202       return data_.size();
00203     }
00204 
00205     template <class KEY, class T, class E>
00206     inline
00207     typename ThreadSafeRegistry<KEY,T,E>::const_iterator
00208     ThreadSafeRegistry<KEY,T,E>::begin() const
00209     {
00210       return data_.begin();
00211     }
00212 
00213     template <class KEY, class T, class E>
00214     inline
00215     typename ThreadSafeRegistry<KEY,T,E>::const_iterator
00216     ThreadSafeRegistry<KEY,T,E>::end() const
00217     {
00218       return data_.end();
00219     }
00220     
00221     template <class KEY, class T, class E>
00222     void
00223     ThreadSafeRegistry<KEY,T,E>::print(std::ostream& os) const
00224     {
00225       os << "Registry with " << size() << " entries\n";
00226       for (const_iterator i=begin(), e=end(); i!=e; ++i)
00227         {
00228           os << i->first << " " << i->second << '\n';
00229         }
00230     }
00231 
00232     template <class KEY, class T, class E>
00233     inline
00234     typename ThreadSafeRegistry<KEY,T,E>::collection_type&
00235     ThreadSafeRegistry<KEY,T,E>::data()
00236     {
00237       return data_;
00238     }
00239 
00240     template <class KEY, class T, class E>
00241     inline
00242     typename ThreadSafeRegistry<KEY,T,E>::extra_type&
00243     ThreadSafeRegistry<KEY,T,E>::extra()
00244     {
00245       return extra_;
00246     }
00247 
00248     template <class KEY, class T, class E>
00249     inline
00250     typename ThreadSafeRegistry<KEY,T,E>::extra_type const&
00251     ThreadSafeRegistry<KEY,T,E>::extra() const
00252     {
00253       return extra_;
00254     }
00255 
00256     template <class KEY, class T, class E>
00257     inline
00258     typename ThreadSafeRegistry<KEY,T,E>::collection_type const&
00259     ThreadSafeRegistry<KEY,T,E>::data() const
00260     {
00261       return data_;
00262     }
00263 
00264     template <class KEY, class T, class E> 
00265     ThreadSafeRegistry<KEY,T,E>::ThreadSafeRegistry() : 
00266       data_()
00267     { }
00268 
00269 
00270     template <class KEY, class T, class E> 
00271     ThreadSafeRegistry<KEY,T,E>::~ThreadSafeRegistry() 
00272     { }
00273 
00274   } // namespace detail
00275 } // namespace edm
00276 
00277 #endif //  FWCoreUtilities_ThreadSafeRegistry_h

Generated on Tue Jun 9 17:36:43 2009 for CMSSW by  doxygen 1.5.4