00001
00002 #ifndef RELTABLE_H
00003 #define RELTABLE_H
00004
00005
00006 #include "GaudiKernel/ObjectList.h"
00007 #include "GaudiKernel/SmartRef.h"
00008 #include "Relation.h"
00009 #include <vector>
00010 #include <algorithm>
00011 #include <iterator>
00012
00026 namespace Event {
00027
00028 template <class T1, class T2>
00029 class RelTable {
00030
00031 public:
00032
00033 RelTable() {}
00034 RelTable(ObjectList < Relation<T1,T2> >* rels);
00035
00036
00038 void init() { m_relations = new ObjectList< Relation<T1,T2> >;}
00039
00045 void addDupRel(Relation<T1,T2>* rel);
00046
00055 bool addRelation(Relation<T1,T2>* rel);
00056
00063 std::vector< Relation<T1,T2>* > getRelByFirst(const T1* pobj) const;
00064
00071 std::vector< Relation<T1,T2>* > getRelBySecond(const T2* pobj) const;
00072
00078 void erase(Relation<T1,T2> *rel);
00079
00086 void changeFirst(Relation<T1,T2> *rel, T1 *pobj);
00087
00094 void changeSecond(Relation<T1,T2> *rel, T2 *pobj);
00095
00097 unsigned long size() const ;
00098
00100 ObjectList< Relation<T1,T2> >* getAllRelations() const;
00101
00102 private:
00103
00105 ObjectList < Relation<T1,T2> >* m_relations;
00106
00107
00108 void bindRelationFirst(Relation<T1,T2> *rel);
00109 void bindRelationSecond(Relation<T1,T2> *rel);
00110
00111 void removeFirst(Relation<T1,T2> *rel);
00112 void removeSecond(Relation<T1,T2> *rel);
00113
00114 Relation<T1,T2>* findDup(Relation<T1,T2> *rel1, Relation<T1,T2>* rel2);
00115 bool bindRelationNoDup(Relation<T1,T2> *rel);
00116
00117
00118 };
00119
00120
00121
00122
00123 template <class T1,class T2>
00124 inline RelTable<T1,T2>::RelTable(ObjectList < Relation<T1,T2> >* rels) {
00125
00126 m_relations = rels;
00127
00128 }
00129
00130 template <class T1,class T2>
00131 void RelTable<T1,T2>::addDupRel(Relation<T1,T2>* rel) {
00132
00133
00134
00135
00136 bindRelationFirst(rel);
00137 bindRelationSecond(rel);
00138 m_relations->push_back(rel);
00139 }
00140
00141
00142 template <class T1,class T2>
00143 bool RelTable<T1,T2>::addRelation(Relation<T1,T2>* rel) {
00144
00145
00146
00147
00148
00149
00150
00151
00152 if (bindRelationNoDup(rel))
00153 {
00154 bindRelationSecond(rel);
00155 m_relations->push_back(rel);
00156 return true;
00157 }
00158 return false;
00159 }
00160
00161
00162 template <class T1,class T2>
00163 std::vector< Relation<T1,T2>* > RelTable<T1,T2>::getRelByFirst(const T1* pobj) const {
00164
00165
00166
00167
00168
00169 std::vector< Relation<T1,T2>* > rels;
00170 if (!m_relations->size()) return rels;
00171 SmartRef< Relation<T1,T2> > r = m_relations->front();
00172 while (pobj != r->getFirst() && r->m_first.getFirst())
00173 {
00174 r = r->m_first.getFirst();
00175 }
00176
00177 if (pobj == r->getFirst())
00178 {
00179 rels.push_back(r);
00180 while (r->m_first.getSame())
00181 {
00182 rels.push_back(r->m_first.getSame());
00183 r = r->m_first.getSame();
00184 }
00185 }
00186 return rels;
00187 }
00188
00189
00190 template <class T1,class T2>
00191 std::vector< Relation<T1,T2>* > RelTable<T1,T2>::getRelBySecond(const T2* pobj) const {
00192
00193
00194
00195
00196 std::vector< Relation<T1,T2>* > rels;
00197 if (!m_relations->size()) return rels;
00198 SmartRef< Relation<T1,T2> > r = m_relations->front();
00199 while (pobj != r->getSecond() && r->m_second.getFirst())
00200 {
00201 r = r->m_second.getFirst();
00202 }
00203
00204 if (pobj == r->getSecond())
00205 {
00206 rels.push_back(r);
00207 while (r->m_second.getSame())
00208 {
00209 rels.push_back(r->m_second.getSame());
00210 r = r->m_second.getSame();
00211 }
00212 }
00213 return rels;
00214 }
00215
00216
00217 template <class T1,class T2>
00218 void RelTable<T1,T2>::erase(Relation<T1,T2> *rel) {
00219
00220
00221 removeFirst(rel);
00222 removeSecond(rel);
00223
00224 m_relations->remove(rel);
00225 delete rel;
00226 }
00227
00228
00229 template <class T1,class T2>
00230 void RelTable<T1,T2>::changeFirst(Relation<T1,T2> *rel, T1 *pobj) {
00231
00232
00233
00234 removeFirst(rel);
00235 removeSecond(rel);
00236 m_relations->remove(rel);
00237 rel->setFirst(pobj);
00238 addRelation(rel);
00239 }
00240
00241
00242 template <class T1,class T2>
00243 void RelTable<T1,T2>::changeSecond(Relation<T1,T2> *rel, T2 *pobj) {
00244
00245
00246
00247 removeFirst(rel);
00248 removeSecond(rel);
00249 m_relations->remove(rel);
00250 rel->setSecond(pobj);
00251 addRelation(rel);
00252 }
00253
00254
00255 template <class T1,class T2>
00256 inline unsigned long RelTable<T1,T2>::size() const {
00257
00258
00259 return m_relations->size();
00260 }
00261
00262 template <class T1,class T2>
00263 inline ObjectList< Relation<T1,T2> >* RelTable<T1,T2>::getAllRelations() const {
00264
00265 return m_relations;
00266
00267 }
00268
00269
00270
00271 template <class T1,class T2>
00272 inline void RelTable<T1,T2>::bindRelationFirst(Relation<T1,T2> *rel) {
00273
00274 Relation<T1,T2>* temp;
00275
00276 if (m_relations->size())
00277 {
00278 SmartRef< Relation<T1,T2> > r = m_relations->front();
00279 while ((r->getFirst() != rel->getFirst()))
00280 {
00281 if (r->m_first.getFirst())
00282 {
00283 r = r->m_first.getFirst();
00284 }
00285 else
00286 {
00287 break;
00288 }
00289 }
00290
00291 if (r->getFirst() != rel->getFirst())
00292 {
00293 r->m_first.setFirst(rel);
00294 rel->m_first.setPrev(r);
00295 }
00296 else
00297 {
00298 temp = r->m_first.getSame();
00299 rel->m_first.setSame(temp);
00300 if (temp)
00301 temp->m_first.setPrev(rel);
00302 r->m_first.setSame(rel);
00303 rel->m_first.setPrev(r);
00304 }
00305 }
00306 }
00307
00308
00309 template <class T1,class T2>
00310 inline void RelTable<T1,T2>::bindRelationSecond(Relation<T1,T2> *rel) {
00311 Relation<T1,T2>* temp;
00312
00313 if (m_relations->size())
00314 {
00315 SmartRef< Relation<T1,T2> > r = m_relations->front();
00316
00317 while ((r->getSecond() != rel->getSecond()))
00318 {
00319 if (r->m_second.getFirst())
00320 {
00321 r = r->m_second.getFirst();
00322 }
00323 else
00324 {
00325 break;
00326 }
00327 }
00328
00329 if (r->getSecond() != rel->getSecond())
00330 {
00331 r->m_second.setFirst(rel);
00332 rel->m_second.setPrev(r);
00333 }
00334 else
00335 {
00336 temp = r->m_second.getSame();
00337 rel->m_second.setSame(temp);
00338 if (temp)
00339 temp->m_second.setPrev(rel);
00340 r->m_second.setSame(rel);
00341 rel->m_second.setPrev(r);
00342 }
00343 }
00344 }
00345
00346
00347
00348 template <class T1,class T2>
00349 inline Relation<T1,T2>* RelTable<T1,T2>::findDup(Relation<T1,T2> *rel1, Relation<T1,T2>* rel2)
00350 {
00351 while (rel1)
00352 {
00353 if (rel1->getSecond() == rel2->getSecond())
00354 return rel1;
00355 rel1 = rel1->m_first.getSame();
00356 }
00357 return rel1;
00358 }
00359
00360
00361
00362 template <class T1,class T2>
00363 inline bool RelTable<T1,T2>::bindRelationNoDup(Relation<T1,T2> *rel) {
00364
00365 Relation<T1,T2>* temp;
00366
00367 if (m_relations->size())
00368 {
00369 SmartRef< Relation<T1,T2> > r = m_relations->front();
00370 while ((r->getFirst() != rel->getFirst()))
00371 {
00372 if (r->m_first.getFirst())
00373 {
00374 r = r->m_first.getFirst();
00375 }
00376 else
00377 {
00378 break;
00379 }
00380 }
00381
00382 if (r->getFirst() != rel->getFirst())
00383 {
00384 r->m_first.setFirst(rel);
00385 rel->m_first.setPrev(r);
00386 return true;
00387 }
00388 else
00389 {
00390 temp = findDup(r,rel);
00391 if (!temp)
00392 {
00393 temp = r->m_first.getSame();
00394 rel->m_first.setSame(temp);
00395 if (temp)
00396 temp->m_first.setPrev(rel);
00397 r->m_first.setSame(rel);
00398 rel->m_first.setPrev(r);
00399 return true;
00400 }
00401 else
00402 {
00403 std::copy(rel->m_infos.begin(),rel->m_infos.end(),std::back_inserter(temp->m_infos));
00404 return false;
00405 }
00406 }
00407 }
00408 return true;
00409 }
00410
00411
00412
00413 template <class T1,class T2>
00414 inline void RelTable<T1,T2>::removeFirst(Relation<T1,T2> *rel) {
00415
00416 Relation<T1,T2> *prev, *next, *first;
00417
00418 prev = rel->m_first.getPrev();
00419 next = rel->m_first.getSame();
00420 if (next)
00421 next->m_first.setPrev(prev);
00422 if (prev)
00423 {
00424 if (prev->m_first.getFirst())
00425 prev->m_first.setFirst(next);
00426 else
00427 prev->m_first.setSame(next);
00428 }
00429 first = rel->m_first.getFirst();
00430 if (first)
00431 first->m_first.setPrev(next);
00432 rel->m_first.setPrev(0);
00433 rel->m_first.setSame(0);
00434 rel->m_first.setFirst(0);
00435 }
00436
00437
00438 template <class T1,class T2>
00439 inline void RelTable<T1,T2>::removeSecond(Relation<T1,T2> *rel) {
00440
00441 Relation<T1,T2> *prev, *next, *first;
00442
00443 prev = rel->m_second.getPrev();
00444 next = rel->m_second.getSame();
00445 if (next)
00446 next->m_second.setPrev(prev);
00447 if (prev)
00448 {
00449 if (prev->m_second.getFirst())
00450 prev->m_second.setFirst(next);
00451 else
00452 prev->m_second.setSame(next);
00453 }
00454 first = rel->m_second.getFirst();
00455 if (first)
00456 first->m_second.setPrev(next);
00457 rel->m_second.setPrev(0);
00458 rel->m_second.setSame(0);
00459 rel->m_second.setFirst(0);
00460 }
00461
00462 }
00463
00464 #endif // RELTABLE_H