#ifndef ROO_CACHE_MANAGER
#define ROO_CACHE_MANAGER
#include "Rtypes.h"
#include "RooMsgService.h"
#include "RooNormSetCache.h"
#include "RooAbsReal.h"
#include "RooArgSet.h"
#include "RooArgList.h"
#include "RooAbsCache.h"
#include "RooAbsCacheElement.h"
#include "RooNameReg.h"
#include <vector>
class RooNameSet ;
template<class T>
class RooCacheManager : public RooAbsCache {
public:
RooCacheManager(Int_t maxSize=2) ;
RooCacheManager(RooAbsArg* owner, Int_t maxSize=2) ;
RooCacheManager(const RooCacheManager& other, RooAbsArg* owner=0) ;
virtual ~RooCacheManager() ;
T* getObj(const RooArgSet* nset, Int_t* sterileIndex=0, const TNamed* isetRangeName=0) {
return getObj(nset,0,sterileIndex,isetRangeName) ;
}
Int_t setObj(const RooArgSet* nset, T* obj, const TNamed* isetRangeName=0) {
return setObj(nset,0,obj,isetRangeName) ;
}
inline T* getObj(const RooArgSet* nset, const RooArgSet* iset, Int_t* sterileIdx, const char* isetRangeName) {
if (_wired) return _object[0] ;
return getObj(nset,iset,sterileIdx,RooNameReg::ptr(isetRangeName)) ;
}
T* getObj(const RooArgSet* nset, const RooArgSet* iset, Int_t* sterileIndex=0, const TNamed* isetRangeName=0) ;
Int_t setObj(const RooArgSet* nset, const RooArgSet* iset, T* obj, const TNamed* isetRangeName=0) ;
void reset() ;
virtual void sterilize() ;
Int_t lastIndex() const {
return _lastIndex ;
}
Int_t cacheSize() const {
return _size ;
}
virtual Bool_t redirectServersHook(const RooAbsCollection& , Bool_t ,
Bool_t , Bool_t ) {
return kFALSE ;
}
virtual void operModeHook() {
}
virtual void printCompactTreeHook(std::ostream&, const char *) {
}
T* getObjByIndex(Int_t index) const ;
const RooNameSet* nameSet1ByIndex(Int_t index) const ;
const RooNameSet* nameSet2ByIndex(Int_t index) const ;
virtual void insertObjectHook(T&) {
}
void wireCache() {
if (_size==0) {
oocoutI(_owner,Optimization) << "RooCacheManager::wireCache(" << _owner->GetName() << ") no cached elements!" << std::endl ;
} else if (_size==1) {
oocoutI(_owner,Optimization) << "RooCacheManager::wireCache(" << _owner->GetName() << ") now wiring cache" << std::endl ;
_wired=kTRUE ;
} else if (_size>1) {
oocoutI(_owner,Optimization) << "RooCacheManager::wireCache(" << _owner->GetName() << ") cache cannot be wired because it contains more than one element" << std::endl ;
}
}
protected:
Int_t _maxSize ;
Int_t _size ;
Int_t _lastIndex ;
std::vector<RooNormSetCache> _nsetCache ;
std::vector<T*> _object ;
Bool_t _wired ;
ClassDef(RooCacheManager,2)
} ;
template<class T>
RooCacheManager<T>::RooCacheManager(Int_t maxSize) : RooAbsCache(0)
{
_maxSize = maxSize ;
_nsetCache.resize(_maxSize) ;
_object.resize(_maxSize,0) ;
_wired = kFALSE ;
}
template<class T>
RooCacheManager<T>::RooCacheManager(RooAbsArg* owner, Int_t maxSize) : RooAbsCache(owner)
{
_maxSize = maxSize ;
_size = 0 ;
_nsetCache.resize(_maxSize) ;
_object.resize(_maxSize,0) ;
_wired = kFALSE ;
_lastIndex = -1 ;
Int_t i ;
for (i=0 ; i<_maxSize ; i++) {
_object[i]=0 ;
}
}
template<class T>
RooCacheManager<T>::RooCacheManager(const RooCacheManager& other, RooAbsArg* owner) : RooAbsCache(other,owner)
{
_maxSize = other._maxSize ;
_size = other._size ;
_nsetCache.resize(_maxSize) ;
_object.resize(_maxSize,0) ;
_wired = kFALSE ;
_lastIndex = -1 ;
Int_t i ;
for (i=0 ; i<other._size ; i++) {
_nsetCache[i].initialize(other._nsetCache[i]) ;
_object[i] = 0 ;
}
for (i=other._size ; i<_maxSize ; i++) {
_object[i] = 0 ;
}
}
template<class T>
RooCacheManager<T>::~RooCacheManager()
{
Int_t i ;
for (i=0 ; i<_size ; i++) {
delete _object[i] ;
}
}
template<class T>
void RooCacheManager<T>::reset()
{
Int_t i ;
for (i=0 ; i<_maxSize ; i++) {
delete _object[i] ;
_object[i]=0 ;
_nsetCache[i].clear() ;
}
_lastIndex = -1 ;
_size = 0 ;
}
template<class T>
void RooCacheManager<T>::sterilize()
{
Int_t i ;
for (i=0 ; i<_maxSize ; i++) {
delete _object[i] ;
_object[i]=0 ;
}
}
template<class T>
Int_t RooCacheManager<T>::setObj(const RooArgSet* nset, const RooArgSet* iset, T* obj, const TNamed* isetRangeName)
{
Int_t sterileIdx(-1) ;
if (getObj(nset,iset,&sterileIdx,isetRangeName)) {
return lastIndex() ;
}
if (sterileIdx>=0) {
if (sterileIdx>=_maxSize) {
_maxSize = sterileIdx+4;
_object.resize(_maxSize,0) ;
_nsetCache.resize(_maxSize) ;
}
_object[sterileIdx] = obj ;
insertObjectHook(*obj) ;
return lastIndex() ;
}
if (_size>=_maxSize-1) {
_maxSize *=2 ;
_object.resize(_maxSize,0) ;
_nsetCache.resize(_maxSize) ;
}
_nsetCache[_size].autoCache(_owner,nset,iset,isetRangeName,kTRUE) ;
if (_object[_size]) {
delete _object[_size] ;
}
_object[_size] = obj ;
_size++ ;
insertObjectHook(*obj) ;
_wired = kFALSE ;
return _size-1 ;
}
template<class T>
T* RooCacheManager<T>::getObj(const RooArgSet* nset, const RooArgSet* iset, Int_t* sterileIdx, const TNamed* isetRangeName)
{
if (_wired) {
if(_object[0]==0 && sterileIdx) *sterileIdx=0 ;
return _object[0] ;
}
Int_t i ;
for (i=0 ; i<_size ; i++) {
if (_nsetCache[i].contains(nset,iset,isetRangeName)==kTRUE) {
_lastIndex = i ;
if(_object[i]==0 && sterileIdx) *sterileIdx=i ;
return _object[i] ;
}
}
for (i=0 ; i<_size ; i++) {
if (_nsetCache[i].autoCache(_owner,nset,iset,isetRangeName,kFALSE)==kFALSE) {
_lastIndex = i ;
if(_object[i]==0 && sterileIdx) *sterileIdx=i ;
return _object[i] ;
}
}
return 0 ;
}
template<class T>
T* RooCacheManager<T>::getObjByIndex(Int_t index) const
{
if (index<0||index>=_size) {
oocoutE(_owner,ObjectHandling) << "RooCacheManager::getNormListByIndex: ERROR index ("
<< index << ") out of range [0," << _size-1 << "]" << std::endl ;
return 0 ;
}
return _object[index] ;
}
template<class T>
const RooNameSet* RooCacheManager<T>::nameSet1ByIndex(Int_t index) const
{
if (index<0||index>=_size) {
oocoutE(_owner,ObjectHandling) << "RooCacheManager::getNormListByIndex: ERROR index ("
<< index << ") out of range [0," << _size-1 << "]" << std::endl ;
return 0 ;
}
return &_nsetCache[index].nameSet1() ;
}
template<class T>
const RooNameSet* RooCacheManager<T>::nameSet2ByIndex(Int_t index) const
{
if (index<0||index>=_size) {
oocoutE(_owner,ObjectHandling) << "RooCacheManager::getNormListByIndex: ERROR index ("
<< index << ") out of range [0," << _size-1 << "]" << std::endl ;
return 0 ;
}
return &_nsetCache[index].nameSet2() ;
}
#endif