Geant4  10.02.p01
G4TAtomicHitsMap.hh
Go to the documentation of this file.
1 //
2 // ********************************************************************
3 // * License and Disclaimer *
4 // * *
5 // * The Geant4 software is copyright of the Copyright Holders of *
6 // * the Geant4 Collaboration. It is provided under the terms and *
7 // * conditions of the Geant4 Software License, included in the file *
8 // * LICENSE and available at http://cern.ch/geant4/license . These *
9 // * include a list of copyright holders. *
10 // * *
11 // * Neither the authors of this software system, nor their employing *
12 // * institutes,nor the agencies providing financial support for this *
13 // * work make any representation or warranty, express or implied, *
14 // * regarding this software system or assume any liability for its *
15 // * use. Please see the license in the file LICENSE and URL above *
16 // * for the full disclaimer and the limitation of liability. *
17 // * *
18 // * This code implementation is the result of the scientific and *
19 // * technical work of the GEANT4 collaboration. *
20 // * By using, copying, modifying or distributing the software (or *
21 // * any work based on the software) you agree to acknowledge its *
22 // * use in resulting scientific publications, and indicate your *
23 // * acceptance of all terms of the Geant4 Software license. *
24 // ********************************************************************
25 //
28 //
29 //
30 // $Id: G4TAtomicHitsMap.hh 93110 2015-11-05 08:37:42Z jmadsen $
31 //
32 //
41 //
42 //
43 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
44 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
45 
46 
47 
48 
49 #ifndef G4TAtomicHitsMap_h
50 #define G4TAtomicHitsMap_h 1
51 
52 #include "G4THitsCollection.hh"
53 #include "G4THitsMap.hh"
54 #include "globals.hh"
55 #include "G4atomic.hh"
56 #include "G4Threading.hh"
57 #include "G4AutoLock.hh"
58 
59 #include <map>
60 #include <type_traits>
61 
62 // class description:
63 //
64 // This is a template class of hits map and parametrized by
65 // The concrete class of G4VHit. This is a uniform collection for
66 // a particular concrete hit class objects.
67 // An intermediate layer class G4HitsMap appeared in this
68 // header file is used just for G4Allocator, because G4Allocator
69 // cannot be instansiated with a template class. Thus G4HitsMap
70 // class MUST NOT be directly used by the user.
71 
72 template <typename T>
74 {
75 protected:
76  static_assert(std::is_fundamental<T>::value,
77  "G4TAtomicHitsMap must use fundamental type");
78 
79 public:
80  typedef G4atomic<T> value_type;
81  typedef value_type* mapped_type;
82  typedef typename std::map<G4int, mapped_type> container_type;
83  typedef typename container_type::iterator iterator;
84  typedef typename container_type::const_iterator const_iterator;
85 
86 public:
88 
89 public: // with description
90  G4TAtomicHitsMap(G4String detName, G4String colNam);
91  // constructor.
92 
93 public:
94  virtual ~G4TAtomicHitsMap();
96  G4TAtomicHitsMap<T> & operator+=(const G4TAtomicHitsMap<T> &right) const;
97  G4TAtomicHitsMap<T> & operator+=(const G4THitsMap<T> &right) const;
98 
99 public: // with description
100  virtual void DrawAllHits();
101  virtual void PrintAllHits();
102  // These two methods invokes Draw() and Print() methods of all of
103  // hit objects stored in this map, respectively.
104 
105 public: // with description
106  inline value_type* operator[](G4int key) const;
107 
108  // Returns a pointer to a concrete hit object.
109  inline container_type* GetMap() const
110  { return theCollection; }
111  // Returns a collection map.
112  inline G4int add(const G4int & key, value_type*& aHit) const;
113  inline G4int add(const G4int & key, T& aHit) const;
114  // Insert a hit object. Total number of hit objects stored in this
115  // map is returned.
116  inline G4int set(const G4int & key, value_type*& aHit) const;
117  inline G4int set(const G4int & key, T& aHit) const;
118  // Overwrite a hit object. Total number of hit objects stored in this
119  // map is returned.
120  inline G4int entries() const
121  {
122  return theCollection->size();
123  }
124  // Returns the number of hit objects stored in this map
125  inline void clear();
126 
127 public:
128  virtual G4VHit* GetHit(size_t) const {return 0;}
129  virtual size_t GetSize() const
130  {
131  return theCollection->size();
132  }
133 
134 public:
135  iterator begin() { return theCollection->begin(); }
136  iterator end() { return theCollection->end(); }
137 
138  const_iterator begin() const { return theCollection->begin(); }
139  const_iterator end() const { return theCollection->end(); }
140 
141  const_iterator cbegin() const { return theCollection->cbegin(); }
142  const_iterator cend() const { return theCollection->cend(); }
143 
144  iterator find(G4int p) { return theCollection->find(p); }
145  const_iterator find(G4int p) const { return theCollection->find(p); }
146 
147 private:
148  container_type* theCollection;
149  mutable G4Mutex fMutex;
150 
151 };
152 
153 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
154 template <typename T>
156  : theCollection(new container_type),
157  fMutex(G4MUTEX_INITIALIZER)
158 { }
159 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
160 template <typename T>
162  G4String colNam)
163  : G4VHitsCollection(detName,colNam),
164  theCollection(new container_type),
165  fMutex(G4MUTEX_INITIALIZER)
166 { }
167 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
168 template <typename T>
170 {
171  for(auto itr = theCollection->begin(); itr != theCollection->end(); itr++)
172  delete itr->second;
173 
174  delete theCollection;
175  G4MUTEXDESTROY(fMutex);
176 }
177 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
178 template <typename T>
180 {
181  return (collectionName == right.collectionName);
182 }
183 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
184 template <typename T>
187 {
188  for(auto itr = rhs.GetMap()->begin(); itr != rhs.GetMap()->end(); itr++)
189  add(itr->first, *(itr->second));
190 
191  return (G4TAtomicHitsMap<T>&)(*this);
192 }
193 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
194 template <typename T>
197 {
198  for(auto itr = rhs.GetMap()->begin(); itr != rhs.GetMap()->end(); itr++)
199  add(itr->first, *(itr->second));
200 
201  return (G4TAtomicHitsMap<T>&)(*this);
202 }
203 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
204 template <typename T>
205 inline typename G4TAtomicHitsMap<T>::value_type*
207 {
208  if(theCollection->find(key) != theCollection->end())
209  return theCollection->find(key)->second;
210  else
211  {
212  G4AutoLock l(&fMutex);
213  if(theCollection->find(key) == theCollection->end())
214  {
215  value_type* ptr = new value_type;
216  (*theCollection)[key] = ptr;
217  return ptr;
218  } else
219  return theCollection->find(key)->second;
220  }
221 }
222 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
223 template <typename T>
224 inline G4int
225 G4TAtomicHitsMap<T>::add(const G4int& key, value_type*& aHit) const
226 {
227  if(theCollection->find(key) != theCollection->end())
228  *(*theCollection)[key] += *aHit;
229  else
230  {
231  G4AutoLock l(&fMutex);
232  (*theCollection)[key] = aHit;
233  }
234  G4AutoLock l(&fMutex);
235  return theCollection->size();
236 }
237 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
238 template <typename T>
239 inline G4int
240 G4TAtomicHitsMap<T>::add(const G4int& key, T& aHit) const
241 {
242 
243  if(theCollection->find(key) != theCollection->end())
244  *(*theCollection)[key] += aHit;
245  else
246  {
247  value_type* hit = new value_type;
248  *hit = aHit;
249  G4AutoLock l(&fMutex);
250  (*theCollection)[key] = hit;
251  }
252  G4AutoLock l(&fMutex);
253  return theCollection->size();
254 }
255 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
256 template <typename T>
257 inline G4int
258 G4TAtomicHitsMap<T>::set(const G4int& key, value_type*& aHit) const
259 {
260  if(theCollection->find(key) != theCollection->end())
261  delete (*theCollection)[key]->second;
262 
263  (*theCollection)[key] = aHit;
264  G4AutoLock l(&fMutex);
265  return theCollection->size();
266 }
267 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
268 template <typename T>
269 inline G4int
270 G4TAtomicHitsMap<T>::set(const G4int& key, T& aHit) const
271 {
272  if(theCollection->find(key) != theCollection->end())
273  *(*theCollection)[key] = aHit;
274  else
275  {
276  value_type* hit = new value_type;
277  *hit = aHit;
278  (*theCollection)[key] = hit;
279  }
280  G4AutoLock l(&fMutex);
281  return theCollection->size();
282 }
283 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
284 template <typename T>
286 { }
287 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
288 template <typename T>
290 {
291  G4cout << "G4TAtomicHitsMap " << SDname << " / " << collectionName << " --- "
292  << entries() << " entries" << G4endl;
293 }
294 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
295 template <typename T>
297 {
298  G4AutoLock l(&fMutex);
299 
300  for(auto itr = theCollection->begin(); itr != theCollection->end(); itr++)
301  delete itr->second;
302 
303  theCollection->clear();
304 
305 }
306 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
307 
308 #endif
virtual size_t GetSize() const
virtual void PrintAllHits()
G4int operator==(const G4VHitsCollection &right) const
virtual G4VHit * GetHit(size_t) const
Definition: G4VHit.hh:48
virtual void DrawAllHits()
int G4int
Definition: G4Types.hh:78
#define G4MUTEX_INITIALIZER
Definition: G4Threading.hh:175
G4GLOB_DLL std::ostream G4cout
G4int G4Mutex
Definition: G4Threading.hh:173
This is an implementation of G4THitsMap where the underlying type is G4atomic, not just T. A static assert is provided to ensure that T is fundamental. This class should be used in lieu of G4THitsMap when memory is a concern. Atomics are thread-safe and generally faster that mutexes (as long as the STL implementation is lock-free) but the synchronization does not come without a cost. If performance is the primary concern, use G4THitsMap in thread-local instances.
std::map< G4int, T * > * GetMap() const
Definition: G4THitsMap.hh:68
#define G4endl
Definition: G4ios.hh:61
#define G4MUTEXDESTROY(mutex)
Definition: G4Threading.hh:178
_Tp G4atomic
This is an friendly implementation of the STL atomic class. This class has the same interface as the ...
Definition: G4atomic.hh:271