Geant4  10.00.p01
G4Cache.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 //
26 // $Id$
27 //
28 // ---------------------------------------------------------------
29 // GEANT 4 class header file
30 //
31 // Class Description:
32 // Helper classes for Geant4 Multi-Threaded.
33 // The classes defined in this header file provide a thread-private
34 // cache to store, in a class instance shared among threads,
35 // a thread-local variable V.
36 // These are templated classes on the to-be-stored object.
37 //
38 // Example:
39 // Let's assume an instance myObject of class G4Shared is sharead between
40 // threads. Still a data member of this class needs to be thread-private.
41 // A typical example of this being a "cache" for a local calculation.
42 // The helper here defined can be used to guarantee thread-safe operations
43 // on the thread-private object.
44 // Example:
45 // class G4Shared {
46 // G4double sharedData;
47 // G4Cache<G4double> threadPrivate;
48 // void foo() {
49 // G4double priv = threadPrivate.Get();
50 // if ( priv < 10 ) priv += sharedData;
51 // threadPrivate.Put( priv );
52 // }
53 // };
54 //
55 // Two variants of the base G4Cache exists. The first one being
56 // G4VectorCache similar to std::vector
57 // Example:
58 // G4VectorCache<G4double> aVect;
59 // aVect.Push_back( 3.2 );
60 // aVect.Push_back( 4.1 );
61 // cout<<aVect[0]<<endl;
62 // The second one being:
63 // G4MapCache similar to std::map
64 // Example:
65 // G4MapCache<G4int,G4double> aMap;
66 // aMap[320]=1.234;
67 //
68 // See classes definition for details.
69 // See testG4Cache unit test for details on usage
70 //
71 // History:
72 // 21 October 2013: A. Dotti - First implementation
73 
74 #ifndef G4CACHE_HH
75 #define G4CACHE_HH
76 
77 //Debug this code
78 //#define g4cdebug 1
79 
80 //Thread Local storage details are in this header file
81 #include "G4CacheDetails.hh"
82 
83 // A templated cache to store a thread-private data of type VALTYPE.
84 template<class VALTYPE>
85 class G4Cache {
86 public:
87  typedef VALTYPE value_type;
88  // The stored type
89 
90  G4Cache();
91  // Default constructor
92 
93  G4Cache(const value_type& v);
94  // Construct cache object with initial value
95 
96  virtual ~G4Cache();
97  // Default destructor
98 
99  inline value_type& Get() const;
100  // Gets reference to cached value of this threads
101 
102  inline void Put( const value_type& val ) const;
103  // Sets this thread cached value to val
104 
105  inline value_type Pop();
106  // Gets copy of cached value
107 
108 protected:
109  const int& GetId() const { return id; }
110 private:
111  int id;
113  static G4Mutex gMutex;
114  static unsigned int instancesctr;
115  static unsigned int dstrctr;
116 
117  inline value_type& GetCache() const {
118  theCache.Initialize(id);
119  return theCache.GetCache(id);
120  }
121 
122  //Disable copy constructor
123  G4Cache(const G4Cache& rhs);
124  G4Cache& operator=(const G4Cache& rhs);
125 };
126 
127 
128 // A vector version of the cache. Implements vector interface.
129 // Can be used directly as a std::vector would be used.
130 template<class VALTYPE>
131 class G4VectorCache : public G4Cache< std::vector<VALTYPE> > {
132 public:
133  //Some useful defintions
134  typedef VALTYPE value_type;
135  typedef typename std::vector<value_type> vector_type;
136  typedef typename vector_type::size_type size_type;
137  typedef typename vector_type::iterator iterator;
138  typedef typename vector_type::const_iterator const_iterator;
139 
140  G4VectorCache();
141  // Default constructor
142 
143  G4VectorCache( G4int nElems );
144  // Creates a vector cache of nElems elements
145 
146  G4VectorCache( G4int nElems , value_type* vals );
147  // Creates a vector cache with elements from an array
148 
149  virtual ~G4VectorCache();
150  // Default destructor
151 
152  // Interface with funxtionalities of similar name of std::vector
153  inline void Push_back( const value_type& val );
154  inline value_type Pop_back();
155  inline value_type& operator[](const G4int& idx);
156  inline iterator Begin();
157  inline iterator End();
158  inline void Clear();
159  inline size_type Size() { return G4Cache<vector_type>::Get().size(); } //Needs to be here for a VC9 compilation problem
160 };
161 
162 
163 // a Map version of the cache. Implemetns std::map interface.
164 // Can be used directly as a std::map would be used.
165 // KEYTYPE being the key type and VALTYPE the value type.
166 #include <map>
167 template<class KEYTYPE, class VALTYPE>
168 class G4MapCache : public G4Cache<std::map<KEYTYPE,VALTYPE> > {
169 public:
170  //Some useful definitions
171  typedef KEYTYPE key_type;
172  typedef VALTYPE value_type;
173  typedef typename std::map<key_type,value_type> map_type;
174  typedef typename map_type::size_type size_type;
175  typedef typename map_type::iterator iterator;
176  typedef typename map_type::const_iterator const_iterator;
177 
178  virtual ~G4MapCache();
179  // Default destructor
180 
181  inline G4bool Has(const key_type& k );
182  // Returns true if map contains element corresponding to key k
183 
184  // Interface with functionalities of similar name of std::map
185  inline std::pair<iterator,G4bool> Insert( const key_type& k , const value_type& v );
186  inline iterator Begin();
187  inline iterator End();
188  inline iterator Find(const key_type& k );
189  inline value_type& Get(const key_type& k );
190  inline size_type Erase(const key_type& k );
191  inline value_type& operator[](const key_type& k);
192  inline size_type Size() { return G4Cache<map_type>::Get().size(); } //Needs to be here for a VC9 compilation problem
193 };
194 
195 
196 
197 //=============================================================
198 // Implementation details follow
199 //=============================================================
200 
201 
202 
203 #ifdef g4cdebug
204 #include <iostream>
205 #include <sstream>
206 using std::cout;
207 using std::endl;
208 #endif
209 
210 #include "G4AutoLock.hh"
211 
212 
213 //========= Implementation: G4Cache<V>
214 
215 template<class V>
217 {
218  G4AutoLock l(&gMutex);
219  id = instancesctr++;
220 #ifdef g4cdebug
221  cout<<"G4Cache id: "<<id<<endl;
222 #endif
223 }
224 
225 template<class V>
226 G4Cache<V>::G4Cache(const V& v)
227 {
228  G4AutoLock l(&gMutex);
229  id = instancesctr++;
230  Put(v);
231 #ifdef g4cdebug
232  cout<<"G4Cache id: "<<id<<" "<<endl;
233 #endif
234 }
235 
236 template<class V>
238 { //Move base calss
239 #ifdef g4cdebug
240  cout<<"~G4Cache id: "<<id<<" "<<endl;
241 #endif
242  G4AutoLock l(&gMutex);
243  ++dstrctr;
244  G4bool last = ( dstrctr == instancesctr );
245  theCache.Destroy(id,last);
246  if (last) {
247  instancesctr = 0;
248  dstrctr = 0;
249  }
250 }
251 
252 template<class V>
253 V& G4Cache<V>::Get() const
254 { return GetCache(); }
255 
256 template<class V>
257 void G4Cache<V>::Put( const V& val ) const
258 { GetCache() = val; }
259 
260 //Should here remove from cache element?
261 template<class V>
263 { return GetCache(); }
264 
265 template<class V>
266 unsigned int G4Cache<V>::instancesctr = 0;
267 
268 template<class V>
269 unsigned int G4Cache<V>::dstrctr = 0;
270 
271 template<class V>
273 
274 //========== Implementation: G4VectorCache<V>
275 template<class V>
277 { }
278 
279 template<class V>
281 #ifdef g4cdebug
282  cout<<"~G4VectorCache "<<G4Cache<G4VectorCache<V>::vector_type>::GetId()<<" with size: "<<Size()<<"->";
283  for ( size_type i = 0 ; i < Size() ; ++i )
284  cout<<operator[](i)<<",";
285  cout<<"<-"<<endl;
286 #endif
287 }
288 
289 template<class V>
292  cc.resize(nElems);
293 }
294 
295 template<class V>
296 G4VectorCache<V>::G4VectorCache(G4int nElems , V* vals ) {
297  vector_type& cc = G4Cache<vector_type>::Get();
298  cc.resize(nElems);
299  for ( G4int idx = 0 ; idx < nElems ; ++idx )
300  cc[idx]=vals[idx];
301 }
302 
303 template<class V>
304 void G4VectorCache<V>::Push_back( const V& val )
305 {
306  G4Cache<vector_type>::Get().push_back( val );
307 }
308 
309 template<class V>
311 {
313  value_type val = cc[cc.size()-1];
314  cc.pop_back();
315  return val;
316 }
317 
318 template<class V>
320 {
322  return cc[idx];
323 }
324 
325 template<class V>
327 {
328  return G4Cache<vector_type>::Get().begin();
329 }
330 
331 template<class V>
333 {
334  return G4Cache<vector_type>::Get().end();
335 }
336 
337 template<class V>
339 {
340  G4Cache<vector_type>::Get().clear();
341 }
342 
343 //template<class V>
344 //typename G4VectorCache<V>::size_type G4VectorCache<V>::Size()
345 //{
346 // return G4Cache<vector_type>::Get().size();
347 //}
348 
349 //======== Implementation: G4MapType<K,V>
350 template<class K, class V>
352 {
353 #ifdef g4cdebug
354  cout<<"~G4MacCache "<<G4Cache<map_type>::GetId()<<" with size: "<<Size()<<"->";
355  for ( iterator it = Begin() ; it != End() ; ++it )
356  cout<<it->first<<":"<<it->second<<",";
357  cout<<"<-"<<endl;
358 #endif
359 }
360 
361 template<class K, class V>
362 std::pair<typename G4MapCache<K,V>::iterator,G4bool> G4MapCache<K,V>::Insert(
363  const K& k,
364  const V& v
365  )
366 {
367  return G4Cache<map_type>::Get().insert( std::pair<key_type,value_type>(k,v) );
368 }
369 
370 //template<class K, class V>
371 //typename G4MapCache<K,V>::size_type G4MapCache<K,V>::Size()
372 //{
373 // return G4Cache<map_type>::Get().size();
374 //}
375 
376 template<class K, class V>
378 {
379  return G4Cache<map_type>::Get().begin();
380 }
381 template<class K, class V>
383 {
384  return G4Cache<map_type>::Get().end();
385 }
386 
387 template<class K, class V>
389 {
390  return G4Cache<map_type>::Get().find(k);
391 }
392 
393 template<class K, class V>
395 {
396  return ( Find(k) != End() );
397 }
398 
399 template<class K, class V>
400 V& G4MapCache<K,V>::Get(const K& k )
401 {
402  return Find(k)->second;
403 }
404 
405 template<class K, class V>
407 {
408  return G4Cache<map_type>::Get().erase(k);
409 }
410 
411 template<class K, class V>
413 {
414  return (G4Cache<map_type>::Get())[k];
415 }
416 
417 #endif
VALTYPE value_type
Definition: G4Cache.hh:87
G4CacheReference< value_type > theCache
Definition: G4Cache.hh:112
void Initialize(unsigned int id)
value_type & GetCache() const
Definition: G4Cache.hh:117
value_type Pop_back()
Definition: G4Cache.hh:310
iterator End()
Definition: G4Cache.hh:382
G4Cache & operator=(const G4Cache &rhs)
size_type Size()
Definition: G4Cache.hh:159
static unsigned int instancesctr
Definition: G4Cache.hh:114
iterator End()
Definition: G4Cache.hh:332
VALTYPE value_type
Definition: G4Cache.hh:134
value_type Pop()
Definition: G4Cache.hh:262
vector_type::const_iterator const_iterator
Definition: G4Cache.hh:138
value_type & Get() const
Definition: G4Cache.hh:253
size_type Size()
Definition: G4Cache.hh:192
virtual ~G4VectorCache()
Definition: G4Cache.hh:280
std::vector< value_type > vector_type
Definition: G4Cache.hh:135
int G4int
Definition: G4Types.hh:78
#define G4MUTEX_INITIALIZER
Definition: G4Threading.hh:158
vector_type::iterator iterator
Definition: G4Cache.hh:137
virtual ~G4Cache()
Definition: G4Cache.hh:237
G4bool Has(const key_type &k)
Definition: G4Cache.hh:394
size_type Erase(const key_type &k)
Definition: G4Cache.hh:406
virtual ~G4MapCache()
Definition: G4Cache.hh:351
const int & GetId() const
Definition: G4Cache.hh:109
bool G4bool
Definition: G4Types.hh:79
void Clear()
Definition: G4Cache.hh:338
map_type::const_iterator const_iterator
Definition: G4Cache.hh:176
VALTYPE & GetCache(unsigned int id) const
value_type & operator[](const G4int &idx)
Definition: G4Cache.hh:319
void Push_back(const value_type &val)
Definition: G4Cache.hh:304
G4int G4Mutex
Definition: G4Threading.hh:156
iterator Find(const key_type &k)
Definition: G4Cache.hh:388
int id
Definition: G4Cache.hh:111
iterator Begin()
Definition: G4Cache.hh:326
map_type::iterator iterator
Definition: G4Cache.hh:175
map_type::size_type size_type
Definition: G4Cache.hh:174
KEYTYPE key_type
Definition: G4Cache.hh:171
iterator Begin()
Definition: G4Cache.hh:377
std::map< key_type, value_type > map_type
Definition: G4Cache.hh:173
G4Cache()
Definition: G4Cache.hh:216
value_type & operator[](const key_type &k)
Definition: G4Cache.hh:412
static unsigned int dstrctr
Definition: G4Cache.hh:115
void Put(const value_type &val) const
Definition: G4Cache.hh:257
std::pair< iterator, G4bool > Insert(const key_type &k, const value_type &v)
Definition: G4Cache.hh:362
VALTYPE value_type
Definition: G4Cache.hh:172
static G4Mutex gMutex
Definition: G4Cache.hh:113
vector_type::size_type size_type
Definition: G4Cache.hh:136