RIFG.hpp

Go to the documentation of this file.
00001 
00022 #ifndef RepresentationIndependentFlowGraph_H
00023 #define RepresentationIndependentFlowGraph_H
00024 
00025 #include <iostream>
00026 #include <map>
00027 
00028 #include <OpenAnalysis/Utils/OA_ptr.hpp>
00029 #include <OpenAnalysis/Utils/DGraph/DGraphInterface.hpp>
00030 
00031 //***************************************************************************
00032 
00033 namespace OA {
00034   
00035   class RIFGNodeIterator;
00036   class RIFGEdgeIterator;
00037 
00038 //***************************************************************************
00039 // Class: Representation Independent Flowgraph Interface
00040 //
00041 // Description:
00042 //    A wrapper that allows access to an OA DGraph through dense id
00043 //    numbers ranging from 1 to n.  It is useful to interface with
00044 //    algorithms that worked by creating a work or result array of
00045 //    size n.  It might more appropriately be a mixin to an OA DGraph.
00046 //
00047 //***************************************************************************
00048 
00049 class RIFG {
00050 public:
00051 
00052   typedef unsigned int NodeId; // use RIFG::NIL for null value
00053   typedef unsigned int EdgeId; // use RIFG::NIL for null value
00054 
00055   static unsigned int NIL;
00056 
00057   
00058   typedef std::map<NodeId, OA::OA_ptr<OA::DGraph::NodeInterface> > 
00059     IdToNodeMap_t;
00060   typedef std::map<OA::OA_ptr<OA::DGraph::NodeInterface>, NodeId>
00061     NodeToIdMap_t;
00062   
00063   typedef std::map<EdgeId, OA::OA_ptr<OA::DGraph::EdgeInterface> > 
00064     IdToEdgeMap_t;
00065   typedef std::map<OA::OA_ptr<OA::DGraph::EdgeInterface>, EdgeId>
00066     EdgeToIdMap_t;
00067 
00068 public:
00069 
00070   class NodesIterator;
00071   class IncomingEdgesIterator;
00072   class OutgoingEdgesIterator;
00073 
00074   class NodesIterator {
00075   public:
00076     NodesIterator(const RIFG& rifg_)
00077       : rifg(rifg_), it(rifg.graph->getNodesIterator()) { }
00078     ~NodesIterator() { }
00079     
00080     RIFG::NodeId current() const {
00081       OA::OA_ptr<OA::DGraph::NodeInterface> node = it->current();
00082       return rifg.getNodeId(node);
00083     }
00084     void operator++() { ++(*it); }
00085     bool isValid() const { return it->isValid(); }
00086     void reset() { it->reset(); }
00087     
00088   private:
00089     const RIFG& rifg;
00090     OA_ptr<OA::DGraph::NodesIteratorInterface> it;
00091   };
00092 
00093 
00094   class IncomingEdgesIterator {
00095   public:
00096     IncomingEdgesIterator(const RIFG& rifg_, RIFG::NodeId nid)
00097       : rifg(rifg_) 
00098     {
00099       OA::OA_ptr<OA::DGraph::NodeInterface> n = rifg.getNode(nid);
00100       it = n->getIncomingEdgesIterator();
00101     }
00102     ~IncomingEdgesIterator() { }
00103     
00104     RIFG::EdgeId current() const {
00105       OA::OA_ptr<OA::DGraph::EdgeInterface> edge = it->current();
00106       return rifg.getEdgeId(edge);
00107     }
00108     void operator++() { ++(*it); }
00109     bool isValid() const { return it->isValid(); }
00110     
00111     void reset() { it->reset(); }
00112     
00113   private:
00114     const RIFG& rifg;
00115     OA_ptr<OA::DGraph::EdgesIteratorInterface> it;
00116   };
00117 
00118 
00119   class OutgoingEdgesIterator {
00120   public:
00121     OutgoingEdgesIterator(const RIFG& rifg_, RIFG::NodeId nid) 
00122       : rifg(rifg_) 
00123     {
00124       OA::OA_ptr<OA::DGraph::NodeInterface> n = rifg.getNode(nid);
00125       it = n->getOutgoingEdgesIterator();
00126     }
00127     ~OutgoingEdgesIterator() { }
00128     
00129     RIFG::EdgeId current() const {
00130       OA::OA_ptr<OA::DGraph::EdgeInterface> edge = it->current();
00131       return rifg.getEdgeId(edge);
00132     }
00133     void operator++() { ++(*it); }
00134     bool isValid() const { return it->isValid(); }
00135     
00136     void reset() { it->reset(); }
00137     
00138   private:
00139     const RIFG& rifg;
00140     OA_ptr<OA::DGraph::EdgesIteratorInterface> it;
00141   };
00142 
00143   
00144 public:
00145   RIFG(OA_ptr<DGraph::DGraphInterface> graph, 
00146        OA_ptr<DGraph::NodeInterface> source,
00147        OA_ptr<DGraph::NodeInterface> sink);
00148   ~RIFG();
00149   
00150   OA_ptr<DGraph::DGraphInterface> getGraph() { return graph; }
00151   
00152   // largest node/edge id in the graph
00153   NodeId getHighWaterMarkNodeId() const { return highWaterMarkNodeId; }
00154   EdgeId getHighWaterMarkEdgeId() const { return highWaterMarkEdgeId; }
00155 
00156   // is the node id still valid, or has it been freed
00157   bool isValid(NodeId nin) const;
00158 
00159   // Map between nodes/edges and node-ids/edge-ids.  Ids can be tested
00160   // against RIFG::NULL for validity.
00161   OA::OA_ptr<OA::DGraph::NodeInterface> 
00162   getNode(const NodeId nid) const
00163   { 
00164     OA::OA_ptr<OA::DGraph::NodeInterface> n;
00165     IdToNodeMap_t::const_iterator it = id_to_node_map.find(nid);
00166     if (it != id_to_node_map.end()) { n = (*it).second; }
00167     return n;
00168   }
00169   OA::OA_ptr<OA::DGraph::EdgeInterface> 
00170   getEdge(const EdgeId eid) const
00171   { 
00172     OA::OA_ptr<OA::DGraph::EdgeInterface> e;
00173     IdToEdgeMap_t::const_iterator it = id_to_edge_map.find(eid);
00174     if (it != id_to_edge_map.end()) { e = (*it).second; }
00175     return e;
00176   }
00177 
00178   NodeId 
00179   getNodeId(const OA::OA_ptr<OA::DGraph::NodeInterface> n) const
00180   { 
00181     NodeToIdMap_t::const_iterator it = node_to_id_map.find(n);
00182     return (it != node_to_id_map.end()) ? (*it).second : RIFG::NIL;
00183   }
00184   EdgeId 
00185   getEdgeId(const OA::OA_ptr<OA::DGraph::EdgeInterface> e) const
00186   { 
00187     EdgeToIdMap_t::const_iterator it = edge_to_id_map.find(e);
00188     return (it != edge_to_id_map.end()) ? (*it).second : RIFG::NIL;
00189   }
00190 
00191   // graph methods operating on the node-id/edge-id abstraction
00192   NodeId getSource() const;
00193   NodeId getSink() const;
00194   
00195   NodeId getEdgeSrc(EdgeId eid)  const;
00196   NodeId getEdgeSink(EdgeId eid) const;
00197   
00198   OA_ptr<NodesIterator> getNodesIterator() const;
00199   OA_ptr<IncomingEdgesIterator> getIncomingEdgesIterator(NodeId nid) const;
00200   OA_ptr<OutgoingEdgesIterator> getOutgoingEdgesIterator(NodeId nid) const;
00201   
00202   void dumpNode(std::ostream& os, NodeId nid);
00203 
00204 
00205   // helper methods to find the source and sink of a DGraph.  These
00206   // may be used with the constructor, e.g.:
00207   //  RIFG(graph, RIFG::getEntryNode(graph), RIFG::getExitNode(graph))
00208 
00209   static OA_ptr<DGraph::NodeInterface>
00210     getSourceNode(OA_ptr<DGraph::DGraphInterface> graph);
00211 
00212   static OA_ptr<DGraph::NodeInterface> 
00213     getSinkNode(OA_ptr<DGraph::DGraphInterface> graph);
00214 
00215 
00216   friend class NodesIterator;
00217 
00218 private:
00219   OA_ptr<DGraph::DGraphInterface> graph;
00220   OA_ptr<DGraph::NodeInterface> mSource; // graph source ('entry')
00221   OA_ptr<DGraph::NodeInterface> mSink;   // graph sink ('exit')
00222 
00223   NodeId highWaterMarkNodeId;
00224   EdgeId highWaterMarkEdgeId;
00225   
00226   IdToNodeMap_t id_to_node_map;
00227   NodeToIdMap_t node_to_id_map;
00228   IdToEdgeMap_t id_to_edge_map;
00229   EdgeToIdMap_t edge_to_id_map;
00230 
00231 };
00232 
00233 } // end of namespace OA
00234 
00235 #endif