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