Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-02-23 09:22:29

0001 //
0002 // ********************************************************************
0003 // * License and Disclaimer                                           *
0004 // *                                                                  *
0005 // * The  Geant4 software  is  copyright of the Copyright Holders  of *
0006 // * the Geant4 Collaboration.  It is provided  under  the terms  and *
0007 // * conditions of the Geant4 Software License,  included in the file *
0008 // * LICENSE and available at  http://cern.ch/geant4/license .  These *
0009 // * include a list of copyright holders.                             *
0010 // *                                                                  *
0011 // * Neither the authors of this software system, nor their employing *
0012 // * institutes,nor the agencies providing financial support for this *
0013 // * work  make  any representation or  warranty, express or implied, *
0014 // * regarding  this  software system or assume any liability for its *
0015 // * use.  Please see the license in the file  LICENSE  and URL above *
0016 // * for the full disclaimer and the limitation of liability.         *
0017 // *                                                                  *
0018 // * This  code  implementation is the result of  the  scientific and *
0019 // * technical work of the GEANT4 collaboration.                      *
0020 // * By using,  copying,  modifying or  distributing the software (or *
0021 // * any work based  on the software)  you  agree  to acknowledge its *
0022 // * use  in  resulting  scientific  publications,  and indicate your *
0023 // * acceptance of all terms of the Geant4 Software license.          *
0024 // ********************************************************************
0025 //
0026 /// \file parallel/ThreadsafeScorers/include/G4TAtomicHitsMap.hh
0027 /// \brief Definition of the G4TAtomicHitsMap class
0028 //
0029 //
0030 //
0031 //
0032 /// This is an implementation of G4THitsMap<T> where the underlying
0033 ///     type is G4atomic<T>, not just T. A static assert is provided to
0034 ///     ensure that T is fundamental. This class should be used in lieu
0035 ///     of G4THitsMap<T> when memory is a concern. Atomics are
0036 ///     thread-safe and *generally* faster that mutexes (as long as the
0037 ///     STL implementation is lock-free) but the synchronization does
0038 ///     not come without a cost. If performance is the primary concern,
0039 ///     use G4THitsMap<T> in thread-local instances.
0040 //
0041 //
0042 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0043 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0044 
0045 #ifndef G4TAtomicHitsMap_h
0046 #define G4TAtomicHitsMap_h 1
0047 
0048 #include "G4AutoLock.hh"
0049 #include "G4THitsCollection.hh"
0050 #include "G4THitsMap.hh"
0051 #include "G4Threading.hh"
0052 #include "G4atomic.hh"
0053 #include "globals.hh"
0054 
0055 #include <map>
0056 #include <type_traits>
0057 
0058 // class description:
0059 //
0060 //  This is a template class of hits map and parametrized by
0061 // The concrete class of G4VHit. This is a uniform collection for
0062 // a particular concrete hit class objects.
0063 //  An intermediate layer class G4HitsMap appeared in this
0064 // header file is used just for G4Allocator, because G4Allocator
0065 // cannot be instansiated with a template class. Thus G4HitsMap
0066 // class MUST NOT be directly used by the user.
0067 
0068 template<typename T>
0069 class G4TAtomicHitsMap : public G4VHitsCollection
0070 {
0071   protected:
0072     static_assert(std::is_fundamental<T>::value, "G4TAtomicHitsMap must use fundamental type");
0073 
0074   public:
0075     typedef G4atomic<T> value_type;
0076     typedef value_type* mapped_type;
0077     typedef typename std::map<G4int, mapped_type> container_type;
0078     typedef typename container_type::iterator iterator;
0079     typedef typename container_type::const_iterator const_iterator;
0080 
0081   public:
0082     G4TAtomicHitsMap();
0083 
0084   public:  // with description
0085     G4TAtomicHitsMap(G4String detName, G4String colNam);
0086     // constructor.
0087 
0088   public:
0089     virtual ~G4TAtomicHitsMap();
0090     G4bool operator==(const G4TAtomicHitsMap<T>& right) const;
0091     G4TAtomicHitsMap<T>& operator+=(const G4TAtomicHitsMap<T>& right) const;
0092     G4TAtomicHitsMap<T>& operator+=(const G4THitsMap<T>& right) const;
0093 
0094   public:  // with description
0095     virtual void DrawAllHits();
0096     virtual void PrintAllHits();
0097     //  These two methods invokes Draw() and Print() methods of all of
0098     // hit objects stored in this map, respectively.
0099 
0100   public:  // with description
0101     inline value_type* operator[](G4int key) const;
0102 
0103     //  Returns a pointer to a concrete hit object.
0104     inline container_type* GetMap() const { return theCollection; }
0105     //  Returns a collection map.
0106     inline G4int add(const G4int& key, value_type*& aHit) const;
0107     inline G4int add(const G4int& key, T& aHit) const;
0108     //  Insert a hit object. Total number of hit objects stored in this
0109     // map is returned.
0110     inline G4int set(const G4int& key, value_type*& aHit) const;
0111     inline G4int set(const G4int& key, T& aHit) const;
0112     //  Overwrite a hit object. Total number of hit objects stored in this
0113     // map is returned.
0114     inline G4int entries() const { return theCollection->size(); }
0115     //  Returns the number of hit objects stored in this map
0116     inline void clear();
0117 
0118   public:
0119     virtual G4VHit* GetHit(size_t) const { return 0; }
0120     virtual size_t GetSize() const { return theCollection->size(); }
0121 
0122     virtual size_t size() const { return theCollection->size(); }
0123 
0124   public:
0125     iterator begin() { return theCollection->begin(); }
0126     iterator end() { return theCollection->end(); }
0127 
0128     const_iterator begin() const { return theCollection->begin(); }
0129     const_iterator end() const { return theCollection->end(); }
0130 
0131     const_iterator cbegin() const { return theCollection->cbegin(); }
0132     const_iterator cend() const { return theCollection->cend(); }
0133 
0134     iterator find(G4int p) { return theCollection->find(p); }
0135     const_iterator find(G4int p) const { return theCollection->find(p); }
0136 
0137   private:
0138     container_type* theCollection;
0139     mutable G4Mutex fMutex;
0140 };
0141 
0142 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0143 template<typename T>
0144 G4TAtomicHitsMap<T>::G4TAtomicHitsMap() : theCollection(new container_type)
0145 {}
0146 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0147 template<typename T>
0148 G4TAtomicHitsMap<T>::G4TAtomicHitsMap(G4String detName, G4String colNam)
0149   : G4VHitsCollection(detName, colNam), theCollection(new container_type)
0150 {}
0151 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0152 template<typename T>
0153 G4TAtomicHitsMap<T>::~G4TAtomicHitsMap()
0154 {
0155   for (auto itr = theCollection->begin(); itr != theCollection->end(); itr++)
0156     delete itr->second;
0157 
0158   delete theCollection;
0159 }
0160 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0161 template<typename T>
0162 G4bool G4TAtomicHitsMap<T>::operator==(const G4TAtomicHitsMap<T>& right) const
0163 {
0164   return (collectionName == right.collectionName);
0165 }
0166 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0167 template<typename T>
0168 G4TAtomicHitsMap<T>& G4TAtomicHitsMap<T>::operator+=(const G4TAtomicHitsMap<T>& rhs) const
0169 {
0170   for (auto itr = rhs.GetMap()->begin(); itr != rhs.GetMap()->end(); itr++)
0171     add(itr->first, *(itr->second));
0172 
0173   return (G4TAtomicHitsMap<T>&)(*this);
0174 }
0175 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0176 template<typename T>
0177 G4TAtomicHitsMap<T>& G4TAtomicHitsMap<T>::operator+=(const G4THitsMap<T>& rhs) const
0178 {
0179   for (auto itr = rhs.GetMap()->begin(); itr != rhs.GetMap()->end(); itr++)
0180     add(itr->first, *(itr->second));
0181 
0182   return (G4TAtomicHitsMap<T>&)(*this);
0183 }
0184 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0185 template<typename T>
0186 inline typename G4TAtomicHitsMap<T>::value_type* G4TAtomicHitsMap<T>::operator[](G4int key) const
0187 {
0188   if (theCollection->find(key) != theCollection->end())
0189     return theCollection->find(key)->second;
0190   else {
0191     G4AutoLock l(&fMutex);
0192     if (theCollection->find(key) == theCollection->end()) {
0193       value_type* ptr = new value_type;
0194       (*theCollection)[key] = ptr;
0195       return ptr;
0196     }
0197     else
0198       return theCollection->find(key)->second;
0199   }
0200 }
0201 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0202 template<typename T>
0203 inline G4int G4TAtomicHitsMap<T>::add(const G4int& key, value_type*& aHit) const
0204 {
0205   if (theCollection->find(key) != theCollection->end())
0206     *(*theCollection)[key] += *aHit;
0207   else {
0208     G4AutoLock l(&fMutex);
0209     (*theCollection)[key] = aHit;
0210   }
0211   G4AutoLock l(&fMutex);
0212   return theCollection->size();
0213 }
0214 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0215 template<typename T>
0216 inline G4int G4TAtomicHitsMap<T>::add(const G4int& key, T& aHit) const
0217 {
0218   if (theCollection->find(key) != theCollection->end())
0219     *(*theCollection)[key] += aHit;
0220   else {
0221     value_type* hit = new value_type;
0222     *hit = aHit;
0223     G4AutoLock l(&fMutex);
0224     (*theCollection)[key] = hit;
0225   }
0226   G4AutoLock l(&fMutex);
0227   return theCollection->size();
0228 }
0229 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0230 template<typename T>
0231 inline G4int G4TAtomicHitsMap<T>::set(const G4int& key, value_type*& aHit) const
0232 {
0233   if (theCollection->find(key) != theCollection->end()) delete (*theCollection)[key]->second;
0234 
0235   (*theCollection)[key] = aHit;
0236   G4AutoLock l(&fMutex);
0237   return theCollection->size();
0238 }
0239 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0240 template<typename T>
0241 inline G4int G4TAtomicHitsMap<T>::set(const G4int& key, T& aHit) const
0242 {
0243   if (theCollection->find(key) != theCollection->end())
0244     *(*theCollection)[key] = aHit;
0245   else {
0246     value_type* hit = new value_type;
0247     *hit = aHit;
0248     (*theCollection)[key] = hit;
0249   }
0250   G4AutoLock l(&fMutex);
0251   return theCollection->size();
0252 }
0253 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0254 template<typename T>
0255 void G4TAtomicHitsMap<T>::DrawAllHits()
0256 {}
0257 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0258 template<typename T>
0259 void G4TAtomicHitsMap<T>::PrintAllHits()
0260 {
0261   G4cout << "G4TAtomicHitsMap " << SDname << " / " << collectionName << " --- " << entries()
0262          << " entries" << G4endl;
0263 }
0264 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0265 template<typename T>
0266 void G4TAtomicHitsMap<T>::clear()
0267 {
0268   G4AutoLock l(&fMutex);
0269 
0270   for (auto itr = theCollection->begin(); itr != theCollection->end(); itr++)
0271     delete itr->second;
0272 
0273   theCollection->clear();
0274 }
0275 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0276 
0277 #endif