/home/bes3soft/bes3soft/Boss/7.0.2/dist/7.0.2/Event/RelTable/RelTable-00-00-02/RelTable/RelTable.h

Go to the documentation of this file.
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     // Purpose and Method:  This routine add a new relation to the collection, even
00133     // if there is a already a relation between the same two objects
00134     // Inputs:  rel is a pointer to the relation to be added.
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     // Purpose and Method:  This routine add a relation to the table if it doesn't 
00145     // contain a relation between the same two objects, otherwise it appends the info
00146     // vector to the exsisting relation
00147     // Inputs:  rel is a pointer to the relation to be added.
00148     // Outputs: a boolean value which is true if the realtion has been added to the
00149     //          table and false it it is a duplicate and thus has not been added.
00150     //          In the latter case the user has to delete the relation
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     // Purpose and Method: This routine finds all relations having pobj in the
00165     // first field.  
00166     // Inputs: pobj is a pointer to the object to be searched in the first field
00167     // Outputs: A pointer to a vector of Relation* including pobj
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     // Purpose and Method: This routine finds all relations having pobj in the
00193     // second field.  
00194     // Inputs: pobj is a pointer to the object to be searched in the second field
00195     // Outputs: A pointer to a vector of Relation* including pobj
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     // Purpose: This method remove the given relation from the table
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     // Purpose: This method change the first data pointer of a relation with the
00232     // one given by the user
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     // Purpose: This method change the second data pointer of a relation with the
00245     // one given by the user
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     // Purpose: This method returns the total number of relations contained in the
00258     // collection
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 

Generated on Tue Nov 29 22:58:37 2016 for BOSS_7.0.2 by  doxygen 1.4.7