Belle II Software  release-05-02-19
RelationIndexContainer.h
1 /**************************************************************************
2  * BASF2 (Belle Analysis Framework 2) *
3  * Copyright(C) 2010-2011 Belle II Collaboration *
4  * *
5  * Author: The Belle II Collaboration *
6  * Contributors: Martin Ritter *
7  * *
8  **************************************************************************/
9 
10 #pragma once
11 
12 #include <framework/datastore/StoreArray.h>
13 #include <framework/datastore/RelationArray.h>
14 
15 #include <boost/multi_index_container.hpp>
16 #include <boost/multi_index/ordered_index.hpp>
17 #include <boost/multi_index/member.hpp>
18 
19 namespace Belle2 {
32  class RelationIndexBase {
33  public:
34 
36  virtual ~RelationIndexBase() {}
37 
39  virtual void clear() = 0;
40  };
41 
51  template<class FROM, class TO> class RelationIndexContainer: public RelationIndexBase {
52  public:
53 
55  struct Element {
56 
59  const FROM* from_, const TO* to_, RelationElement::weight_type weight_):
60  indexFrom(indexFrom_), indexTo(indexTo_), from(from_), to(to_), weight(weight_) {}
61 
64 
67 
69  const FROM* from;
70 
72  const TO* to;
73 
76  };
77 
82  typedef boost::multi_index::multi_index_container <
83  Element,
84  boost::multi_index::indexed_by <
85  boost::multi_index::ordered_non_unique <
86  boost::multi_index::member<Element, const FROM*, &Element::from>
87  > ,
88  boost::multi_index::ordered_non_unique <
89  boost::multi_index::member<Element, const TO*, &Element::to>
90  >
91  >
92  > ElementIndex;
93 
95  operator bool() const { return m_valid; }
96 
98  const ElementIndex& index() const { return m_index; }
100  ElementIndex& index() { return m_index; }
101 
104 
106  const AccessorParams& getFromAccessorParams() const { return m_storeFrom; }
107 
109  const AccessorParams& getToAccessorParams() const { return m_storeTo; }
110 
111  protected:
116  explicit RelationIndexContainer(const RelationArray& relArray): m_storeRel(relArray), m_valid(false)
117  {
118  rebuild(true);
119  }
120 
123 
126 
132  void rebuild(bool force = false);
133 
135  virtual void clear() override { m_index.clear(); }
136 
139 
142 
145 
148 
150  bool m_valid;
151 
153  friend class RelationIndexManager;
154  };
155 
157  template<class FROM, class TO> void RelationIndexContainer<FROM, TO>::rebuild(bool force)
158  {
159  m_valid = m_storeRel.isValid();
160  if (!m_valid) {
161  B2DEBUG(100, "Relation " << m_storeRel.getName() << " does not exist, cannot build index");
162  m_index.clear();
163  m_storeFrom = AccessorParams();
164  m_storeTo = AccessorParams();
165  return;
166  }
167 
168  //Check if relation has been modified since we created the index
169  //If not, keep old contents
170  if (!force && !m_storeRel.getModified()) return;
171 
172  B2DEBUG(100, "Building index for " << m_storeRel.getName());
173 
174  //Reset modification flag
175  m_storeRel.setModified(false);
176 
177  m_index.clear();
178 
179  //Get related StoreArrays
180  m_storeFrom = m_storeRel.getFromAccessorParams();
181  m_storeTo = m_storeRel.getToAccessorParams();
182  const StoreArray<FROM> storeFrom(m_storeFrom.first, m_storeFrom.second);
183  const StoreArray<TO> storeTo(m_storeTo.first, m_storeTo.second);
184 
185  //Get number of entries in relation and stores (also checks template type versus DataStore contents)
186  const RelationElement::index_type nFrom = storeFrom.getEntries();
187  const RelationElement::index_type nTo = storeTo.getEntries();
188  const unsigned int nRel = m_storeRel.getEntries();
189 
190  //Loop over all RelationElements and add them to index
191  for (unsigned int i = 0; i < nRel; ++i) {
192  const RelationElement& r = m_storeRel[i];
193  RelationElement::index_type idxFrom = r.getFromIndex();
194  if (idxFrom >= nFrom)
195  B2FATAL("Relation " << m_storeRel.getName() << " is inconsistent: from-index (" << idxFrom << ") out of range");
196  const FROM* from = storeFrom[idxFrom];
197 
198  //Loop over index and weight vector at once
199  const auto& indices = r.getToIndices();
200  const auto& weights = r.getWeights();
201  auto itIdx = indices.begin();
202  auto itWgt = weights.begin();
203  const auto& idxEnd = indices.end();
204  for (; itIdx != idxEnd; ++itIdx, ++itWgt) {
205  const RelationElement::index_type idxTo = *itIdx;
206  if (idxTo >= nTo)
207  B2FATAL("Relation " << m_storeRel.getName() << " is inconsistent: to-index (" << idxTo << ") out of range");
208  const TO* to = storeTo[idxTo];
209  m_index.insert(Element(idxFrom, idxTo, from, to, *itWgt));
210  }
211  }
212  }
213 
215 } // end namespace Belle2
Belle2::RelationIndexContainer::Element::weight
RelationElement::weight_type weight
weight of the relation.
Definition: RelationIndexContainer.h:82
Belle2::RelationIndexBase
Baseclass for all RelationIndexContainers.
Definition: RelationIndexContainer.h:39
Belle2::RelationArray
Low-level class to create/modify relations between StoreArrays.
Definition: RelationArray.h:72
Belle2::RelationIndexContainer::m_storeFrom
AccessorParams m_storeFrom
AccessorParams of the StoreArray the relation points from.
Definition: RelationIndexContainer.h:151
Belle2::RelationIndexContainer::Element::indexTo
RelationElement::index_type indexTo
index of the element to which the relation points.
Definition: RelationIndexContainer.h:73
Belle2::RelationIndexContainer::m_index
ElementIndex m_index
Instance of the index.
Definition: RelationIndexContainer.h:145
Belle2::RelationIndexBase::~RelationIndexBase
virtual ~RelationIndexBase()
Virtual destructor to create vtable.
Definition: RelationIndexContainer.h:43
Belle2::StoreAccessorBase::getAccessorParams
AccessorParams getAccessorParams() const
Return pair of name and durability under which stored object is saved.
Definition: StoreAccessorBase.h:136
Belle2::RelationIndexContainer::Element::indexFrom
RelationElement::index_type indexFrom
index of the element from which the relation points.
Definition: RelationIndexContainer.h:70
Belle2::RelationIndexManager
Manager to keep a cache of existing RelationIndexContainers.
Definition: RelationIndexManager.h:38
Belle2::RelationIndexContainer::Element::from
const FROM * from
pointer of the element from which the relation points.
Definition: RelationIndexContainer.h:76
Belle2::RelationIndexContainer::operator=
RelationIndexContainer & operator=(const RelationIndexContainer &)=delete
Restrict copies.
Belle2::RelationIndexContainer::Element::to
const TO * to
pointer of the element to which the relation points.
Definition: RelationIndexContainer.h:79
Belle2::RelationIndexContainer::getFromAccessorParams
const AccessorParams & getFromAccessorParams() const
Get the AccessorParams of the StoreArray the relation points from.
Definition: RelationIndexContainer.h:113
Belle2::RelationIndexContainer::clear
virtual void clear() override
Clear the index (at the end of an event)
Definition: RelationIndexContainer.h:142
Belle2::RelationIndexContainer::rebuild
void rebuild(bool force=false)
Rebuild the index.
Definition: RelationIndexContainer.h:164
Belle2::RelationElement
Class to store a single element of a relation.
Definition: RelationElement.h:33
Belle2::AccessorParams
std::pair< std::string, DataStore::EDurability > AccessorParams
Pair of parameters needed to find an object in the DataStore.
Definition: StoreAccessorBase.h:26
Belle2::RelationIndexContainer::Element
Element type for the index.
Definition: RelationIndexContainer.h:62
Belle2::RelationIndexContainer::RelationIndexContainer
RelationIndexContainer(const RelationArray &relArray)
Constructor to create a new IndexContainer.
Definition: RelationIndexContainer.h:123
Belle2::RelationIndexContainer::Element::Element
Element(RelationElement::index_type indexFrom_, RelationElement::index_type indexTo_, const FROM *from_, const TO *to_, RelationElement::weight_type weight_)
Create a new element.
Definition: RelationIndexContainer.h:65
Belle2::RelationIndexContainer::m_storeTo
AccessorParams m_storeTo
AccessorParams of the StoreArray the relation points to.
Definition: RelationIndexContainer.h:154
Belle2::RelationIndexContainer::m_storeRel
RelationArray m_storeRel
the underlying relation.
Definition: RelationIndexContainer.h:148
Belle2
Abstract base class for different kinds of events.
Definition: MillepedeAlgorithm.h:19
Belle2::RelationElement::index_type
unsigned int index_type
type used for indices.
Definition: RelationElement.h:37
Belle2::RelationIndexBase::clear
virtual void clear()=0
Clear the index (at the end of the event)
Belle2::RelationIndexContainer::getAccessorParams
AccessorParams getAccessorParams() const
Get the AccessorParams of the underlying relation.
Definition: RelationIndexContainer.h:110
Belle2::RelationIndexContainer
Class to store a bidirectional index between two StoreArrays.
Definition: RelationIndexContainer.h:58
Belle2::RelationIndexContainer::ElementIndex
boost::multi_index::multi_index_container< Element, boost::multi_index::indexed_by< boost::multi_index::ordered_non_unique< boost::multi_index::member< Element, const FROM *, &Element::from > >, boost::multi_index::ordered_non_unique< boost::multi_index::member< Element, const TO *, &Element::to > > > > ElementIndex
Boost MultiIndex container to keep the bidirectional index.
Definition: RelationIndexContainer.h:99
Belle2::RelationIndexContainer::index
const ElementIndex & index() const
Get the index.
Definition: RelationIndexContainer.h:105
Belle2::StoreArray
Accessor to arrays stored in the data store.
Definition: ECLMatchingPerformanceExpertModule.h:33
Belle2::RelationIndexContainer::getToAccessorParams
const AccessorParams & getToAccessorParams() const
Get the AccessorParams of the StoreArray the relation points to.
Definition: RelationIndexContainer.h:116
Belle2::RelationElement::weight_type
float weight_type
type used for weights.
Definition: RelationElement.h:40
Belle2::RelationIndexContainer::m_valid
bool m_valid
Indicate wether the relation is valid.
Definition: RelationIndexContainer.h:157