CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_4_2_9_HLT1_bphpatch4/src/FWCore/Utilities/interface/ThreadSafeRegistry.h

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