// Class RooNormSet cache manage the bookkeeping of multiple instances
// of sets of integration and normalization observables that effectively
// have the same definition. In complex function expression many
// RooArgSets with the same contents may be passed to an object that
// caches intermediate results dependent on the normalization/integration set
// To avoid unnecessary cache faulting, This class tracks all instances
// with the same contents and reports to the owner if the present nset/iset
// is truely different from the current reference. Class RooNormSet only
// evaluates each RooArgSet pointer once, it therefore assumes that
// RooArgSets with normalization and/or integration sets are not changes
// during their lifetime.
// END_HTML
#include "RooFit.h"
#include "RooNormSetCache.h"
#include "RooNormSetCache.h"
#include "RooArgSet.h"
ClassImp(RooNormSetCache)
;
#include <iostream>
using namespace std ;
RooNormSetCache::RooNormSetCache(Int_t regSize) :
_htable(0), _regSize(regSize), _nreg(0), _asArr(0), _set2RangeName(0)
{
}
RooNormSetCache::RooNormSetCache(const RooNormSetCache& other) :
_htable(0), _regSize(other._regSize), _nreg(0), _asArr(0), _set2RangeName(0)
{
initialize(other) ;
}
RooNormSetCache::~RooNormSetCache()
{
delete[] _asArr ;
if (_htable) delete _htable ;
}
void RooNormSetCache::clear()
{
_nreg = 0 ;
if (_htable) {
delete _htable ;
_htable = 0 ;
}
}
void RooNormSetCache::initialize(const RooNormSetCache& other)
{
clear() ;
Int_t i ;
for (i=0 ; i<other._nreg ; i++) {
add(other._asArr[i]._set1,other._asArr[i]._set2) ;
}
_name1 = other._name1 ;
_name2 = other._name2 ;
_set2RangeName = other._set2RangeName ;
}
void RooNormSetCache::add(const RooArgSet* set1, const RooArgSet* set2)
{
if (!_asArr) {
_asArr = new RooSetPair[_regSize] ;
}
if (!contains(set1,set2)) {
_asArr[_nreg]._set1 = (RooArgSet*)set1 ;
_asArr[_nreg]._set2 = (RooArgSet*)set2 ;
if (_htable) _htable->add((TObject*)&_asArr[_nreg]) ;
_nreg++ ;
}
if (_nreg==_regSize) _nreg = 0 ;
}
void RooNormSetCache::expand()
{
Int_t newSize = _regSize*2 ;
if (_htable) {
delete _htable ;
_htable = 0 ;
}
RooSetPair* asArr_new = new RooSetPair[newSize] ;
if (newSize>16) {
_htable = new RooHashTable(newSize,RooHashTable::Intrinsic) ;
}
Int_t i ;
for (i=0 ; i<_nreg ; i++) {
asArr_new[i]._set1 = _asArr[i]._set1 ;
asArr_new[i]._set2 = _asArr[i]._set2 ;
if (_htable) _htable->add((TObject*)&asArr_new[i]) ;
}
delete[] _asArr ;
_asArr = asArr_new ;
_regSize = newSize ;
}
Bool_t RooNormSetCache::autoCache(const RooAbsArg* self, const RooArgSet* set1, const RooArgSet* set2, const TNamed* set2RangeName, Bool_t doRefill)
{
if (set2RangeName==_set2RangeName && contains(set1,set2)) {
return kFALSE ;
}
RooNameSet nset1d,nset2d ;
RooArgSet *set1d, *set2d ;
if (self) {
set1d = set1 ? self->getObservables(*set1,kFALSE) : new RooArgSet ;
set2d = set2 ? self->getObservables(*set2,kFALSE) : new RooArgSet ;
} else {
set1d = set1 ? (RooArgSet*)set1->snapshot() : new RooArgSet ;
set2d = set2 ? (RooArgSet*)set2->snapshot() : new RooArgSet ;
}
nset1d.refill(*set1d) ;
nset2d.refill(*set2d) ;
if (nset1d==_name1&&nset2d==_name2&&_set2RangeName==set2RangeName) {
add(set1,set2) ;
delete set1d ;
delete set2d ;
return kFALSE ;
}
if (doRefill) {
clear() ;
add(set1,set2) ;
_name1.refill(*set1d) ;
_name2.refill(*set2d) ;
_set2RangeName = (TNamed*) set2RangeName ;
}
delete set1d ;
delete set2d ;
return kTRUE ;
}