Belle II Software  release-08-01-10
DataStore.h
1 /**************************************************************************
2  * basf2 (Belle II Analysis Software Framework) *
3  * Author: The Belle II Collaboration *
4  * *
5  * See git log for contributors and copyright holders. *
6  * This file is licensed under LGPL-3.0, see LICENSE.md. *
7  **************************************************************************/
8 #pragma once
9 
10 #include <framework/datastore/StoreEntry.h>
11 #include <framework/core/BitMask.h>
12 
13 #if defined(__CINT__) || defined(__ROOTCLING__) || defined(R__DICTIONARY_FILENAME)
14 //a few methods use these, but are only included in dictionaries
15 #include <framework/datastore/RelationVector.h>
16 #include <framework/datastore/RelationEntry.h>
17 #endif
18 
19 #include <regex>
20 #include <array>
21 #include <vector>
22 #include <string>
23 #include <map>
24 
25 class TObject;
26 class TClass;
27 
28 namespace Belle2 {
33  class StoreAccessorBase;
34  class DependencyMap;
35  class RelationVectorBase;
36  template <class T> class RelationVector;
37  struct RelationEntry;
38 
51  class DataStore {
52  public:
53  //----------------------------------- enums and typedefs ---------------------------------------------------
58  enum EDurability {
61  };
63  const static int c_NDurabilityTypes = 2;
64 
69  enum EStoreFlags {
70  c_WriteOut = 0,
73  };
74 
76  enum ESearchSide {
80  };
81 
82 
85 
86  // Convenient typedefs.
87  typedef std::map<std::string, StoreEntry> StoreEntryMap;
88  typedef StoreEntryMap::iterator StoreEntryIter;
89  typedef StoreEntryMap::const_iterator StoreEntryConstIter;
90  typedef std::array<StoreEntryMap, c_NDurabilityTypes> DataStoreContents;
100  static bool s_DoCleanup;
101 
102 
103  //--------------------------------- Instance ---------------------------------------------------------------
108  static DataStore& Instance();
109 
110  //--------------------------------- default name stuff -----------------------------------------------------
111 
114  static TClass* getTClassFromDefaultObjectName(const std::string& objectName);
115 
118  static TClass* getTClassFromDefaultArrayName(const std::string& arrayName);
119 
121  static std::string defaultObjectName(const std::string& classname);
122 
124  static std::string defaultObjectName(const TClass* t);
125 
127  template<class T> static std::string defaultObjectName()
128  {
129  const static std::string s = defaultObjectName(T::Class_Name());
130  return s;
131  }
132 
134  static std::string objectName(const TClass* t, const std::string& name);
135 
137  template<class T> static std::string objectName(const std::string& name)
138  {
139  return ((name.empty()) ? defaultObjectName<T>() : name);
140  }
141 
143  static std::string defaultArrayName(const std::string& classname)
144  {
145  const std::string& objName = defaultObjectName(classname);
146  std::string s;
147  s.reserve(objName.length() + 1);
148  s += objName;
149  s += 's';
150  return s;
151  }
152 
154  static std::string defaultArrayName(const TClass* t);
155 
157  template<class T> static std::string defaultArrayName()
158  {
159  const static std::string s = defaultArrayName(defaultObjectName<T>());
160  return s;
161  }
162 
164  static std::string arrayName(const TClass* t, const std::string& name);
165 
167  template<class T> static std::string arrayName(const std::string& name)
168  {
169  return ((name.empty()) ? defaultArrayName<T>() : name);
170  }
171 
173  template<class FROM, class TO> static std::string defaultRelationName()
174  {
175  const static std::string s = relationName(defaultArrayName<FROM>(), defaultArrayName<TO>());
176  return s;
177  }
178 
180  static std::string relationName(const std::string& fromName, const std::string& toName,
181  std::string const& namedRelation = "")
182  {
183  std::string s;
184  s.reserve(fromName.length() + toName.length() + 2);
185  s += fromName;
186  s += "To";
187  s += toName;
188  if (namedRelation.length() > 0) {
189  s += "Named";
190  // Characters are not escaped here, because in registerRelation, the namedRelation
191  // given is checked to contain no special characters or white spaces
192  s += namedRelation;
193  }
194  return s;
195  }
196 
197  //------------------------------ Accessing objects and arrays ----------------------------------------------
212  bool registerEntry(const std::string& name, EDurability durability,
213  TClass* objClass, bool array, EStoreFlags storeFlags);
214 
226  bool registerRelation(const StoreAccessorBase& fromArray, const StoreAccessorBase& toArray, EDurability durability,
227  EStoreFlags storeFlags, const std::string& namedRelation);
228 
238  bool hasRelation(const StoreAccessorBase& fromArray, const StoreAccessorBase& toArray, EDurability durability,
239  const std::string& namedRelation);
240 
248  bool requireInput(const StoreAccessorBase& accessor);
249 
260  bool requireRelation(const StoreAccessorBase& fromArray, const StoreAccessorBase& toArray, EDurability durability,
261  std::string const& namedRelation);
262 
271  bool optionalInput(const StoreAccessorBase& accessor);
272 
283  bool optionalRelation(const StoreAccessorBase& fromArray, const StoreAccessorBase& toArray, EDurability durability,
284  std::string const& namedRelation);
285 
294  StoreEntry* getEntry(const StoreAccessorBase& accessor);
295 
303  TObject** getObject(const StoreAccessorBase& accessor);
304 
313  bool createObject(TObject* object, bool replace, const StoreAccessorBase& accessor);
314 
319  void replaceData(const StoreAccessorBase& from, const StoreAccessorBase& to);
320 
325  StoreEntryMap& getStoreEntryMap(EDurability durability) { return m_storeEntryMap[durability]; }
326 
327 
339  void addRelation(const TObject* fromObject, StoreEntry*& fromEntry, int& fromIndex, const TObject* toObject, StoreEntry*& toEntry,
340  int& toIndex, float weight, const std::string& namedRelation);
341 
342 
357  RelationVectorBase getRelationsWith(ESearchSide searchSide, const TObject* object, StoreEntry*& entry, int& index,
358  const TClass* withClass, const std::string& withName, const std::string& namedRelation);
359 
374  Belle2::RelationEntry getRelationWith(ESearchSide searchSide, const TObject* object, StoreEntry*& entry, int& index,
375  const TClass* withClass, const std::string& withName, const std::string& namedRelation);
376 
387  static void addRelationFromTo(const TObject* fromObject, const TObject* toObject, float weight = 1.0,
388  const std::string& namedRelation = "")
389  {
390  DataStore::StoreEntry* fromEntry = nullptr;
391  int fromIndex = -1;
392  StoreEntry* toEntry = nullptr;
393  int toIndex = -1;
394  Instance().addRelation(fromObject, fromEntry, fromIndex, toObject, toEntry, toIndex, weight, namedRelation);
395  }
396 
412  template <class T> static RelationVector<T> getRelationsWithObj(const TObject* object, const std::string& name = "",
413  const std::string& namedRelation = "")
414  {
415  StoreEntry* storeEntry = nullptr;
416  int index = -1;
417  return RelationVector<T>(Instance().getRelationsWith(c_BothSides, object, storeEntry, index, T::Class(), name, namedRelation));
418  }
419 
432  template <class T> static T* getRelated(const TObject* object, const std::string& name = "", const std::string& namedRelation = "")
433  {
434  if (!object) return nullptr;
435  StoreEntry* storeEntry = nullptr;
436  int index = -1;
437  return static_cast<T*>(DataStore::Instance().getRelationWith(c_BothSides, object, storeEntry, index, T::Class(), name,
438  namedRelation).object);
439  }
440 
441 #if defined(__CINT__) || defined(__ROOTCLING__) || defined(R__DICTIONARY_FILENAME)
442 
447  static RelationVector<TObject> getRelationsWithObj(const TObject* object, const std::string& name)
448  {
449  return getRelationsWithObj<TObject>(object, name);
450  }
451  static TObject* getRelated(const TObject* object, const std::string& name) { return getRelated<TObject>(object, name); }
453 #endif
454 
468  bool findStoreEntry(const TObject* object, StoreEntry*& entry, int& index);
469 
474  std::vector<std::string> getListOfRelatedArrays(const StoreAccessorBase& array) const;
475 
477  std::vector<std::string> getListOfArrays(const TClass* arrayClass, EDurability durability) const;
478 
483  std::vector<std::string> getListOfObjects(const TClass* objClass, EDurability durability) const;
484 
487  std::vector<std::string> getListOfRelations(EDurability durability) const;
488 
491  std::vector<std::string> getSortedListOfDataStore(EDurability durability) const;
492 
493 
494  //------------------------------ For internal use --------------------------------------------------
499  void setInitializeActive(bool active);
500 
502  bool getInitializeActive() const { return m_initializeActive; }
503 
508  void invalidateData(EDurability durability);
509 
515  void reset(EDurability durability);
516 
521  void reset();
522 
525 
526 
528  void createNewDataStoreID(const std::string& id);
530  void createEmptyDataStoreID(const std::string& id);
532  std::string currentID() const;
534  void switchID(const std::string& id);
536  void copyEntriesTo(const std::string& id, const std::vector<std::string>& entrylist_event = {}, bool mergeEntries = false);
538  void copyContentsTo(const std::string& id, const std::vector<std::string>& entrylist_event = {});
540  void mergeContentsTo(const std::string& id, const std::vector<std::string>& entrylist_event = {});
541 
542  private:
544  explicit DataStore();
546  DataStore(const DataStore&) = delete;
548  DataStore& operator=(const DataStore&) = delete;
550  ~DataStore();
551 
560  bool checkType(const StoreEntry& entry, const StoreAccessorBase& accessor) const;
561 
568  const std::vector<std::string>& getArrayNames(const std::string& arrayName, const TClass* arrayClass,
569  EDurability durability = c_Event) const;
570 
575  static void updateRelationsObjectCache(StoreEntry& entry);
576 
582  public:
585  void clear();
587  void reset(EDurability durability);
589  void invalidateData(EDurability durability);
591  const StoreEntryMap& operator [](int durability) const { return m_entries[m_currentIdx][durability]; }
593  StoreEntryMap& operator [](int durability)
594  {
595  //reuse const implementation
596  const SwitchableDataStoreContents* this2 = this;
597  return const_cast<StoreEntryMap&>((*this2)[durability]);
598  }
599 
601  void switchID(const std::string& id);
603  const std::string& currentID() const { return m_currentID; }
605  void copyEntriesTo(const std::string& id, const std::vector<std::string>& entrylist_event = {}, bool mergeEntries = false);
607  void copyContentsTo(const std::string& id, const std::vector<std::string>& entrylist_event = {});
609  void mergeContentsTo(const std::string& id, const std::vector<std::string>& entrylist_event = {});
611  void createNewDataStoreID(const std::string& id);
613  void createEmptyDataStoreID(const std::string& id);
614  private:
615  std::vector<DataStoreContents> m_entries;
616  std::map<std::string, int> m_idToIndexMap;
617  std::string m_currentID = "";
618  int m_currentIdx = 0;
619  };
622 
623 
629 
634  const std::regex m_regexNamedRelationCheck = std::regex("^[a-zA-Z]*$");
635 
638  };
639 
642 } // namespace Belle2
Encapsulates DataStoreContents, but allows transparently switching between different versions ('DataS...
Definition: DataStore.h:581
const std::string & currentID() const
returns ID of current DataStore.
Definition: DataStore.h:603
std::string m_currentID
currently active DataStore ID.
Definition: DataStore.h:617
void createNewDataStoreID(const std::string &id)
creates new datastore with given id, copying the registered objects/arrays from the current one.
Definition: DataStore.cc:827
std::vector< DataStoreContents > m_entries
wrapped DataStoreContents.
Definition: DataStore.h:615
void createEmptyDataStoreID(const std::string &id)
creates empty datastore with given id.
Definition: DataStore.cc:838
void copyEntriesTo(const std::string &id, const std::vector< std::string > &entrylist_event={}, bool mergeEntries=false)
copy entries (not contents) of current DataStore to the DataStore with given ID.
Definition: DataStore.cc:850
void switchID(const std::string &id)
switch to DataStore with given ID.
Definition: DataStore.cc:1144
std::map< std::string, int > m_idToIndexMap
Maps DataStore ID to index in m_entries.
Definition: DataStore.h:616
void mergeContentsTo(const std::string &id, const std::vector< std::string > &entrylist_event={})
merge contents (actual array / object contents) of current DataStore to the DataStore with given ID.
Definition: DataStore.cc:987
int m_currentIdx
index of currently active DataStore.
Definition: DataStore.h:618
void copyContentsTo(const std::string &id, const std::vector< std::string > &entrylist_event={})
copy contents (actual array / object contents) of current DataStore to the DataStore with given ID.
Definition: DataStore.cc:946
const StoreEntryMap & operator[](int durability) const
Get StoreEntry map for given durability (and current DataStore ID).
Definition: DataStore.h:591
void clear()
same as calling reset() for all durabilities + all non-default datastore IDs are removed.
Definition: DataStore.cc:1154
void reset(EDurability durability)
Frees memory occupied by data store items and removes all objects from the map.
Definition: DataStore.cc:1167
void invalidateData(EDurability durability)
Clears all registered StoreEntry objects of a specified durability, invalidating all objects.
Definition: DataStore.cc:1177
In the store you can park objects that have to be accessed by various modules.
Definition: DataStore.h:51
static std::string objectName(const TClass *t, const std::string &name)
Return the storage name for an object of the given TClass and name.
Definition: DataStore.cc:151
StoreEntryMap::const_iterator StoreEntryConstIter
const_iterator for a StoreEntry map.
Definition: DataStore.h:89
std::array< StoreEntryMap, c_NDurabilityTypes > DataStoreContents
StoreEntry maps for each durability.
Definition: DataStore.h:90
static void addRelationFromTo(const TObject *fromObject, const TObject *toObject, float weight=1.0, const std::string &namedRelation="")
Add a relation from an object in a store array to another object in a store array.
Definition: DataStore.h:387
std::vector< std::string > getListOfRelatedArrays(const StoreAccessorBase &array) const
Returns a list of names of arrays which have registered relations that point to or from 'array'.
Definition: DataStore.cc:640
std::vector< std::string > getListOfRelations(EDurability durability) const
Returns a list of names of StoreObjPtr-objects whose class is (or inherits from) RelationContainer.
Definition: DataStore.cc:688
bool getInitializeActive() const
Are we currently initializing modules?
Definition: DataStore.h:502
void createNewDataStoreID(const std::string &id)
creates new datastore with given id, copying the registered objects/arrays from the current one.
Definition: DataStore.cc:779
static std::string defaultArrayName(const std::string &classname)
Return the default storage name for an given class name.
Definition: DataStore.h:143
void createEmptyDataStoreID(const std::string &id)
creates empty datastore with given id.
Definition: DataStore.cc:784
DependencyMap & getDependencyMap()
Return map of depedencies between modules.
Definition: DataStore.h:524
bool findStoreEntry(const TObject *object, StoreEntry *&entry, int &index)
Find an object in an array in the data store.
Definition: DataStore.cc:398
const std::vector< std::string > & getArrayNames(const std::string &arrayName, const TClass *arrayClass, EDurability durability=c_Event) const
Returns a vector with the names of store arrays matching the given name and class.
Definition: DataStore.cc:465
void copyEntriesTo(const std::string &id, const std::vector< std::string > &entrylist_event={}, bool mergeEntries=false)
copy entries (not contents) of current DataStore to the DataStore with given ID.
Definition: DataStore.cc:805
static std::string defaultObjectName()
Return the default storage name for an object of the given type.
Definition: DataStore.h:127
bool checkType(const StoreEntry &entry, const StoreAccessorBase &accessor) const
Check whether the given entry and the requested class match.
Definition: DataStore.cc:170
bool optionalRelation(const StoreAccessorBase &fromArray, const StoreAccessorBase &toArray, EDurability durability, std::string const &namedRelation)
Register the given relation as an optional input.
Definition: DataStore.cc:766
EStoreFlags
Flags describing behaviours of objects etc.
Definition: DataStore.h:69
@ c_WriteOut
Object/array should be saved by output modules.
Definition: DataStore.h:70
@ c_DontWriteOut
Object/array should be NOT saved by output modules.
Definition: DataStore.h:71
@ c_ErrorIfAlreadyRegistered
If the object/array was already registered, produce an error (aborting initialisation).
Definition: DataStore.h:72
void switchID(const std::string &id)
switch to DataStore with given ID.
Definition: DataStore.cc:794
std::vector< std::string > getSortedListOfDataStore(EDurability durability) const
Returns a (sorted) list of all the content of the DataStore (Objs-Arrays-Relations).
Definition: DataStore.cc:703
StoreEntryMap::iterator StoreEntryIter
Iterator for a StoreEntry map.
Definition: DataStore.h:88
const std::regex m_regexNamedRelationCheck
Regular expression to check that no special characters and no white spaces are in the string given fo...
Definition: DataStore.h:634
static TClass * getTClassFromDefaultArrayName(const std::string &arrayName)
Tries to deduce the TClass from a default array name, which is generally the name of the C++ class wi...
Definition: DataStore.cc:116
void mergeContentsTo(const std::string &id, const std::vector< std::string > &entrylist_event={})
merge contents (actual array / object contents) of current DataStore to the DataStore with given ID.
Definition: DataStore.cc:815
static std::string objectName(const std::string &name)
Return the storage name for an object of the given type and name.
Definition: DataStore.h:137
void addRelation(const TObject *fromObject, StoreEntry *&fromEntry, int &fromIndex, const TObject *toObject, StoreEntry *&toEntry, int &toIndex, float weight, const std::string &namedRelation)
Add a relation from an object in a store array to another object in a store array.
Definition: DataStore.cc:492
bool registerRelation(const StoreAccessorBase &fromArray, const StoreAccessorBase &toArray, EDurability durability, EStoreFlags storeFlags, const std::string &namedRelation)
Register a relation in the DataStore map.
Definition: DataStore.cc:244
static TClass * getTClassFromDefaultObjectName(const std::string &objectName)
Tries to deduce the TClass from a default object name, which is generally the name of the C++ class.
Definition: DataStore.cc:105
StoreEntryMap & getStoreEntryMap(EDurability durability)
Get a reference to the object/array map.
Definition: DataStore.h:325
DataStore()
Hidden constructor, as it is a singleton.
Definition: DataStore.cc:61
static RelationVector< T > getRelationsWithObj(const TObject *object, const std::string &name="", const std::string &namedRelation="")
Get the relations between an object and other objects in a store array.
Definition: DataStore.h:412
DependencyMap * m_dependencyMap
Collect information about the dependencies between modules.
Definition: DataStore.h:637
~DataStore()
Destructor.
Definition: DataStore.cc:65
static std::string defaultArrayName()
Return the default storage name for an array of the given type.
Definition: DataStore.h:157
std::vector< std::string > getListOfArrays(const TClass *arrayClass, EDurability durability) const
Returns a list of names of arrays which are of type (or inherit from) arrayClass.
Definition: DataStore.cc:666
ESearchSide
Which side of relations should be returned?
Definition: DataStore.h:76
@ c_BothSides
Combination of c_FromSide and c_ToSide.
Definition: DataStore.h:79
@ c_FromSide
Return relations/objects pointed from (to a given object).
Definition: DataStore.h:77
@ c_ToSide
Return relations/objects pointed to (from a given object).
Definition: DataStore.h:78
static void updateRelationsObjectCache(StoreEntry &entry)
For an array containing RelationsObjects, update index and entry cache for entire contents.
Definition: DataStore.cc:387
static const int c_NDurabilityTypes
Number of Durability Types.
Definition: DataStore.h:63
std::vector< std::string > getListOfObjects(const TClass *objClass, EDurability durability) const
Returns a list of names of StoreObjPtr-objects whose class is (or inherits from) objClass.
Definition: DataStore.cc:671
static std::string defaultRelationName()
Return the default storage name for a relation between the given types.
Definition: DataStore.h:173
void copyContentsTo(const std::string &id, const std::vector< std::string > &entrylist_event={})
copy contents (actual array / object contents) of current DataStore to the DataStore with given ID.
Definition: DataStore.cc:810
bool requireInput(const StoreAccessorBase &accessor)
Produce ERROR message if no entry of the given type is registered in the DataStore.
Definition: DataStore.cc:722
EDurability
Durability types.
Definition: DataStore.h:58
@ c_Persistent
Object is available during entire execution time.
Definition: DataStore.h:60
@ c_Event
Different object in each event, all objects/arrays are invalidated after event() function has been ca...
Definition: DataStore.h:59
Belle2::StoreEntry StoreEntry
Wraps a stored array/object, stored under unique (name, durability) key.
Definition: DataStore.h:84
bool requireRelation(const StoreAccessorBase &fromArray, const StoreAccessorBase &toArray, EDurability durability, std::string const &namedRelation)
Produce ERROR message if no relation of given durability exists between fromArray and toArray (in tha...
Definition: DataStore.cc:749
std::string currentID() const
returns ID of current DataStore.
Definition: DataStore.cc:789
static T * getRelated(const TObject *object, const std::string &name="", const std::string &namedRelation="")
Get the object to or from which another object has a relation.
Definition: DataStore.h:432
static DataStore & Instance()
Instance of singleton Store.
Definition: DataStore.cc:54
bool hasRelation(const StoreAccessorBase &fromArray, const StoreAccessorBase &toArray, EDurability durability, const std::string &namedRelation)
Check for the existence of a relation in the DataStore map.
Definition: DataStore.cc:271
void setInitializeActive(bool active)
Setter for m_initializeActive.
Definition: DataStore.cc:94
static std::string relationName(const std::string &fromName, const std::string &toName, std::string const &namedRelation="")
Return storage name for a relation between two arrays of the given names.
Definition: DataStore.h:180
static bool s_DoCleanup
Global flag to to decide if we can do normal cleanup.
Definition: DataStore.h:100
void reset()
Clears contents of the datastore (all durabilities)
Definition: DataStore.cc:74
StoreEntry * getEntry(const StoreAccessorBase &accessor)
Check whether an entry with the correct type is registered in the DataStore map and return it.
Definition: DataStore.cc:294
void invalidateData(EDurability durability)
Clears all registered StoreEntry objects of a specified durability, invalidating all objects.
Definition: DataStore.cc:715
static std::string arrayName(const std::string &name)
Return the storage name for an object of the given type and name.
Definition: DataStore.h:167
RelationVectorBase getRelationsWith(ESearchSide searchSide, const TObject *object, StoreEntry *&entry, int &index, const TClass *withClass, const std::string &withName, const std::string &namedRelation)
Get the relations between an object and other objects in a store array.
Definition: DataStore.cc:545
Belle2::RelationEntry getRelationWith(ESearchSide searchSide, const TObject *object, StoreEntry *&entry, int &index, const TClass *withClass, const std::string &withName, const std::string &namedRelation)
Get the first relation between an object and another object in a store array.
Definition: DataStore.cc:597
bool createObject(TObject *object, bool replace, const StoreAccessorBase &accessor)
Create a new object/array in the DataStore or add an existing one.
Definition: DataStore.cc:316
TObject ** getObject(const StoreAccessorBase &accessor)
Get a pointer to a pointer of an object in the DataStore.
Definition: DataStore.cc:306
static std::string arrayName(const TClass *t, const std::string &name)
Return the storage name for an object of the given TClass and name.
Definition: DataStore.cc:164
bool m_initializeActive
True if modules are currently being initialized.
Definition: DataStore.h:628
DataStore & operator=(const DataStore &)=delete
no assignment operator
bool registerEntry(const std::string &name, EDurability durability, TClass *objClass, bool array, EStoreFlags storeFlags)
Register an entry in the DataStore map.
Definition: DataStore.cc:190
bool optionalInput(const StoreAccessorBase &accessor)
Register the given object/array as an optional input.
Definition: DataStore.cc:739
DataStore(const DataStore &)=delete
no copy constructor
SwitchableDataStoreContents m_storeEntryMap
Maps (name, durability) key to StoreEntry objects.
Definition: DataStore.h:621
void replaceData(const StoreAccessorBase &from, const StoreAccessorBase &to)
For two StoreAccessors of same type, move all data in 'from' into 'to', discarding previous contents ...
Definition: DataStore.cc:343
std::map< std::string, StoreEntry > StoreEntryMap
Map for StoreEntries.
Definition: DataStore.h:87
Collect information about the dependencies between modules.
Definition: DependencyMap.h:29
base class for RelationVector<T>
Class for type safe access to objects that are referred to in relations.
Base class for StoreObjPtr and StoreArray for easier common treatment.
ADD_BITMASK_OPERATORS(DataStore::EStoreFlags)
Add bitmask operators to DataStore::EStoreFlags.
Abstract base class for different kinds of events.
Struct for relations.
Definition: RelationEntry.h:24
TObject * object
Pointer to the object.
Definition: RelationEntry.h:32
Wraps a stored array/object, stored under unique (name, durability) key.
Definition: StoreEntry.h:22