// Follow connected junctions and connectors from the given junction to // determine the hyperedge topology, saving objects to the deleted-objects // vectors as we go. bool HyperedgeRerouter::findAttachedObjects(size_t index, JunctionRef *junction, ConnRef *ignore, ConnRefSet& hyperedgeConns) { bool validHyperedge = false; m_deleted_junctions_vector[index].push_back(junction); ConnRefList connectors = junction->attachedConnectors(); if (connectors.size() > 2) { // A valid hyperedge must have at least one junction with three // connectors attached, i.e., more than two endpoints. validHyperedge |= true; } for (ConnRefList::iterator curr = connectors.begin(); curr != connectors.end(); ++curr) { if (*curr == ignore) { continue; } COLA_ASSERT(*curr != NULL); validHyperedge |= findAttachedObjects(index, (*curr), junction, hyperedgeConns); } return validHyperedge; }
ConnRefList Obstacle::attachedConnectors(void) const { ConnRefList attachedConns; for (std::set<ConnEnd *>::const_iterator curr = m_following_conns.begin(); curr != m_following_conns.end(); ++curr) { ConnEnd *connEnd = *curr; COLA_ASSERT(connEnd->m_conn_ref != NULL); attachedConns.push_back(connEnd->m_conn_ref); } return attachedConns; }
// This method traverses the hyperedge tree and creates connectors for each // segment bridging junction and/or terminals. It also sets the // appropriate ConnEnds for each connector. // void HyperEdgeTreeEdge::addConns(HyperEdgeTreeNode *ignored, Router *router, ConnRefList& oldConns) { COLA_ASSERT(conn != NULL); HyperEdgeTreeNode *endNode = NULL; if (ends.first && (ends.first != ignored)) { endNode = ends.first; ends.first->addConns(this, router, oldConns, conn); } if (ends.second && (ends.second != ignored)) { endNode = ends.second; ends.second->addConns(this, router, oldConns, conn); } if (endNode->finalVertex) { // We have reached a terminal of the hyperedge, so set a ConnEnd for // the original connector endpoint ConnEnd connend; bool result = false; // Find the ConnEnd from the list of original connectors. for (ConnRefList::iterator curr = oldConns.begin(); curr != oldConns.end(); ++curr) { result |= (*curr)->getConnEndForEndpointVertex( endNode->finalVertex, connend); if (result) { break; } } if (result) { // XXX: Create new conn here. conn->updateEndPoint(VertID::tar, connend); } } else if (endNode->junction) { // Or, set a ConnEnd connecting to the junction we have reached. ConnEnd connend(endNode->junction); conn->updateEndPoint(VertID::tar, connend); } }
// This method traverses the hyperedge tree and rewrites connector ends // that may have changed junctions due to major hyperedge improvement. // void HyperedgeTreeEdge::updateConnEnds(HyperedgeTreeNode *ignored, bool forward, ConnRefList& changedConns) { HyperedgeTreeNode *endNode = NULL; if (ends.first && (ends.first != ignored)) { endNode = ends.first; ends.first->updateConnEnds(this, forward, changedConns); } if (ends.second && (ends.second != ignored)) { endNode = ends.second; ends.second->updateConnEnds(this, forward, changedConns); } if (endNode->junction) { // We've reached a junction at the end of this connector, and it's // not an endpoint of the hyperedge. So the connector ConnEnd to // connect to the junction we have reached. std::pair<ConnEnd, ConnEnd> existingEnds = conn->endpointConnEnds(); ConnEnd existingEnd = (forward) ? existingEnds.second : existingEnds.first; if (existingEnd.junction() != endNode->junction) { #ifdef MAJOR_HYPEREDGE_IMPROVEMENT_DEBUG fprintf(stderr, "HyperedgeImprover: changed %s of " "connector %u (from junction %u to %u)\n", (forward) ? "tar" : "src", conn->id(), existingEnd.junction()->id(), endNode->junction->id()); #endif ConnEnd connend(endNode->junction); unsigned short end = (forward) ? VertID::tar : VertID::src; conn->updateEndPoint(end, connend); // Record that this connector was changed (so long as it wasn't // already recorded). if (changedConns.empty() || (changedConns.back() != conn)) { changedConns.push_back(conn); } } } }
// Follow connected junctions and connectors from the given junction to // determine the hyperedge topology, saving objects to the deleted-objects // vectors as we go. void HyperedgeRerouter::findAttachedObjects(size_t index, JunctionRef *junction, ConnRef *ignore, ConnRefSet& hyperedgeConns) { m_deleted_junctions_vector[index].push_back(junction); ConnRefList connectors = junction->attachedConnectors(); for (ConnRefList::iterator curr = connectors.begin(); curr != connectors.end(); ++curr) { if (*curr == ignore) { continue; } COLA_ASSERT(*curr != NULL); findAttachedObjects(index, (*curr), junction, hyperedgeConns); } }
// This method traverses the hyperedge tree and returns a list of the junctions // and connectors that make up the hyperedge. // void HyperEdgeTreeEdge::listJunctionsAndConnectors(HyperEdgeTreeNode *ignored, JunctionRefList& junctions, ConnRefList& connectors) { ConnRefList::iterator foundPosition = std::find(connectors.begin(), connectors.end(), conn); if (foundPosition == connectors.end()) { // Add connector if it isn't already in the list. connectors.push_back(conn); } if (ends.first != ignored) { ends.first->listJunctionsAndConnectors(this, junctions, connectors); } else if (ends.second != ignored) { ends.second->listJunctionsAndConnectors(this, junctions, connectors); } }
// This method traverses the hyperedge tree and rewrites connector ends // that may have changed junctions due to major hyperedge improvement. // void HyperedgeTreeNode::updateConnEnds(HyperedgeTreeEdge *ignored, bool forward, ConnRefList& changedConns) { for (std::list<HyperedgeTreeEdge *>::iterator curr = edges.begin(); curr != edges.end(); ++curr) { HyperedgeTreeEdge *edge = *curr; if (edge != ignored) { if (junction) { // If we're at a junction, then we are effectively starting // our traversal along a connector, so create this new connector // and set it's start ConnEnd to be this junction. forward = travellingForwardOnConnector(edge->conn, junction); std::pair<ConnEnd, ConnEnd> existingEnds = edge->conn->endpointConnEnds(); ConnEnd existingEnd = (forward) ? existingEnds.first : existingEnds.second; if (existingEnd.junction() != junction) { #ifdef MAJOR_HYPEREDGE_IMPROVEMENT_DEBUG fprintf(stderr, "HyperedgeImprover: changed %s of " "connector %u (from junction %u to %u)\n", (forward) ? "src" : "tar", edge->conn->id(), existingEnd.junction()->id(), junction->id()); #endif unsigned short end = (forward) ? VertID::src : VertID::tar; ConnEnd connend(junction); edge->conn->updateEndPoint(end, connend); changedConns.push_back(edge->conn); } } // Continue recursive traversal. edge->updateConnEnds(this, forward, changedConns); } } }