level_one_hmap.h

00001 /*
00002  *  Copyright (C) 2005 M.J. Zaki <zaki@cs.rpi.edu> Rensselaer Polytechnic Institute
00003  *  Written by parimi@cs.rpi.edu
00004  *  Updated by chaojv@cs.rpi.edu, alhasan@cs.rpi.edu, salems@cs.rpi.edu
00005  *
00006  *  This program is free software; you can redistribute it and/or
00007  *  modify it under the terms of the GNU General Public License
00008  *  as published by the Free Software Foundation; either version 2
00009  *  of the License, or (at your option) any later version.
00010  *
00011  *  This program is distributed in the hope that it will be useful,
00012  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  *  GNU General Public License for more details.
00015  *
00016  *  You should have received a copy of the GNU General Public License along
00017  *  with this program; if not, write to the Free Software Foundation, Inc.,
00018  *  59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
00019  */
00020 #ifndef _LEVEL_ONE_HMAP_H
00021 #define _LEVEL_ONE_HMAP_H
00022 
00023 #include <ext/hash_map>
00024 #include <ext/hash_set>
00025 #include <iostream>
00026 #include <utility>
00027 
00028 
00029 using namespace std;
00030 
00036 template<typename V_T, typename E_T, template <typename> class ALLOC=std::allocator >
00037 class level_one_hmap
00038 {
00039 public:
00040   typedef element_parser<V_T> V_EP;
00041 
00042   // typedef HASHNS::hash_set<E_T, HASHNS::hash<E_T>, std::equal_to<E_T>, ALLOC<const E_T> > LABELS;
00043   typedef HASHNS::hash_set<E_T, HASHNS::hash<E_T>, std::equal_to<E_T>, ALLOC<E_T> > LABELS;
00044   typedef HASHNS::hash_map<typename V_EP::HASH_TYPE, LABELS, HASHNS::hash<typename V_EP::HASH_TYPE>, 
00045                            // typename V_EP::COMP_FUNC, ALLOC<std::pair<const typename V_EP::HASH_TYPE, LABELS> > > NEIGHBORS;
00046                            typename V_EP::COMP_FUNC, ALLOC<std::pair<typename V_EP::HASH_TYPE, LABELS> > > NEIGHBORS;
00047   typedef HASHNS::hash_map<typename V_EP::HASH_TYPE, NEIGHBORS, HASHNS::hash<typename V_EP::HASH_TYPE>, 
00048                            // typename V_EP::COMP_FUNC, ALLOC<std::pair<const typename V_EP::HASH_TYPE, NEIGHBORS> > > HMAP;
00049                            typename V_EP::COMP_FUNC, ALLOC<std::pair<typename V_EP::HASH_TYPE, NEIGHBORS> > > HMAP;
00050   typedef typename HMAP::const_iterator CONST_IT;
00051   typedef typename HMAP::iterator IT;
00052   typedef typename NEIGHBORS::const_iterator CONST_NIT;
00053   typedef typename NEIGHBORS::iterator NIT;
00054   typedef typename LABELS::const_iterator CONST_LIT;
00055   typedef typename LABELS::iterator LIT;
00056 
00057 
00058   void print() const {
00059     cout<<"LEVEL ONE HMAP CONTENTS"<<endl<<endl;
00060 
00061     CONST_IT it;
00062     CONST_NIT nit;
00063     CONST_LIT lit;
00064 
00065     for(it=_hmap.begin(); it!=_hmap.end(); it++) {
00066       cout<<"Vertex="<<it->first<<" has neighbors:"<<endl;
00067       for(nit=it->second.begin(); nit!=it->second.end(); nit++) {
00068         cout<<nit->first<<" with labels:";
00069         for(lit=nit->second.begin(); lit!=nit->second.end(); lit++)
00070           cout<<" "<<*lit;
00071           cout<<endl;
00072         }
00073         cout<<endl;
00074       }
00075 
00076   }//print()
00077 
00078   int size() const { return _hmap.size();}
00079 
00083   // NOTE: in order for this map to be applicable to both directed and
00084   // undirected graphs, insert adds an edge FROM src TO dest only;
00085   // hence for undirected graphs, insert shall have to be called twice
00086   void insert(const V_T& src, const V_T& dest, const E_T& lbl) {
00087     IT it;
00088     NIT nit;
00089     LIT lit;
00090     pair<LIT, bool> lit_p;
00091     pair<NIT, bool> nit_p;
00092     pair<IT, bool> it_p;
00093    
00094     typename V_EP::HASH_TYPE ret = V_EP::conv_hash_type(src); 
00095     // if((it=_hmap.find(V_EP::conv_hash_type(src)))!=_hmap.end()) {
00096     if((it=_hmap.find(ret))!=_hmap.end()) {
00097       // src exists in hmap
00098       if((nit=it->second.find(V_EP::conv_hash_type(dest)))!=it->second.end()) {
00099         // dest exists in neighbor list
00100         if(nit->second.find(lbl)==nit->second.end()) {
00101           // lbl does not exist
00102           lit_p=nit->second.insert(lbl);
00103           if(!lit_p.second) {
00104             cout<<"level_one_map.insert: lbl insert(1) failed for lbl="<<lbl<<endl;
00105             return;
00106           }
00107         }
00108       }
00109       else {
00110         // dest not found in neighbor list of src
00111         LABELS lset;
00112         lit_p=lset.insert(lbl);
00113 
00114         if(!lit_p.second) {
00115           cout<<"level_one_map.insert: lbl insert(2) failed for lbl="<<lbl<<endl;
00116           return;
00117         }
00118     
00119         nit_p=it->second.insert(make_pair(V_EP::conv_hash_type(dest), lset));
00120         if(!nit_p.second) {
00121           cout<<"level_one_map.insert: dest insert(1) failed for dest="<<dest<<endl;
00122           return;
00123         }    
00124       }
00125     }//end if it=hmap.find..
00126 
00127     else {
00128 
00129       // src not found in hmap
00130       NEIGHBORS nbr;
00131       LABELS lset;
00132       lit_p=lset.insert(lbl);
00133 
00134       if(!lit_p.second) {
00135         cout<<"level_one_map.insert: lbl insert(3) failed for lbl="<<lbl<<endl;
00136         return;
00137       }
00138 
00139       nit_p=nbr.insert(make_pair(V_EP::conv_hash_type(dest), lset));
00140       if(!nit_p.second) {
00141         cout<<"level_one_map.insert: dest insert(2) failed for dest="<<dest<<endl;
00142         return;
00143       }
00144 
00145       it_p=_hmap.insert(make_pair(V_EP::conv_hash_type(src), nbr));
00146       if(!it_p.second) {
00147         cout<<"level_one_map.insert: src insert(1) failed for src="<<src<<endl;
00148         return;
00149       }
00150     }//end else it!=hmap.find ..
00151 
00152   }//end insert()
00153 
00154 
00155   const LABELS& get_labels(const V_T& src, const V_T& dest) const {
00156     CONST_IT it=_hmap.find(V_EP::conv_hash_type(src));
00157     if(it==_hmap.end()) {
00158       cout<<"level_one_map.get_labels: src not found in hmap for src="<<src<<"*"<<endl;
00159       exit(0);
00160     }
00161     
00162     CONST_NIT nit=it->second.find(V_EP::conv_hash_type(dest));
00163     if(nit==it->second.end()) {
00164       return _empty_lbls;
00165     }
00166 
00167     return nit->second;
00168   }//end get_labels()
00169 
00170   const NEIGHBORS& get_neighbors(const V_T& src) const {
00171     CONST_IT it=_hmap.find(V_EP::conv_hash_type(src));
00172     if(it==_hmap.end()) {
00173       cout<<"level_one_map.get_neighbors: src not found in hmap for src="<<src<<endl;
00174       exit(0);
00175     }
00176     return it->second;
00177   }//end get_neighbors()
00178 
00179 
00180 private:
00181     // HMAP _hmap(HASHNS::hash<typename V_EP::HASH_TYPE>(), ALLOC<std::pair<const typename V_EP::HASH_TYPE, NEIGHBORS> >());
00182     HMAP _hmap;
00183     LABELS _empty_lbls;
00184     
00185 };//end class level_one_map
00186 
00187 #endif

Generated on Wed Jul 26 14:01:08 2006 for DMTL by  doxygen 1.4.7