BOSS 8.0.0
BESIII Offline Software System
Loading...
Searching...
No Matches
Event/RelTable/include/RelTable/RelTable.h
Go to the documentation of this file.
1
2#ifndef RELTABLE_H
3#define RELTABLE_H
4
5#include "GaudiKernel/ObjectList.h"
6#include "GaudiKernel/SmartRef.h"
7#include "Relation.h"
8#include <algorithm>
9#include <iterator>
10#include <vector>
11
12/**
13 * @class RelTable
14 *
15 * @brief This class is used to wrap a collection of Relations.
16 *
17 * The RelTable class wraps a list (a Gaudi ObjectList) of Relations. It
18 * lets the user search for all object related to a given one. The search can be
19 * done with respect to an object of the first or the second field of the
20 * relations. The user can also modify or delete relations.
21 *
22 */
23
24namespace Event {
25
26 template <class T1, class T2> class RelTable {
27
28 public:
30 RelTable( ObjectList<Relation<T1, T2>>* rels );
31
32 /// Initialize the internal pointer to an ObjectList of relations
33 void init() { m_relations = new ObjectList<Relation<T1, T2>>; }
34
35 /**
36 * The following method add a new Relation to the table, even if there is
37 * already a relation with the same two objects (they could have different
38 * infos vector)
39 */
41
42 /**
43 * The following method add a Relation to the table if it doesn't contain
44 * a relation between the same two objects, otherwise it appends the info
45 * vector to the exsisting relation
46 * @param rel is a pointer to a relation between two objects
47 * @return true if the relation has been added and false if it is a duplicate
48 * and has not been added (in this case the user has to delete it)
49 */
51
52 /**
53 * This method search for all relations having obj in the first
54 * field.
55 * @param obj it's a pointer to the object given by the user
56 * @return A vector of pointers to the relations involving the given object.
57 */
58 std::vector<Relation<T1, T2>*> getRelByFirst( const T1* pobj ) const;
59
60 /**
61 * This method search for all relations having pobj in the second
62 * field.
63 * @param pobj it's a pointer to the object given by the user
64 * @return A vector of pointers to the relations involving the given object.
65 */
66 std::vector<Relation<T1, T2>*> getRelBySecond( const T2* pobj ) const;
67
68 /**
69 * This method erase a particular relation from the table (keeping the
70 * integrity).
71 * @param rel it's a pointer to the relation to be erased
72 */
73 void erase( Relation<T1, T2>* rel );
74
75 /**
76 * This method change the first data pointer of a given relation contained
77 * into the table.
78 * @param rel it's a pointer to the relation to be modified
79 * @param pobj is the new data value provided by the user
80 */
81 void changeFirst( Relation<T1, T2>* rel, T1* pobj );
82
83 /**
84 * This method change the second data pointer of a given relation contained
85 * into the table.
86 * @param rel it's a pointer to the relation to be modified
87 * @param pobj is the new data value provided by the user
88 */
89 void changeSecond( Relation<T1, T2>* rel, T2* pobj );
90
91 /// This method returns the number of relations in the table
92 unsigned long size() const;
93
94 /// Returns the pointer to the collection of relations.
95 ObjectList<Relation<T1, T2>>* getAllRelations() const;
96
97 private:
98 /// Pointer to a collection of relations
99 ObjectList<Relation<T1, T2>>* m_relations;
100
101 void bindRelationFirst( Relation<T1, T2>* rel );
102 void bindRelationSecond( Relation<T1, T2>* rel );
103
104 void removeFirst( Relation<T1, T2>* rel );
105 void removeSecond( Relation<T1, T2>* rel );
106
107 Relation<T1, T2>* findDup( Relation<T1, T2>* rel1, Relation<T1, T2>* rel2 );
108 bool bindRelationNoDup( Relation<T1, T2>* rel );
109 };
110
111 template <class T1, class T2>
112 inline RelTable<T1, T2>::RelTable( ObjectList<Relation<T1, T2>>* rels ) {
113
114 m_relations = rels;
115 }
116
117 template <class T1, class T2> void RelTable<T1, T2>::addDupRel( Relation<T1, T2>* rel ) {
118 // Purpose and Method: This routine add a new relation to the collection, even
119 // if there is a already a relation between the same two objects
120 // Inputs: rel is a pointer to the relation to be added.
121
122 bindRelationFirst( rel );
123 bindRelationSecond( rel );
124 m_relations->push_back( rel );
125 }
126
127 template <class T1, class T2> bool RelTable<T1, T2>::addRelation( Relation<T1, T2>* rel ) {
128 // Purpose and Method: This routine add a relation to the table if it doesn't
129 // contain a relation between the same two objects, otherwise it appends the info
130 // vector to the exsisting relation
131 // Inputs: rel is a pointer to the relation to be added.
132 // Outputs: a boolean value which is true if the realtion has been added to the
133 // table and false it it is a duplicate and thus has not been added.
134 // In the latter case the user has to delete the relation
135
136 if ( bindRelationNoDup( rel ) )
137 {
138 bindRelationSecond( rel );
139 m_relations->push_back( rel );
140 return true;
141 }
142 return false;
143 }
144
145 template <class T1, class T2>
146 std::vector<Relation<T1, T2>*> RelTable<T1, T2>::getRelByFirst( const T1* pobj ) const {
147 // Purpose and Method: This routine finds all relations having pobj in the
148 // first field.
149 // Inputs: pobj is a pointer to the object to be searched in the first field
150 // Outputs: A pointer to a vector of Relation* including pobj
151
152 std::vector<Relation<T1, T2>*> rels;
153 if ( !m_relations->size() ) return rels;
154 SmartRef<Relation<T1, T2>> r = m_relations->front();
155 while ( pobj != r->getFirst() && r->m_first.getFirst() ) { r = r->m_first.getFirst(); }
156
157 if ( pobj == r->getFirst() )
158 {
159 rels.push_back( r );
160 while ( r->m_first.getSame() )
161 {
162 rels.push_back( r->m_first.getSame() );
163 r = r->m_first.getSame();
164 }
165 }
166 return rels;
167 }
168
169 template <class T1, class T2>
170 std::vector<Relation<T1, T2>*> RelTable<T1, T2>::getRelBySecond( const T2* pobj ) const {
171 // Purpose and Method: This routine finds all relations having pobj in the
172 // second field.
173 // Inputs: pobj is a pointer to the object to be searched in the second field
174 // Outputs: A pointer to a vector of Relation* including pobj
175 std::vector<Relation<T1, T2>*> rels;
176 if ( !m_relations->size() ) return rels;
177 SmartRef<Relation<T1, T2>> r = m_relations->front();
178 while ( pobj != r->getSecond() && r->m_second.getFirst() ) { r = r->m_second.getFirst(); }
179
180 if ( pobj == r->getSecond() )
181 {
182 rels.push_back( r );
183 while ( r->m_second.getSame() )
184 {
185 rels.push_back( r->m_second.getSame() );
186 r = r->m_second.getSame();
187 }
188 }
189 return rels;
190 }
191
192 template <class T1, class T2> void RelTable<T1, T2>::erase( Relation<T1, T2>* rel ) {
193 // Purpose: This method remove the given relation from the table
194
195 removeFirst( rel );
196 removeSecond( rel );
197
198 m_relations->remove( rel );
199 delete rel;
200 }
201
202 template <class T1, class T2>
204 // Purpose: This method change the first data pointer of a relation with the
205 // one given by the user
206
207 removeFirst( rel );
208 removeSecond( rel );
209 m_relations->remove( rel );
210 rel->setFirst( pobj );
211 addRelation( rel );
212 }
213
214 template <class T1, class T2>
216 // Purpose: This method change the second data pointer of a relation with the
217 // one given by the user
218
219 removeFirst( rel );
220 removeSecond( rel );
221 m_relations->remove( rel );
222 rel->setSecond( pobj );
223 addRelation( rel );
224 }
225
226 template <class T1, class T2> inline unsigned long RelTable<T1, T2>::size() const {
227 // Purpose: This method returns the total number of relations contained in the
228 // collection
229 return m_relations->size();
230 }
231
232 template <class T1, class T2>
233 inline ObjectList<Relation<T1, T2>>* RelTable<T1, T2>::getAllRelations() const {
234
235 return m_relations;
236 }
237
238 template <class T1, class T2>
239 inline void RelTable<T1, T2>::bindRelationFirst( Relation<T1, T2>* rel ) {
240
241 Relation<T1, T2>* temp;
242
243 if ( m_relations->size() )
244 {
245 SmartRef<Relation<T1, T2>> r = m_relations->front();
246 while ( ( r->getFirst() != rel->getFirst() ) )
247 {
248 if ( r->m_first.getFirst() ) { r = r->m_first.getFirst(); }
249 else { break; }
250 }
251
252 if ( r->getFirst() != rel->getFirst() )
253 {
254 r->m_first.setFirst( rel );
255 rel->m_first.setPrev( r );
256 }
257 else
258 {
259 temp = r->m_first.getSame();
260 rel->m_first.setSame( temp );
261 if ( temp ) temp->m_first.setPrev( rel );
262 r->m_first.setSame( rel );
263 rel->m_first.setPrev( r );
264 }
265 }
266 }
267
268 template <class T1, class T2>
269 inline void RelTable<T1, T2>::bindRelationSecond( Relation<T1, T2>* rel ) {
270 Relation<T1, T2>* temp;
271
272 if ( m_relations->size() )
273 {
274 SmartRef<Relation<T1, T2>> r = m_relations->front();
275
276 while ( ( r->getSecond() != rel->getSecond() ) )
277 {
278 if ( r->m_second.getFirst() ) { r = r->m_second.getFirst(); }
279 else { break; }
280 }
281
282 if ( r->getSecond() != rel->getSecond() )
283 {
284 r->m_second.setFirst( rel );
285 rel->m_second.setPrev( r );
286 }
287 else
288 {
289 temp = r->m_second.getSame();
290 rel->m_second.setSame( temp );
291 if ( temp ) temp->m_second.setPrev( rel );
292 r->m_second.setSame( rel );
293 rel->m_second.setPrev( r );
294 }
295 }
296 }
297
298 template <class T1, class T2>
299 inline Relation<T1, T2>* RelTable<T1, T2>::findDup( Relation<T1, T2>* rel1,
300 Relation<T1, T2>* rel2 ) {
301 while ( rel1 )
302 {
303 if ( rel1->getSecond() == rel2->getSecond() ) return rel1;
304 rel1 = rel1->m_first.getSame();
305 }
306 return rel1;
307 }
308
309 template <class T1, class T2>
310 inline bool RelTable<T1, T2>::bindRelationNoDup( Relation<T1, T2>* rel ) {
311
312 Relation<T1, T2>* temp;
313
314 if ( m_relations->size() )
315 {
316 SmartRef<Relation<T1, T2>> r = m_relations->front();
317 while ( ( r->getFirst() != rel->getFirst() ) )
318 {
319 if ( r->m_first.getFirst() ) { r = r->m_first.getFirst(); }
320 else { break; }
321 }
322
323 if ( r->getFirst() != rel->getFirst() )
324 {
325 r->m_first.setFirst( rel );
326 rel->m_first.setPrev( r );
327 return true;
328 }
329 else
330 {
331 temp = findDup( r, rel );
332 if ( !temp )
333 {
334 temp = r->m_first.getSame();
335 rel->m_first.setSame( temp );
336 if ( temp ) temp->m_first.setPrev( rel );
337 r->m_first.setSame( rel );
338 rel->m_first.setPrev( r );
339 return true;
340 }
341 else
342 {
343 std::copy( rel->m_infos.begin(), rel->m_infos.end(),
344 std::back_inserter( temp->m_infos ) );
345 return false;
346 }
347 }
348 }
349 return true;
350 }
351
352 template <class T1, class T2>
353 inline void RelTable<T1, T2>::removeFirst( Relation<T1, T2>* rel ) {
354
356
357 prev = rel->m_first.getPrev();
358 next = rel->m_first.getSame();
359 if ( next ) next->m_first.setPrev( prev );
360 if ( prev )
361 {
362 if ( prev->m_first.getFirst() ) prev->m_first.setFirst( next );
363 else prev->m_first.setSame( next );
364 }
365 first = rel->m_first.getFirst();
366 if ( first ) first->m_first.setPrev( next );
367 rel->m_first.setPrev( 0 );
368 rel->m_first.setSame( 0 );
369 rel->m_first.setFirst( 0 );
370 }
371
372 template <class T1, class T2>
373 inline void RelTable<T1, T2>::removeSecond( Relation<T1, T2>* rel ) {
374
376
377 prev = rel->m_second.getPrev();
378 next = rel->m_second.getSame();
379 if ( next ) next->m_second.setPrev( prev );
380 if ( prev )
381 {
382 if ( prev->m_second.getFirst() ) prev->m_second.setFirst( next );
383 else prev->m_second.setSame( next );
384 }
385 first = rel->m_second.getFirst();
386 if ( first ) first->m_second.setPrev( next );
387 rel->m_second.setPrev( 0 );
388 rel->m_second.setSame( 0 );
389 rel->m_second.setFirst( 0 );
390 }
391
392} // namespace Event
393
394#endif // RELTABLE_H
void setSame(Relation< T2, T3 > *rel)
void setPrev(Relation< T2, T3 > *rel)
void changeSecond(Relation< T1, T2 > *rel, T2 *pobj)
std::vector< Relation< T1, T2 > * > getRelBySecond(const T2 *pobj) const
void init()
Initialize the internal pointer to an ObjectList of relations.
ObjectList< Relation< T1, T2 > > * getAllRelations() const
Returns the pointer to the collection of relations.
unsigned long size() const
This method returns the number of relations in the table.
void erase(Relation< T1, T2 > *rel)
bool addRelation(Relation< T1, T2 > *rel)
RelTable(ObjectList< Relation< T1, T2 > > *rels)
std::vector< Relation< T1, T2 > * > getRelByFirst(const T1 *pobj) const
void changeFirst(Relation< T1, T2 > *rel, T1 *pobj)
void addDupRel(Relation< T1, T2 > *rel)
This class is used to wrap a collection of Relations.
Index next(Index i)
Index prev(Index i)
Definition EvtCyclic3.cc:94
Index first(Pair i)