Logo ROOT   6.30.04
Reference Guide
 All Namespaces Files Pages
RooCacheManager.h
Go to the documentation of this file.
1 /*****************************************************************************
2  * Project: RooFit *
3  * Package: RooFitCore *
4  * File: $Id$
5  * Authors: *
6  * WV, Wouter Verkerke, UC Santa Barbara, verkerke@slac.stanford.edu *
7  * DK, David Kirkby, UC Irvine, dkirkby@uci.edu *
8  * *
9  * Copyright (c) 2000-2005, Regents of the University of California *
10  * and Stanford University. All rights reserved. *
11  * *
12  * Redistribution and use in source and binary forms, *
13  * with or without modification, are permitted according to the terms *
14  * listed in LICENSE (http://roofit.sourceforge.net/license.txt) *
15  *****************************************************************************/
16 #ifndef ROO_CACHE_MANAGER
17 #define ROO_CACHE_MANAGER
18 
19 #include "Rtypes.h"
20 
21 #include "RooMsgService.h"
22 #include "RooNormSetCache.h"
23 #include "RooAbsReal.h"
24 #include "RooArgSet.h"
25 #include "RooArgList.h"
26 #include "RooAbsCache.h"
27 #include "RooAbsCacheElement.h"
28 #include "RooNameReg.h"
29 #include <vector>
30 
31 class RooNameSet ;
32 
33 
34 template<class T>
35 class RooCacheManager : public RooAbsCache {
36 
37 public:
38 
39  RooCacheManager(Int_t maxSize=2) ;
40  RooCacheManager(RooAbsArg* owner, Int_t maxSize=2) ;
41  RooCacheManager(const RooCacheManager& other, RooAbsArg* owner=0) ;
42  virtual ~RooCacheManager() ;
43 
44  T* getObj(const RooArgSet* nset, Int_t* sterileIndex=0, const TNamed* isetRangeName=0) {
45  // Getter function without integration set
46  return getObj(nset,0,sterileIndex,isetRangeName) ;
47  }
48 
49  Int_t setObj(const RooArgSet* nset, T* obj, const TNamed* isetRangeName=0) {
50  // Setter function without integration set
51  return setObj(nset,0,obj,isetRangeName) ;
52  }
53 
54  inline T* getObj(const RooArgSet* nset, const RooArgSet* iset, Int_t* sterileIdx, const char* isetRangeName) {
55  if (_wired) return _object[0] ;
56  return getObj(nset,iset,sterileIdx,RooNameReg::ptr(isetRangeName)) ;
57  }
58 
59  T* getObj(const RooArgSet* nset, const RooArgSet* iset, Int_t* sterileIndex=0, const TNamed* isetRangeName=0) ;
60  Int_t setObj(const RooArgSet* nset, const RooArgSet* iset, T* obj, const TNamed* isetRangeName=0) ;
61 
62  void reset() ;
63  virtual void sterilize() ;
64 
65  Int_t lastIndex() const {
66  // Return index of slot used in last get or set operation
67  return _lastIndex ;
68  }
69  Int_t cacheSize() const {
70  // Return size of cache
71  return _size ;
72  }
73 
74  virtual Bool_t redirectServersHook(const RooAbsCollection& /*newServerList*/, Bool_t /*mustReplaceAll*/,
75  Bool_t /*nameChange*/, Bool_t /*isRecursive*/) {
76  // Interface function to intercept server redirects
77  return kFALSE ;
78  }
79  virtual void operModeHook() {
80  // Interface function to intercept cache operation mode changes
81  }
82  virtual void printCompactTreeHook(std::ostream&, const char *) {
83  // Interface function to cache add contents to output in tree printing mode
84  }
85 
86  T* getObjByIndex(Int_t index) const ;
87  const RooNameSet* nameSet1ByIndex(Int_t index) const ;
88  const RooNameSet* nameSet2ByIndex(Int_t index) const ;
89 
90  virtual void insertObjectHook(T&) {
91  // Interface function to perform post-insert operations on cached object
92  }
93 
94  void wireCache() {
95  if (_size==0) {
96  oocoutI(_owner,Optimization) << "RooCacheManager::wireCache(" << _owner->GetName() << ") no cached elements!" << std::endl ;
97  } else if (_size==1) {
98  oocoutI(_owner,Optimization) << "RooCacheManager::wireCache(" << _owner->GetName() << ") now wiring cache" << std::endl ;
99  _wired=kTRUE ;
100  } else if (_size>1) {
101  oocoutI(_owner,Optimization) << "RooCacheManager::wireCache(" << _owner->GetName() << ") cache cannot be wired because it contains more than one element" << std::endl ;
102  }
103  }
104 
105 protected:
106 
107  Int_t _maxSize ; //! Maximum size
108  Int_t _size ; //! Actual use
109  Int_t _lastIndex ; //! Last slot accessed
110 
111  std::vector<RooNormSetCache> _nsetCache ; //! Normalization/Integration set manager
112  std::vector<T*> _object ; //! Payload
113  Bool_t _wired ; //! In wired mode, there is a single payload which is returned always
114 
115  ClassDef(RooCacheManager,2) // Cache Manager class generic objects
116 } ;
117 
118 
119 /// Constructor for simple caches without RooAbsArg payload. A cache
120 /// made with this constructor is not registered with its owner
121 /// and will not receive information on server redirects and
122 /// cache operation mode changes.
123 template<class T>
124 RooCacheManager<T>::RooCacheManager(Int_t maxSize) : RooAbsCache(0)
125 {
126  _maxSize = maxSize ;
127  _nsetCache.resize(_maxSize) ; // = new RooNormSetCache[maxSize] ;
128  _object.resize(_maxSize,0) ; // = new T*[maxSize] ;
129  _wired = kFALSE ;
130 }
131 
132 
133 /// Constructor for simple caches with RooAbsArg derived payload. A cache
134 /// made with this constructor is registered with its owner
135 /// and will receive information on server redirects and
136 /// cache operation mode changes.
137 template<class T>
138 RooCacheManager<T>::RooCacheManager(RooAbsArg* owner, Int_t maxSize) : RooAbsCache(owner)
139 {
140  _maxSize = maxSize ;
141  _size = 0 ;
142 
143  _nsetCache.resize(_maxSize) ; // = new RooNormSetCache[maxSize] ;
144  _object.resize(_maxSize,0) ; // = new T*[maxSize] ;
145  _wired = kFALSE ;
146  _lastIndex = -1 ;
147 
148  Int_t i ;
149  for (i=0 ; i<_maxSize ; i++) {
150  _object[i]=0 ;
151  }
152 
153 }
154 
155 /// Copy constructor.
156 template<class T>
157 RooCacheManager<T>::RooCacheManager(const RooCacheManager& other, RooAbsArg* owner) : RooAbsCache(other,owner)
158 {
159  _maxSize = other._maxSize ;
160  _size = other._size ;
161 
162  _nsetCache.resize(_maxSize) ; // = new RooNormSetCache[_maxSize] ;
163  _object.resize(_maxSize,0) ; // = new T*[_maxSize] ;
164  _wired = kFALSE ;
165  _lastIndex = -1 ;
166 
167  //std::cout << "RooCacheManager:cctor(" << this << ") other = " << &other << " _size=" << _size << " _maxSize = " << _maxSize << std::endl ;
168 
169  Int_t i ;
170  for (i=0 ; i<other._size ; i++) {
171  _nsetCache[i].initialize(other._nsetCache[i]) ;
172  _object[i] = 0 ;
173  }
174 
175  for (i=other._size ; i<_maxSize ; i++) {
176  _object[i] = 0 ;
177  }
178 }
179 
180  /// Destructor
181 template<class T>
182 RooCacheManager<T>::~RooCacheManager()
183 {
184  for (int i=0 ; i<_size ; i++) {
185  delete _object[i] ;
186  }
187 }
188 
189 
190  /// Clear the cache
191 template<class T>
192 void RooCacheManager<T>::reset()
193 {
194  for (int i=0 ; i<_maxSize ; i++) {
195  delete _object[i] ;
196  _object[i]=0 ;
197  _nsetCache[i].clear() ;
198  }
199  _lastIndex = -1 ;
200  _size = 0 ;
201 }
202 
203 
204 /// Clear the cache payload but retain slot mapping w.r.t to
205 /// normalization and integration sets.
206 template<class T>
207 void RooCacheManager<T>::sterilize()
208 {
209  Int_t i ;
210  for (i=0 ; i<_maxSize ; i++) {
211  delete _object[i] ;
212  _object[i]=0 ;
213  }
214 }
215 
216 
217 /// Insert payload object 'obj' in cache indexed on nset,iset and isetRangeName.
218 template<class T>
219 Int_t RooCacheManager<T>::setObj(const RooArgSet* nset, const RooArgSet* iset, T* obj, const TNamed* isetRangeName)
220 {
221  // Check if object is already registered
222  Int_t sterileIdx(-1) ;
223  if (getObj(nset,iset,&sterileIdx,isetRangeName)) {
224  return lastIndex() ;
225  }
226 
227 
228  if (sterileIdx>=0) {
229  // Found sterile slot that can should be recycled [ sterileIndex only set if isetRangeName matches ]
230 
231  if (sterileIdx>=_maxSize) {
232  //cout << "RooCacheManager<T>::setObj()/SI increasing object cache size from " << _maxSize << " to " << sterileIdx+4 << endl ;
233  _maxSize = sterileIdx+4;
234  _object.resize(_maxSize,0) ;
235  _nsetCache.resize(_maxSize) ;
236  }
237 
238 
239  _object[sterileIdx] = obj ;
240 
241  // Allow optional post-processing of object inserted in cache
242  insertObjectHook(*obj) ;
243 
244  return lastIndex() ;
245  }
246 
247  if (_size>=_maxSize-1) {
248  //cout << "RooCacheManager<T>::setObj() increasing object cache size from " << _maxSize << " to " << _maxSize*2 << endl ;
249  _maxSize *=2 ;
250  _object.resize(_maxSize,0) ;
251  _nsetCache.resize(_maxSize) ;
252  }
253 
254  //cout << "RooCacheManager::setObj<T>(" << this << ") _size = " << _size << " _maxSize = " << _maxSize << endl ;
255  _nsetCache[_size].autoCache(_owner,nset,iset,isetRangeName,kTRUE) ;
256  if (_object[_size]) {
257  delete _object[_size] ;
258  }
259 
260  _object[_size] = obj ;
261  _size++ ;
262 
263  // Allow optional post-processing of object inserted in cache
264  insertObjectHook(*obj) ;
265 
266  // Unwire cache in case it was wired
267  _wired = kFALSE ;
268 
269  return _size-1 ;
270 }
271 
272 
273 /// Retrieve payload object indexed on nset,uset amd isetRangeName
274 /// If sterileIdx is not null, it is set to the index of the sterile
275 /// slot in cacse such a slot is recycled.
276 template<class T>
277 T* RooCacheManager<T>::getObj(const RooArgSet* nset, const RooArgSet* iset, Int_t* sterileIdx, const TNamed* isetRangeName)
278 {
279  // Fast-track for wired mode
280  if (_wired) {
281  if(_object[0]==0 && sterileIdx) *sterileIdx=0 ;
282  return _object[0] ;
283  }
284 
285  Int_t i ;
286  for (i=0 ; i<_size ; i++) {
287  if (_nsetCache[i].contains(nset,iset,isetRangeName)==kTRUE) {
288  _lastIndex = i ;
289  if(_object[i]==0 && sterileIdx) *sterileIdx=i ;
290  return _object[i] ;
291  }
292  }
293 
294  for (i=0 ; i<_size ; i++) {
295  if (_nsetCache[i].autoCache(_owner,nset,iset,isetRangeName,kFALSE)==kFALSE) {
296  _lastIndex = i ;
297  if(_object[i]==0 && sterileIdx) *sterileIdx=i ;
298  return _object[i] ;
299  }
300  }
301 
302  return 0 ;
303 }
304 
305 
306 /// Retrieve payload object by slot index.
307 template<class T>
308 T* RooCacheManager<T>::getObjByIndex(Int_t index) const
309 {
310  if (index<0||index>=_size) {
311  oocoutE(_owner,ObjectHandling) << "RooCacheManager::getNormListByIndex: ERROR index ("
312  << index << ") out of range [0," << _size-1 << "]" << std::endl ;
313  return 0 ;
314  }
315  return _object[index] ;
316 }
317 
318 
319 /// Retrieve RooNameSet associated with slot at given index.
320 template<class T>
321 const RooNameSet* RooCacheManager<T>::nameSet1ByIndex(Int_t index) const
322 {
323  if (index<0||index>=_size) {
324  oocoutE(_owner,ObjectHandling) << "RooCacheManager::getNormListByIndex: ERROR index ("
325  << index << ") out of range [0," << _size-1 << "]" << std::endl ;
326  return 0 ;
327  }
328  return &_nsetCache[index].nameSet1() ;
329 }
330 
331 
332 /// Retrieve RooNameSet associated with slot at given index.
333 template<class T>
334 const RooNameSet* RooCacheManager<T>::nameSet2ByIndex(Int_t index) const
335 {
336  if (index<0||index>=_size) {
337  oocoutE(_owner,ObjectHandling) << "RooCacheManager::getNormListByIndex: ERROR index ("
338  << index << ") out of range [0," << _size-1 << "]" << std::endl ;
339  return 0 ;
340  }
341  return &_nsetCache[index].nameSet2() ;
342 }
343 
344 
345 #endif