Diana Software
QGlobalDataManager.hh
Go to the documentation of this file.
1 #ifndef _Q_GLOBALDATAMANAGER_HH_
2 #define _Q_GLOBALDATAMANAGER_HH_
3 
35 #include "QDiana.hh"
36 #include "QError.hh"
37 #include "QObject.hh"
38 #include "QGlobalHandle.hh"
39 #include "QGlobalLabel.hh"
40 #include "QMessage.hh"
41 #include <string>
42 #include <sstream>
43 #include <vector>
44 #include <map>
45 
47 
49  public:
54  static QGlobalDataManager& GetInstance(const std::string& owner="");
57 
60 
62  void Clear();
78  template<class Q> QError Get(const std::string& owner, GlobalHandle<Q> * gh, const std::string& inSource, bool printError=true) const;
93  template<class Q> QError Get( GlobalHandle<Q>* gh, const std::string& inSource, bool printError = true) const;
94 
104  template<class Q> const Q& Get(const std::string& owner, const std::string& name, const std::string& inSource) const
105  {
106  GlobalHandle<Q> gd(name);
107  Get(owner, &gd, inSource);
108  return gd.Get();
109  }
118  template<class Q> const Q& Get(const std::string& name, const std::string& inSource) const
119  {
120  GlobalHandle<Q> gd(name);
121  Get(&gd,inSource);
122  return gd.Get();
123  }
138  template<class Q> QError Set( GlobalHandle<Q>* gh, const std::string& outSource, bool printError = true) const;
149  template<class Q> QError Set(const std::string& name, const Q& obj, const std::string& outSource) const
150  {
151  GlobalHandle<Q> gd(name.c_str());
152  gd.Set(obj);
153  return Set(&gd,outSource);
154  }
155 
157  std::vector<QGlobalLabel> GetWriteLabels() const;
158 
160  const QObject* GetByLabel(const QGlobalLabel&) const;
161 
163  void SetOwner(const std::string& owner) { fOwner = owner; }
164 
166  void SetInputVersion(std::string versionTag) { fInputVersion = versionTag; }
167 
169  void EnableCache(const bool enable) { fCacheEnabled = enable; }
170 
172  void Dump(std::ostream& o) const;
173 
174  bool GetCacheEnable() const
175  { return fCacheEnabled;}
176 
177 private:
179  struct CachedObject {
180  std::string source;
181  std::string version;
183  };
185  std::string fOwner;
186 
187 
189  mutable std::map<QGlobalLabel, CachedObject> fDataMap;
190 
192  mutable std::map<QGlobalLabel, std::string> fDefaultMap;
193 
196 
198  static int fInstances;
199 
201  std::string fOutputVersion;
202 
205  std::string fInputVersion;
206 
209  friend class QBaseModule;
210 
211 
212 };
213 
214 template<class Q> QError QGlobalDataManager::Get( GlobalHandle<Q>* bgh, const std::string& inSource, bool printError) const
215 {
216  if(!fOwner.empty()) bgh->SetOwner(fOwner);
217  return Get(bgh->GetOwner(),bgh,inSource, printError);
218 }
219 
220 template<class Q> QError QGlobalDataManager::Get(const std::string& owner, GlobalHandle<Q>* bgh, const std::string& inSource, bool printError) const
221 {
222  bgh->SetOwner(owner);
223  if(owner == "") {
224  // look for default owner
225  const QGlobalLabel& label = bgh->GetLabel();
226  std::map<QGlobalLabel,std::string>::const_iterator idef = fDefaultMap.find(label);
227  if(idef != fDefaultMap.end())
228  bgh->SetOwner(idef->second);
229  else
230  bgh->SetOwner(bgh->GetDefaultOwner());
231  }
232 
234 
235  const QGlobalLabel& label = bgh->GetLabel();
236  Q** addr = bgh->GetAddress();
237  // if in cache return;
238  std::map<QGlobalLabel, CachedObject>::const_iterator iter = fDataMap.find(label);
239 
241 
242  if(iter != fDataMap.end()) {
243  bool cacheError = true;
244  cacheError = cacheError && inSource != "" && inSource != iter->second.source && iter->second.object;
245  cacheError = cacheError && bgh->GetVersion() != iter->second.version;
246  if(cacheError) {
247  std::stringstream msg;
248  msg<<"Cannot get object "<<std::string(label)<<" from \""<<inSource
249  <<"\"(Version=\""<<bgh->GetVersion()
250  <<"\") since it is in cache with another source: \""<<iter->second.source
251  <<"\"(Version=\""<<iter->second.version
252  <<"\"). If outside diana, you may consider to disable the cache [see QGlobalDataManager::EnableCache()]";
253  if(printError) QMessageHandler::Error("QGlobalDataManager::Get()", msg.str());
255  err.SetDescription(msg.str());
257  }
258  *addr = dynamic_cast<Q*>(iter->second.object);
259  return err;
260  }
261 
263  err.SetDescription("Object not found");
264 
265  if(inSource == "DB") {
266  err = bgh->FillFromDB();
267  } else if(!inSource.empty()) {
268  err = bgh->FillFromFile(inSource);
269  }
270  if(err != QERR_SUCCESS) {
271  if(*addr) (*addr)->InValidate();
273  // if looking for cache, do not cache non existing objects
274  if(fCacheEnabled && inSource != "") {
275  fDataMap[label].object = 0;
276  fDataMap[label].source = inSource;
277  fDataMap[label].version = bgh->GetVersion();
278  }
279  return err;
280  }
281  // cache object
282  if(fCacheEnabled) {
283  fDataMap[label].source = inSource;
284  fDataMap[label].version = bgh->GetVersion();
285  fDataMap[label].object = (*addr)->Duplicate();
286  (*addr)->FullyFill(fDataMap[label].object);
287  (*addr) = (Q*)fDataMap[label].object;
288  }
289 
290  // fill defaults:
291  QGlobalLabel defLab = bgh->GetLabel();
292  defLab.fOwner = "";
293  if(fDefaultMap.find(defLab) == fDefaultMap.end()) {
294  fDefaultMap[defLab] = bgh->GetOwner();
295  std::stringstream msg;
296  msg<<"Setting default owner \""<<bgh->GetOwner()<<"\" ";
297  msg<<"for object \""<<defLab.GetStringLabel()<<"\"";
298  QMessageHandler::Debug("QGlobalDataManager::Get()", msg.str());
299  }
300 
301  return err;
302 }
303 
304 template<class Q> QError QGlobalDataManager::Set(GlobalHandle<Q> * bgh, const std::string& outSource, bool printError) const
305 {
306  // here we print error messages on screen since we are not sure that
307  // the caller will check it.
309  if(bgh->GetOwner() == "") {
310  if(!fOwner.empty()) bgh->SetOwner(fOwner);
311  else {
313  err.SetDescription("QGlobalDataManager::Set(): Unable to Set object, since no owner has been specified (if you are using this class outside diana, set the object owner with QGlobalDataManager::SetOwner())");
314  if(printError) QMessageHandler::Error("QGlobalDataManager::Set()",err.GetDescription());
315  return err;
316  }
317  }
318 
319  if(bgh->GetVersion() == "") {
321  }
322  if(fCacheEnabled) {
323  // cache object
324  const QGlobalLabel& label = bgh->GetLabel();
325  std::map<QGlobalLabel, CachedObject>::const_iterator iter = fDataMap.find(label);
326  if(iter == fDataMap.end()) {
327  fDataMap[label].object = 0;
328  fDataMap[label].source = outSource;
329  fDataMap[label].version = bgh->GetVersion();
330  }
331  std::map<QGlobalLabel, CachedObject>::iterator iter2 = fDataMap.find(label);
332  if(bgh->IsValid()) {
333  Q** addr = bgh->GetAddress();
334  if(!iter2->second.object) iter2->second.object = (*addr)->Duplicate();
335  if((*addr) != (iter2->second.object))
336  (*addr)->FullyFill(iter2->second.object);
337  } else {
338  if(iter2->second.object) iter2->second.object->Reset();
339  }
340  }
341 
342  // save object
343  if(outSource == "DB") {
344  err = bgh->StoreOnDB();
345  } else if(!outSource.empty()){
346  err = bgh->StoreOnFile(outSource);
347  }
348  if(err != QERR_SUCCESS)
349  if(printError) QMessageHandler::Error("QGlobalDataManager::Set()",err.GetDescription());
350 
351 
352  // fill defaults:
353  QGlobalLabel defLab = bgh->GetLabel();
354  defLab.fOwner = "";
355  if(fDefaultMap.find(defLab) == fDefaultMap.end()) {
356  fDefaultMap[defLab] = bgh->GetOwner();
357  std::stringstream msg;
358  msg<<"Setting default owner \""<<bgh->GetOwner()<<"\" ";
359  msg<<"for object \""<<defLab.GetStringLabel()<<"\"";
360  QMessageHandler::Debug("QGlobalDataManager::Set()", msg.str());
361  }
362 
363  return err;
364 
365 }
366 
368 
369 #endif
err
Definition: CheckOF.C:114
#define Q_END_NAMESPACE
Definition: QDiana.hh:22
#define Q_BEGIN_NAMESPACE
Definition: QDiana.hh:20
@ QERR_GLOBAL_GENERIC
Definition: QError.hh:44
@ QERR_SUCCESS
Definition: QError.hh:27
template class to handle diana global QObject with QGlobalDataManager
virtual QError FillFromFile(const std::string &fname)
fill QObject from file fname
bool IsValid() const
check QObject validity
virtual QError StoreOnDB() const
store object on DB
virtual QError StoreOnFile(const std::string &fname) const
store object on file fname
const QGlobalLabel & GetLabel() const
Get label.
Q ** GetAddress()
get object address
void SetOwner(const std::string &owner)
set object owner
std::string GetVersion() const
Get version tag of the object, if any.
const std::string & GetOwner() const
Get object owner.
QError fGlobalDataManagerError
I/O error from the QGlobalDataManager.
const std::string & GetDefaultOwner() const
Get default owner (may be set by inheriting classes)
void Set(const Q &obj)
set the QObject
virtual QError FillFromDB()
fill object from DB
const Q & Get() const
get the QObject
void SetVersion(const std::string &tag)
set version tag of the object to be read (used by QGlobalDataManager)
Base class for modules.
Definition: QBaseModule.hh:57
error class with error type and description
Definition: QError.hh:115
Object to manage I/O (DB, file, or memory) of diana global quantities.
std::vector< QGlobalLabel > GetWriteLabels() const
get labels
static QGlobalDataManager & GetInstance(const std::string &owner="")
singleton interface provided for use in non diana executables. Do not use it within diana or root mac...
std::string fOutputVersion
Version tag of this release, used to write onto the DB. Parameter not accessible to the user.
bool fCacheEnabled
cache enabled
std::string fOwner
the module that is accessing this object
QError Set(const std::string &name, const Q &obj, const std::string &outSource) const
Set a QObject of type Q.
static QGlobalDataManager * fUniqueInstance
singleton instance
std::string fInputVersion
Version tag of the objects to be read, used to read from the DB. Parameter not accessible to the user...
void SetOwner(const std::string &owner)
set the module that is accessing this object
void EnableCache(const bool enable)
enable / disable caching of objects
std::map< QGlobalLabel, CachedObject > fDataMap
cached QObject 's
void SetInputVersion(std::string versionTag)
set the version tag of the object to be read (default = this release)
void Clear()
clear cache
QError Set(GlobalHandle< Q > *gh, const std::string &outSource, bool printError=true) const
Set a QObject using a GlobalHandle.
QError Get(const std::string &owner, GlobalHandle< Q > *gh, const std::string &inSource, bool printError=true) const
Get an object using a global handle.
const Q & Get(const std::string &owner, const std::string &name, const std::string &inSource) const
Get a QObject of type Q.
void Dump(std::ostream &o) const
Dump cached objects to stream.
QGlobalDataManager()
constructor
std::map< QGlobalLabel, std::string > fDefaultMap
default owners
const QObject * GetByLabel(const QGlobalLabel &) const
get object by label (not-recommended). Works only on cached object's
static int fInstances
number of instances
const Q & Get(const std::string &name, const std::string &inSource) const
Get a QObject of type Q owned by the caller module.
Label for global QObject's.
Definition: QGlobalLabel.hh:19
std::string fOwner
Object owner.
Definition: QGlobalLabel.hh:42
std::string GetStringLabel() const
convert label to string
static void Debug(const std::string &sender, const std::string &msg)
Definition: QMessage.hh:41
static void Error(const std::string &sender, const std::string &msg)
Definition: QMessage.hh:42
base class for objects handled by QEvent and QGlobalDataManager.
Definition: QObject.hh:76
store source of cached objects