Polaris: SimGraphIterator.cc Source File

SimGraphIterator.cc

Go to the documentation of this file.
00001 ///
00002 /// \file SimGraphIterator.cc
00003 ///
00004 ///
00005 #ifdef POLARIS_GNU_PRAGMAS
00006 #pragma implementation
00007 #endif
00008 ///
00009 #include "SimGraphIterator.h"
00010 
00011 /// Create an empty iterator
00012 SimGraphIterator::SimGraphIterator( ) {
00013     #ifdef CLASS_INSTANCE_REGISTRY
00014     register_instance(SIM_GRAPH_ITERATOR, sizeof(SimGraphIterator), this);
00015     #endif
00016 
00017     _graph = NULL;
00018     _check_edge = NULL;
00019     _valid = false;
00020     _node1_pos = -1;
00021     _node2_pos = -1;
00022 }
00023 
00024 /// Reset the iterator position
00025 
00026 void
00027 SimGraphIterator::reset( ) 
00028 {
00029 
00030     /// ...  For all descrs which exist, set _check_edge to be true
00031 
00032     for (int i=0; i < _graph->_nodes; ++i) {
00033     if ( (*(_graph->_descr_exists))[i] ) {
00034 
00035         for (int j=i+1; j < _graph->_nodes; ++j ) {
00036         if ( (*(_graph->_descr_exists))[j] ) {
00037             
00038             ((*_check_edge)[i])[j] = true;
00039         }
00040         }
00041     }
00042     }
00043 
00044     /// ...  Search for the first valid pair of descriptors
00045 
00046     for (int i=0; i < _graph->_nodes; ++i) {
00047     if ( (*(_graph->_descr_exists))[i] ) {
00048 
00049         for (int j=i+1; j < _graph->_nodes; ++j ) {
00050         if ( (*(_graph->_descr_exists))[j] ) {
00051             
00052             _valid = true;
00053             _node1_pos = i;
00054             _node2_pos = j;
00055             return;
00056         }
00057         }
00058     }
00059     }
00060 
00061 
00062     _valid = false;
00063     _node1_pos = -1;
00064     _node2_pos = -1;
00065     return;
00066 }
00067 
00068 /// Make an iterator for an explicit graph
00069 
00070 SimGraphIterator::SimGraphIterator( SimGraph & graph )
00071 : _graph( &graph )
00072 {
00073     #ifdef CLASS_INSTANCE_REGISTRY
00074     register_instance(SIM_GRAPH_ITERATOR, sizeof(SimGraphIterator), this);
00075     #endif
00076 
00077     /// ...  Initialize to check every edge
00078 
00079     _check_edge = new Array< Array< bool > >;
00080     _check_edge->resize( _graph->_nodes );
00081 
00082     for (int i=0; i < _graph->_nodes; ++i) {
00083     (*_check_edge)[i].resize(_graph->_nodes);
00084     }
00085 
00086     reset( );
00087 }
00088 
00089 /// Update the Similarity graph due to the change in a single node
00090 
00091 void
00092 SimGraphIterator::record_change( SimTypeOfChange change, SimEdge & edge )
00093 {
00094     int index1;
00095     int index2;
00096 
00097     switch (change) {
00098     case SIM_COALESCE_NODE1:
00099     index1 = edge.index1();
00100     for (int i=0; i<_graph->_nodes; ++i) {
00101         ((*(_graph->_graph))[index1])[i].type( SIM_UNKNOWN );
00102         ((*_check_edge)[index1])[i] = true;
00103 
00104         ((*(_graph->_graph))[i])[index1].type( SIM_UNKNOWN );
00105         ((*_check_edge)[i])[index1] = true;
00106     }
00107     break;
00108 
00109     case SIM_COALESCE_NODE2:
00110     index2 = edge.index2();
00111     for (int i=0; i<_graph->_nodes; ++i) {
00112         ((*(_graph->_graph))[index2])[i].type( SIM_UNKNOWN );
00113         ((*_check_edge)[index2])[i] = true;
00114 
00115         ((*(_graph->_graph))[i])[index2].type( SIM_UNKNOWN );
00116         ((*_check_edge)[i])[index2] = true;
00117     }
00118     break;
00119 
00120     case SIM_CONTIG_NODE1:  /// ...  Found contiguous, keeping node 1
00121     index1 = edge.index1();
00122     index2 = edge.index2();
00123     (*(_graph->_descr_exists))[index2] = false;   /// ...  delete node index2
00124     for (int i=0; i<_graph->_nodes; ++i) {
00125         SimEdgeKernel & kernel = ((*(_graph->_graph))[index1])[i];
00126         kernel.type( contig_type( kernel.type( ) ) );
00127         ((*_check_edge)[index1])[i] = true;
00128 
00129         SimEdgeKernel & kernel2 = ((*(_graph->_graph))[i])[index1];
00130         kernel2.type( contig_type( kernel2.type( ) ) );
00131         ((*_check_edge)[i])[index1] = true;
00132     }
00133     break;
00134 
00135     case SIM_CONTIG_NODE2:  /// ...  Found contiguous, keeping node 2
00136     index1 = edge.index1();
00137     index2 = edge.index2();
00138     (*(_graph->_descr_exists))[index1] = false;   /// ...  delete node index1
00139     for (int i=0; i<_graph->_nodes; ++i) {
00140         SimEdgeKernel & kernel = ((*(_graph->_graph))[index2])[i];
00141         kernel.type( contig_type( kernel.type( ) ) );
00142         ((*_check_edge)[index2])[i] = true;
00143 
00144         SimEdgeKernel & kernel2 = ((*(_graph->_graph))[i])[index2];
00145         kernel2.type( contig_type( kernel2.type( ) ) );
00146         ((*_check_edge)[i])[index2] = true;
00147     }
00148     break;
00149 
00150     case SIM_SUBREG_NODE1:  /// ...  node 2 is a subregion of node 1 (keep node 1)
00151     index2 = edge.index2();
00152     (*(_graph->_descr_exists))[index2] = false;   /// ...  delete node index2
00153     break;
00154     case SIM_SUBREG_NODE2:   /// ...  node 1 is a subregion of node 2 (keep node 2)
00155     index1 = edge.index1();
00156     (*(_graph->_descr_exists))[index1] = false;   /// ...  delete node index1
00157     break;
00158     case SIM_EQUIVALENCE:
00159     index2 = edge.index2();
00160     (*(_graph->_descr_exists))[index2] = false;   /// ...  delete node index2
00161     break;
00162     case SIM_NOCHANGE:
00163     break;
00164     }
00165 
00166     return;
00167 }
00168 
00169 SimGraphIterator::~SimGraphIterator( )
00170 {
00171     #ifdef CLASS_INSTANCE_REGISTRY
00172     unregister_instance(SIM_GRAPH_ITERATOR, this);
00173     #endif
00174 
00175     if (_check_edge)
00176     delete _check_edge;
00177 }
00178 
00179 SimEdge & 
00180 SimGraphIterator::current( )
00181 {
00182     p_assert( _valid, "SimGraphIterator not valid on call to current()");
00183 
00184     SimEdgeKernel & kernel = ((*(_graph->_graph))[_node1_pos])[_node2_pos];
00185     SimilarityType type = kernel.type();
00186 
00187     if ((type == SIM_UNKNOWN) ||
00188     (type == SIM_DIM_EQUIV_UP) ||
00189     (type == SIM_STRIDE_EQUIV_UP)) {
00190 
00191     _graph->calc_similarity( _node1_pos, _node2_pos );
00192     }
00193 
00194     SimEdge * edge = new SimEdge( _node1_pos, _node2_pos,
00195                  &(*(*(_graph->_ptrs))[_node1_pos]), 
00196                  &(*(*(_graph->_ptrs))[_node2_pos]), 
00197                  &kernel);
00198     _created_edges.ins_last(edge);
00199 
00200     /// ...  Mark that this edge has been checked
00201 
00202     ((*_check_edge)[_node1_pos])[_node2_pos] = false;
00203 
00204     return *edge;
00205 }
00206 
00207 bool
00208 SimGraphIterator::valid( )
00209 {
00210     return _valid;
00211 }
00212 
00213 void
00214 SimGraphIterator::operator ++( )
00215 {
00216     int nodes = _graph->_nodes;
00217 
00218     /// ...  Find the next edge to visit
00219 
00220     int start_i = _node1_pos;
00221     int start_j = _node2_pos+1;
00222 
00223     /// ...  Make a private class for checking termination of the loop
00224 
00225     class Termination {
00226     private:
00227     int _limit;
00228     int _count;
00229     public:
00230     Termination(int nodes) { _count = 0; _limit = nodes*nodes;}  /// ...  At most nodes^2 iters of inner loop
00231     ~Termination(){}
00232     bool notdone() { ++_count; return (_count >= _limit) ? false : true; }
00233     bool done()    { return (_count >= _limit) ? true : false; }
00234     };
00235     Termination t(nodes);
00236 
00237 
00238     while (1) {
00239     for (int i=start_i; i < nodes; ++i,start_j=i+1) {
00240         if ( (*(_graph->_descr_exists))[i] ) {
00241 
00242         for (int j=start_j; t.notdone() && j < nodes; ++j) {
00243             if ((*(_graph->_descr_exists))[j] &&
00244             ((*_check_edge)[i])[j] ) {
00245 
00246             _valid = true;
00247             _node1_pos = i;
00248             _node2_pos = j;
00249             return;
00250             }
00251 
00252         }
00253         /// ...  See if we've gone totally around without finding an edge to visit
00254         if (t.done()) {
00255             _valid = false;
00256             _node1_pos = -1;
00257             _node2_pos = -1;
00258             return;
00259         }
00260         }
00261     }
00262     start_i = 0;
00263     start_j = 1;
00264     }
00265  
00266 /// Can never reach this point
00267 
00268     _valid = false;
00269     _node1_pos = -1;
00270     _node2_pos = -1;
00271     return;
00272 }
00273 
00274 /// Same as operator++
00275 
00276 void
00277 SimGraphIterator::next( )
00278 {
00279     ++(*this);
00280 }
00281 
00282 bool
00283 SimGraphIterator::end( ) const
00284 {
00285     return !_valid;
00286 }
00287     
00288 
00289 /// Mark all edges from this node as SIM_UNKNOWN
00290 void 
00291 SimGraphIterator::mark_unknown( AbstractAccess & node )
00292 {
00293     int node_index = -1;
00294 
00295     for (int i=0; i < _graph->_nodes; ++i) {
00296     if (((*(_graph->_ptrs))[i]).operator -> () == &node) {
00297         node_index = i;
00298         break;
00299     }
00300     }
00301 
00302     p_assert(node_index != -1,"Node not found in Similarity graph");
00303 
00304     for (int i=0; i<_graph->_nodes; ++i) {
00305     SimEdgeKernel & kernel = ((*(_graph->_graph))[node_index])[i];
00306     kernel.type( SIM_UNKNOWN );
00307     ((*_check_edge)[node_index])[i] = true;
00308 
00309     SimEdgeKernel & kernel2 = ((*(_graph->_graph))[i])[node_index];
00310     kernel2.type( SIM_UNKNOWN );
00311     ((*_check_edge)[i])[node_index] = true;
00312     }
00313 }
00314 
00315 /// Delete the given node from the graph
00316 void 
00317 SimGraphIterator::delete_node( AbstractAccess & node )
00318 {
00319     for (int i=0; i < _graph->_nodes; ++i) {
00320     if (((*(_graph->_ptrs))[i]).operator -> () == &node) {
00321         (*(_graph->_descr_exists))[i] = false;
00322         break;
00323     }
00324     }
00325 }
00326 
00327 void
00328 SimGraphIterator::delete_node( int node )
00329 {
00330     (*(_graph->_descr_exists))[node] = false;
00331 }
00332 
00333 void
00334 SimGraphIterator::print(ostream & o) const 
00335 {
00336     o << "{ ";
00337     if (_valid) {
00338     o << "VALID;";
00339     } else { 
00340     o << "NOT VALID;";
00341     }
00342 
00343     o << "(" << _node1_pos << "," << _node2_pos << ") }";
00344 }
00345 
00346 SimGraphIterator *
00347 SimGraphIterator::clone() const
00348 {
00349     return new SimGraphIterator( (SimGraphIterator &) *this );
00350 }
00351 
00352 Listable *
00353 SimGraphIterator::listable_clone() const
00354 {
00355     return (Listable *) clone();
00356 }
00357 
00358 ostream & 
00359 operator << (ostream & o, const SimGraphIterator & iter) 
00360 {
00361     iter.print(o);
00362     return o;
00363 }
 © 1995-2005 University of Illinois, Urbana-Champaign. All rights reserved.  Fri Mar 25 23:06:07 2005