Open64 (mfef90, whirl2f, and IR tools)  TAG: version-openad; SVN changeset: 916
graph_template.h
Go to the documentation of this file.
00001 /*
00002 
00003   Copyright (C) 2000, 2001 Silicon Graphics, Inc.  All Rights Reserved.
00004 
00005   This program is free software; you can redistribute it and/or modify it
00006   under the terms of version 2 of the GNU General Public License as
00007   published by the Free Software Foundation.
00008 
00009   This program is distributed in the hope that it would be useful, but
00010   WITHOUT ANY WARRANTY; without even the implied warranty of
00011   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
00012 
00013   Further, this software is distributed without any warranty that it is
00014   free of the rightful claim of any third person regarding infringement 
00015   or the like.  Any license provided herein, whether implied or 
00016   otherwise, applies only to this software file.  Patent licenses, if 
00017   any, provided herein do not apply to combinations of this program with 
00018   other software, or any other product whatsoever.  
00019 
00020   You should have received a copy of the GNU General Public License along
00021   with this program; if not, write the Free Software Foundation, Inc., 59
00022   Temple Place - Suite 330, Boston MA 02111-1307, USA.
00023 
00024   Contact information:  Silicon Graphics, Inc., 1600 Amphitheatre Pky,
00025   Mountain View, CA 94043, or:
00026 
00027   http://www.sgi.com
00028 
00029   For further information regarding this notice, see:
00030 
00031   http://oss.sgi.com/projects/GenInfo/NoticeExplan
00032 
00033 */
00034 
00035 
00036 //-*-c++-*-
00037 //
00208 #ifndef graph_template_INCLUDED
00209 #define graph_template_INCLUDED "graph_template.h"
00210 
00211 #ifdef _KEEP_RCS_ID
00212 #endif /* _KEEP_RCS_ID */
00213 
00214 #ifndef defs_INCLUDED
00215 #include "defs.h"
00216 #endif
00217 #ifndef mempool_INCLUDED
00218 #include "mempool.h"
00219 #endif
00220 #ifndef cxx_template_INCLUDED
00221 #include "cxx_template.h"
00222 #endif
00223 #ifndef cxx_graph_i_INCLUDED
00224 #include "cxx_graph.i"
00225 #endif
00226 #include "cxx_memory.h"
00227 
00228 
00229 template <class EDGE_TYPE, class VERTEX_TYPE>
00230 class DIRECTED_GRAPH16 {
00231 private:
00232   MEM_POOL      *_vmpool;       // pool used for vertex allocation
00233   MEM_POOL      *_empool;       // pool used for edge allocation
00234   VINDEX16      _vfree;         // the first vertex in the free vertex list
00235   EINDEX16      _efree;         // the first edge in the free edge list
00236 
00237                 DIRECTED_GRAPH16(const DIRECTED_GRAPH16&);
00238 protected:
00239   DYN_ARRAY<VERTEX_TYPE> _v;            // dynamic array for vertices
00240   VINDEX16      _vcnt;          // how many nodes there are in the graph
00241   DYN_ARRAY<EDGE_TYPE> _e;              // dynamic array for edges
00242   EINDEX16      _ecnt;          // how many edges there are in the graph
00243 
00244 public:
00245                 DIRECTED_GRAPH16(const VINDEX16 vsize, const EINDEX16 evsize);
00246                 ~DIRECTED_GRAPH16()             { 
00247                         _v.Free_array();
00248                         _e.Free_array();
00249                         MEM_POOL_Pop(_vmpool);
00250                         MEM_POOL_Delete(_vmpool);
00251                         CXX_DELETE(_vmpool,Malloc_Mem_Pool);
00252                         MEM_POOL_Pop(_empool);
00253                         MEM_POOL_Delete(_empool);
00254                         CXX_DELETE(_empool,Malloc_Mem_Pool);
00255                         }
00256 
00257   DIRECTED_GRAPH16<EDGE_TYPE,VERTEX_TYPE>& 
00258                 operator=(const DIRECTED_GRAPH16<EDGE_TYPE,VERTEX_TYPE>& g);
00259 
00260   void  Erase_Graph() { 
00261          _v.Setidx(0); _vcnt = 0; _vfree = 0; _e.Setidx(0); _ecnt = 0;
00262          _efree = 0; }
00263 
00264   VINDEX16      Add_Vertex();
00265   EINDEX16      Add_Edge(VINDEX16 from, VINDEX16 to);
00266   EINDEX16      Add_Unique_Edge(VINDEX16 from, VINDEX16 to);
00267 
00268   EINDEX16      Get_Edge(VINDEX16 from, VINDEX16 to) const;
00269   void          Delete_Vertex(VINDEX16 v);
00270   void          Delete_Edge(EINDEX16 e);
00271 
00272   VINDEX16      Get_Vertex() const;
00273   VINDEX16      Get_Next_Vertex(VINDEX16 v) const;
00274 
00275   EINDEX16      Get_Edge() const;
00276   EINDEX16      Get_Next_Edge(EINDEX16 e) const;
00277 
00278   BOOL          Vertex_Is_In_Graph(VINDEX16 v) const    {
00279                   return ((v <=_v.Lastidx()) && v>0 && !_v[v].Is_Free()); }
00280   BOOL          Edge_Is_In_Graph(EINDEX16 e) const      {
00281                   return ((e <=_e.Lastidx()) && e>0 && !_e[e].Is_Free()); }
00282 
00283   VINDEX16      Get_Source(EINDEX16 e) const    { 
00284                   Is_True (Edge_Is_In_Graph(e), ("Edge not in graph\n"));
00285                   return _e[e].Get_Source(); }
00286   VINDEX16      Get_Sink(EINDEX16 e) const      { 
00287                   Is_True (Edge_Is_In_Graph(e), ("Edge not in graph\n"));
00288                   return _e[e].Get_Sink(); }
00289 
00290   EINDEX16      Get_In_Edge(VINDEX16 v) const   { 
00291                   Is_True (Vertex_Is_In_Graph(v), ("Vertex not in graph\n"));
00292                   return _v[v].Get_In_Edge(); }
00293   EINDEX16      Get_Out_Edge(VINDEX16 v) const  { 
00294                   Is_True (Vertex_Is_In_Graph(v), ("Vertex not in graph\n"));
00295                   return _v[v].Get_Out_Edge(); }
00296 
00297   EINDEX16      Get_Next_In_Edge(EINDEX16 e) const
00298                                         { return _e[e].Get_Next_In_Edge(); }
00299   EINDEX16      Get_Next_Out_Edge(EINDEX16 e) const
00300                                         { return _e[e].Get_Next_Out_Edge(); }
00301 
00302   VINDEX16      Get_Vertex_Count() const        { return _vcnt; }
00303   EINDEX16      Get_Edge_Count() const          { return _ecnt; }
00304 
00305   BOOL          Is_Empty() const                { return _vcnt == 0; }
00306 
00307   void          Print(FILE *file) const;
00308 };
00309 
00310 // Implementation stuff from graph_template.cxx, since g++ (rightly)
00311 // doesn't do implicit .cxx file inclusion.
00312 template <class EDGE_TYPE, class VERTEX_TYPE>
00313 DIRECTED_GRAPH16<EDGE_TYPE,VERTEX_TYPE>::
00314 DIRECTED_GRAPH16( const VINDEX16 vsize, const EINDEX16 esize) {
00315 
00316   //Is_True( vsize >=0, ("Illegal graph size\n"));
00317 
00318   _vmpool = CXX_NEW(MEM_POOL,Malloc_Mem_Pool);
00319   MEM_POOL_Initialize(_vmpool,"vmpool",FALSE);
00320   MEM_POOL_Push(_vmpool);
00321   _v.Set_Mem_Pool(_vmpool);
00322   _v.Alloc_array(vsize+1);
00323   _v.Setidx( 0 );
00324   _vcnt = 0;
00325   _vfree = 0;
00326 
00327   //for (mINT16 i=1; i<=_vcnt; i++) {   // initialization
00328   //  _v[i].Set_Out_Edge(0);
00329   //  _v[i].Set_In_Edge(0);
00330   //}
00331 
00332   _empool = CXX_NEW(MEM_POOL,Malloc_Mem_Pool);
00333   MEM_POOL_Initialize(_empool,"empool",FALSE);
00334   MEM_POOL_Push(_empool);
00335   _e.Set_Mem_Pool(_empool);
00336   _e.Alloc_array(esize+1);
00337   _e.Setidx( 0 );
00338   _ecnt = 0;
00339   _efree = 0;
00340 
00341 }
00342 
00343 template <class EDGE_TYPE, class VERTEX_TYPE>
00344 VINDEX16
00345 DIRECTED_GRAPH16<EDGE_TYPE,VERTEX_TYPE>::Add_Vertex() {
00346   VINDEX16 new_vertex;
00347 
00348   // Is_True(_vcnt < GRAPH16_CAPACITY, ("Too many vertices\n"));
00349   if (_vcnt == GRAPH16_CAPACITY) return 0;
00350 
00351   if (_vfree == 0) { // grow the _v[] to accept more vertices
00352     new_vertex = _v.Newidx();
00353   } else {
00354     new_vertex = _vfree;
00355     _vfree = _v[_vfree].Get_Next_Free_Vertex();
00356   }
00357 
00358   // reset the in/out edge-lists to NULL
00359   _v[new_vertex].Set_Out_Edge(0);
00360   _v[new_vertex].Set_In_Edge(0);
00361 
00362   _vcnt++;
00363 
00364   return new_vertex;
00365 
00366 }
00367 
00368 template <class EDGE_TYPE, class VERTEX_TYPE>
00369 EINDEX16
00370 DIRECTED_GRAPH16<EDGE_TYPE,VERTEX_TYPE>::Add_Edge(VINDEX16 from, VINDEX16 to) {
00371   EINDEX16 new_edge;
00372 
00373   // Is_True(_ecnt < GRAPH16_CAPACITY, ("Too many edges\n"));
00374   if (_ecnt == GRAPH16_CAPACITY) return 0;
00375   if (_efree == 0) { // grow the _e[] to accept more edges
00376     new_edge = _e.Newidx();
00377   } else {
00378     new_edge = _efree;
00379     _efree = _e[_efree].Get_Next_Free_Edge();
00380   }
00381   
00382   _e[new_edge].Set_Source(from);
00383   _e[new_edge].Set_Sink(to);
00384 
00385   _ecnt++;
00386 
00387   // insert this edge into the out-edge list of the source vertex 'from'
00388   _e[new_edge].Set_Next_Out_Edge(_v[from].Get_Out_Edge());
00389   _v[from].Set_Out_Edge(new_edge);
00390 
00391   // insert this edge into the in-edge list of the sink vertex 'to'
00392   _e[new_edge].Set_Next_In_Edge(_v[to].Get_In_Edge());
00393   _v[to].Set_In_Edge(new_edge);
00394 
00395   return new_edge;
00396 
00397 }
00398 
00399 template <class EDGE_TYPE, class VERTEX_TYPE>
00400 EINDEX16
00401 DIRECTED_GRAPH16<EDGE_TYPE,VERTEX_TYPE>::Add_Unique_Edge(VINDEX16 from, VINDEX16 to) {
00402   EINDEX16 new_edge;
00403 
00404   // see if an edge already exists. No multiple edges between the same
00405   // pair of source and sink vertices.
00406   if (new_edge=Get_Edge(from,to)) return new_edge;
00407 
00408   return Add_Edge(from,to);
00409 
00410 }
00411 
00412 template <class EDGE_TYPE, class VERTEX_TYPE>
00413 EINDEX16
00414 DIRECTED_GRAPH16<EDGE_TYPE,VERTEX_TYPE>::Get_Edge(VINDEX16 from, VINDEX16 to) const {
00415   EINDEX16 e;
00416   e = _v[from].Get_Out_Edge();
00417   while (e != 0) {
00418     if (_e[e].Get_Sink() == to) return e;
00419     e = _e[e].Get_Next_Out_Edge();
00420   }
00421   return 0; // no corresponding edge
00422 }
00423 
00424 template <class EDGE_TYPE, class VERTEX_TYPE>
00425 void
00426 DIRECTED_GRAPH16<EDGE_TYPE,VERTEX_TYPE>::Delete_Vertex(VINDEX16 v) {
00427 
00428   EINDEX16 e;
00429 
00430   // see if the vertex exists
00431   Is_True (Vertex_Is_In_Graph(v), ("Vertex not in graph\n"));
00432 
00433   while (e = _v[v].Get_In_Edge()) {
00434     Delete_Edge(e);
00435   };
00436   while (e = _v[v].Get_Out_Edge()) {
00437     Delete_Edge(e);
00438   };
00439 
00440   // insert the deleted vertex in free list
00441   _v[v].Set_Next_Free_Vertex(_vfree);
00442   _v[v].Set_To_Free();
00443   _vfree = v;
00444 
00445   _vcnt--;
00446   
00447 }
00448 
00449 template <class EDGE_TYPE, class VERTEX_TYPE>
00450 void
00451 DIRECTED_GRAPH16<EDGE_TYPE,VERTEX_TYPE>::Delete_Edge(EINDEX16 e) {
00452 
00453   VINDEX16 from, to;
00454   EINDEX16 e1;
00455 
00456   // see if the edge exists
00457   Is_True (Edge_Is_In_Graph(e), ("Edge not in graph\n"));
00458 
00459   from = _e[e].Get_Source();
00460   to = _e[e].Get_Sink();
00461 
00462   if (_v[from].Get_Out_Edge() == e) {  // to delete the first edge in list
00463     _v[from].Set_Out_Edge(_e[e].Get_Next_Out_Edge());
00464   } else {
00465     e1 = _v[from].Get_Out_Edge();
00466     while (_e[e1].Get_Next_Out_Edge() != e) 
00467         e1 = _e[e1].Get_Next_Out_Edge();
00468     _e[e1].Set_Next_Out_Edge(_e[e].Get_Next_Out_Edge());
00469   }
00470 
00471   if (_v[to].Get_In_Edge() == e) {  // to delete the first edge in list
00472     _v[to].Set_In_Edge(_e[e].Get_Next_In_Edge());
00473   } else {
00474     e1 = _v[to].Get_In_Edge();
00475     while (_e[e1].Get_Next_In_Edge() != e) 
00476         e1 = _e[e1].Get_Next_In_Edge();
00477     _e[e1].Set_Next_In_Edge(_e[e].Get_Next_In_Edge());
00478   }
00479 
00480   _e[e].Set_Next_Free_Edge(_efree);  // insert the deleted edge in free list
00481   _e[e].Set_To_Free();
00482   _efree = e;
00483 
00484   _ecnt--;
00485   
00486 }
00487 
00488 template <class EDGE_TYPE, class VERTEX_TYPE>
00489 VINDEX16
00490 DIRECTED_GRAPH16<EDGE_TYPE,VERTEX_TYPE>::Get_Vertex() const {
00491   VINDEX16 v;
00492 
00493   if (Is_Empty()) return 0;
00494 
00495   v = _v.Lastidx();
00496   while (v>0 &&_v[v].Is_Free() ) v--;   // skip over free vertices
00497   Is_True( v>0 , ("Fail to get vertex\n"));
00498 
00499   return v;
00500 }
00501 
00502 template <class EDGE_TYPE, class VERTEX_TYPE>
00503 VINDEX16
00504 DIRECTED_GRAPH16<EDGE_TYPE,VERTEX_TYPE>::Get_Next_Vertex(VINDEX16 v) const {
00505 
00506   Is_True( Vertex_Is_In_Graph(v), ("Vertex does not exist in graph\n"));
00507 
00508   do {
00509     v--;
00510   } while (v>0 && _v[v].Is_Free() );    // skip over free vertices
00511 
00512   return v;
00513 }
00514 
00515 template <class EDGE_TYPE, class VERTEX_TYPE>
00516 EINDEX16
00517 DIRECTED_GRAPH16<EDGE_TYPE,VERTEX_TYPE>::Get_Edge() const {
00518   EINDEX16 e;
00519 
00520   if (_ecnt == 0) return 0;
00521 
00522   e = _e.Lastidx();
00523   while (_e[e].Is_Free() && e>0) e--;   // skip over free edges
00524   Is_True( e>0 , ("Fail to get edge\n"));
00525 
00526   return e;
00527 }
00528 
00529 template <class EDGE_TYPE, class VERTEX_TYPE>
00530 EINDEX16
00531 DIRECTED_GRAPH16<EDGE_TYPE,VERTEX_TYPE>::Get_Next_Edge(EINDEX16 e) const {
00532 
00533   Is_True( Edge_Is_In_Graph(e), ("Edge does not exist in graph\n"));
00534 
00535   do {
00536     e--;
00537   } while (e > 0 && _e[e].Is_Free() );  // skip over free edges
00538 
00539   return e;
00540 }
00541 
00542 template <class EDGE_TYPE, class VERTEX_TYPE>
00543 DIRECTED_GRAPH16<EDGE_TYPE,VERTEX_TYPE>&
00544 DIRECTED_GRAPH16<EDGE_TYPE,VERTEX_TYPE>::
00545 operator=(const DIRECTED_GRAPH16<EDGE_TYPE,VERTEX_TYPE>& g) {
00546 
00547   // copy everything except mpool
00548 
00549   _vfree = g._vfree;
00550   _vcnt = g._vcnt;
00551   _efree = g._efree;
00552   _ecnt = g._ecnt;
00553 
00554   _v = g._v;
00555   _e = g._e;
00556 
00557   return *this;
00558 }
00559 
00560 template <class EDGE_TYPE, class VERTEX_TYPE>
00561 void
00562 DIRECTED_GRAPH16<EDGE_TYPE,VERTEX_TYPE>::Print(FILE *file) const {
00563   VINDEX16 i;
00564   EINDEX16 e;
00565 
00566   fprintf(file,"Print out graph edges and vertices ...\n");
00567   for (i=1; i<_e.Lastidx()+1; i++)
00568    if (!_e[i].Is_Free())
00569     fprintf(file, "%d: %d --> %d\n", i, _e[i]._from, _e[i]._to);
00570 
00571   for (i=1; i<_v.Lastidx()+1; i++)
00572    if (!_v[i].Is_Free()) {
00573     fprintf(file, "( ");
00574     e = _v[i].Get_In_Edge();
00575     while (e) {
00576       fprintf(file, "%d ", e);
00577       e = _e[e].Get_Next_In_Edge();
00578     }
00579     fprintf(file, ") %d ( ", i);
00580     e = _v[i].Get_Out_Edge();
00581     while (e) {
00582       fprintf(file, "%d ", e);
00583       e = _e[e].Get_Next_Out_Edge();
00584     }
00585     fprintf(file, ")\n");
00586   }
00587 }
00588 
00589 #endif          // graph_template_INCLUDED
00590 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines