Belle II Software development
RelationIndexContainer.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
9#pragma once
10
11#include <framework/datastore/StoreArray.h>
12#include <framework/datastore/RelationArray.h>
13
14#include <boost/multi_index_container.hpp>
15#include <boost/multi_index/ordered_index.hpp>
16#include <boost/multi_index/member.hpp>
17
18namespace Belle2 {
32 public:
33
35 virtual ~RelationIndexBase() {}
36
38 virtual void clear() = 0;
39 };
40
50 template<class FROM, class TO> class RelationIndexContainer: public RelationIndexBase {
51 public:
52
54 struct Element {
55
58 const FROM* from_, const TO* to_, RelationElement::weight_type weight_):
59 indexFrom(indexFrom_), indexTo(indexTo_), from(from_), to(to_), weight(weight_) {}
60
63
66
68 const FROM* from;
69
71 const TO* to;
72
75 };
76
81 typedef boost::multi_index::multi_index_container <
82 Element,
83 boost::multi_index::indexed_by <
84 boost::multi_index::ordered_non_unique <
85 boost::multi_index::member<Element, const FROM*, &Element::from>
86 >,
87 boost::multi_index::ordered_non_unique <
88 boost::multi_index::member<Element, const TO*, &Element::to>
89 >
90 >
92
94 operator bool() const { return m_valid; }
95
97 const ElementIndex& index() const { return m_index; }
99 ElementIndex& index() { return m_index; }
100
103
106
109
110 protected:
115 explicit RelationIndexContainer(const RelationArray& relArray): m_storeRel(relArray), m_valid(false)
116 {
117 rebuild(true);
118 }
119
122
125
131 void rebuild(bool force = false);
132
134 virtual void clear() override { m_index.clear(); }
135
138
141
144
147
150
153 };
154
156 template<class FROM, class TO> void RelationIndexContainer<FROM, TO>::rebuild(bool force)
157 {
158 m_valid = m_storeRel.isValid();
159 if (!m_valid) {
160 B2DEBUG(100, "Relation " << m_storeRel.getName() << " does not exist, cannot build index");
161 m_index.clear();
162 m_storeFrom = AccessorParams();
163 m_storeTo = AccessorParams();
164 return;
165 }
166
167 //Check if relation has been modified since we created the index
168 //If not, keep old contents
169 if (!force && !m_storeRel.getModified()) return;
170
171 B2DEBUG(100, "Building index for " << m_storeRel.getName());
172
173 //Reset modification flag
174 m_storeRel.setModified(false);
175
176 m_index.clear();
177
178 //Get related StoreArrays
179 m_storeFrom = m_storeRel.getFromAccessorParams();
180 m_storeTo = m_storeRel.getToAccessorParams();
181 const StoreArray<FROM> storeFrom(m_storeFrom.first, m_storeFrom.second);
182 const StoreArray<TO> storeTo(m_storeTo.first, m_storeTo.second);
183
184 //Get number of entries in relation and stores (also checks template type versus DataStore contents)
185 const RelationElement::index_type nFrom = storeFrom.getEntries();
186 const RelationElement::index_type nTo = storeTo.getEntries();
187 const unsigned int nRel = m_storeRel.getEntries();
188
189 //Loop over all RelationElements and add them to index
190 for (unsigned int i = 0; i < nRel; ++i) {
191 const RelationElement& r = m_storeRel[i];
192 RelationElement::index_type idxFrom = r.getFromIndex();
193 if (idxFrom >= nFrom)
194 B2FATAL("Relation " << m_storeRel.getName() << " is inconsistent: from-index (" << idxFrom << ") out of range");
195 const FROM* from = storeFrom[idxFrom];
196
197 //Loop over index and weight vector at once
198 const auto& indices = r.getToIndices();
199 const auto& weights = r.getWeights();
200 auto itIdx = indices.begin();
201 auto itWgt = weights.begin();
202 const auto& idxEnd = indices.end();
203 for (; itIdx != idxEnd; ++itIdx, ++itWgt) {
204 const RelationElement::index_type idxTo = *itIdx;
205 if (idxTo >= nTo)
206 B2FATAL("Relation " << m_storeRel.getName() << " is inconsistent: to-index (" << idxTo << ") out of range");
207 const TO* to = storeTo[idxTo];
208 m_index.insert(Element(idxFrom, idxTo, from, to, *itWgt));
209 }
210 }
211 }
212
214} // end namespace Belle2
Low-level class to create/modify relations between StoreArrays.
Definition: RelationArray.h:62
Class to store a single element of a relation.
unsigned int index_type
type used for indices.
float weight_type
type used for weights.
Baseclass for all RelationIndexContainers.
virtual void clear()=0
Clear the index (at the end of the event)
virtual ~RelationIndexBase()
Virtual destructor to create vtable.
Class to store a bidirectional index between two StoreArrays.
const AccessorParams & getFromAccessorParams() const
Get the AccessorParams of the StoreArray the relation points from.
RelationIndexContainer(const RelationIndexContainer &)=delete
Restrict copies.
RelationArray m_storeRel
the underlying relation.
AccessorParams m_storeFrom
AccessorParams of the StoreArray the relation points from.
RelationIndexContainer(const RelationArray &relArray)
Constructor to create a new IndexContainer.
ElementIndex & index()
Get the index.
const AccessorParams & getToAccessorParams() const
Get the AccessorParams of the StoreArray the relation points to.
const ElementIndex & index() const
Get the index.
bool m_valid
Indicate wether the relation is valid.
virtual void clear() override
Clear the index (at the end of an event)
RelationIndexContainer & operator=(const RelationIndexContainer &)=delete
Restrict copies.
AccessorParams getAccessorParams() const
Get the AccessorParams of the underlying relation.
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.
ElementIndex m_index
Instance of the index.
AccessorParams m_storeTo
AccessorParams of the StoreArray the relation points to.
Manager to keep a cache of existing RelationIndexContainers.
AccessorParams getAccessorParams() const
Return pair of name and durability under which stored object is saved.
Accessor to arrays stored in the data store.
Definition: StoreArray.h:113
int getEntries() const
Get the number of objects in the array.
Definition: StoreArray.h:216
void rebuild(bool force=false)
Rebuild the index.
std::pair< std::string, DataStore::EDurability > AccessorParams
Pair of parameters needed to find an object in the DataStore.
Abstract base class for different kinds of events.
const FROM * from
pointer of the element from which the relation points.
const TO * to
pointer of the element to which the relation points.
RelationElement::index_type indexTo
index of the element to which the relation points.
RelationElement::index_type indexFrom
index of the element from which the relation points.
RelationElement::weight_type weight
weight of the relation.
Element(RelationElement::index_type indexFrom_, RelationElement::index_type indexTo_, const FROM *from_, const TO *to_, RelationElement::weight_type weight_)
Create a new element.