+/* Copyright (c) 2007-2011, 2014. The SimGrid Team.
+ * All rights reserved. */
-//SGNode, SGTopology: tmporary classes for GTNetS topology.
+/* This program is free software; you can redistribute it and/or modify it
+ * under the terms of the license (GNU LGPL) which comes with this package. */
+
+//GTNETS_Link, GTNETS_Node, GTNETS_Topology:
+//Temporary classes for generating GTNetS topology
#include "gtnets_topology.h"
+#ifdef XBT_DEBUG
+ #undef XBT_DEBUG
+#endif
+#include "xbt/log.h"
+#include "xbt/asserts.h"
+#include <stdio.h> //for fflush in print_topology
+
+XBT_LOG_NEW_DEFAULT_SUBCATEGORY(surf_network_gtnets_topology, surf_network_gtnets,
+ "Logging specific to the SURF network GTNetS simulator");
//
-// SGNode
+// GTNETS_Node
//
-// TODO when merging a node, remember to add the existing "hosts".
-SGNode::SGNode(int id, int hostid){
- ID_ = id;
- if (hostid >= 0)
- hosts_.push_back(hostid);
-}
-SGNode::~SGNode(){
- //TODO
-}
-
-void SGNode::add_link(SGLink* newlink){
- links_.push_back(newlink);
+// Constructor
+GTNETS_Node::GTNETS_Node(int id):ID_(id),is_router_(false){}
+// Copy constructor
+GTNETS_Node::GTNETS_Node(const GTNETS_Node& node){
+ ID_ = node.ID_;
+ is_router_ = node.is_router_;
+ hosts_ = node.hosts_;
}
+GTNETS_Node::~GTNETS_Node(){
-SGLink* SGNode::other_link(int linkid){
- for (int i = 0; i < links_.size(); i++){
- if (links_[i]->id() != linkid)
- return links_[i];
- }
- return NULL;
}
-bool SGNode::has_link(SGLink* link){
- for (int i = 0; i < links_.size(); i++){
- //TODO can compare by object itself?
- if ((links_[i]->id()) == (link->id()))
- return true;
- }
- return false;
+// hostid = network_card_id
+int GTNETS_Node::add_host(int hostid){
+ xbt_assert(!(is_router_), "Cannot add a host to a router node");
+ hosts_.insert(hostid);
+ return 0;
}
-void SGNode::print_hosts(){
- cout << "hosts[";
- for (int i = 0; i < hosts_.size(); i++){
- cout << hosts_[i] << ",";
+// Add a router. If this node already has a router/host,
+// return -1.
+int GTNETS_Node::add_router(int routerid){
+ xbt_assert(!(hosts_.size() > 1), "Router node should have only one router");
+ if (hosts_.size() == 1){
+ xbt_assert((hosts_.find(routerid) != hosts_.end()), "Node %d is a different router", routerid);
+ return 0;
}
- cout << "] ";
+ is_router_ = true;
+ hosts_.insert(routerid);
+ return 0;
}
-void SGNode::print_links(){
- cout << "links[";
- for (int i = 0; i < links_.size(); i++){
- cout << links_[i]->id() << ",";
- }
- cout << "]" << endl;
+bool GTNETS_Node::is_router(){
+ return is_router_;
}
-vector<SGLink*>& SGNode::links(){
- return links_;
+bool GTNETS_Node::include(int hostid){
+ if (hosts_.find(hostid) == hosts_.end()) return false;
+ else return true;
}
-vector<int>& SGNode::hosts(){
- return hosts_;
+
+void GTNETS_Node::print_hosts(){
+ set<int>::iterator it;
+ for (it = hosts_.begin(); it != hosts_.end(); it++){
+ XBT_DEBUG("host id %d", *it);
+ }
}
//
-// SGLink
+// GTNETS_Link
//
-SGLink::SGLink(int id, SGNode* left, SGNode* right)
- :ID_(id),
- left_node_(left),
- right_node_(right){}
+// Constructor
+GTNETS_Link::GTNETS_Link(){
+ ID_=-1;
+ src_node_ = 0;
+ dst_node_ = 0;
+}
+GTNETS_Link::GTNETS_Link(int id):ID_(id), src_node_(0), dst_node_(0){}
-SGLink::~SGLink(){
+// Copy constructor
+GTNETS_Link::GTNETS_Link(const GTNETS_Link& link){
+ ID_ = link.ID_;
+ src_node_ = link.src_node_;
+ dst_node_ = link.dst_node_;
+}
+GTNETS_Link::~GTNETS_Link(){
+
}
-// add_left_linK: tow things.
-// add the link to the corresponding node.
-// add the corresponding node to the new link.
-// (change from the tmp node to the correct node)
-void SGLink::add_left_link(SGLink* newlink, int side){
- if (!left_node_){
- //if alllinks don't have a node, then copy it from
- //tmporary link.
- if (side == LEFTSIDE){
- left_node_ = newlink->left_node_;
- } else if (side == RIGHTSIDE){
- left_node_ = newlink->right_node_;
- } else {
- cout << "should not come here. side: " << side << endl;
- }
- } else {
- // if already exists, then add the new link to the existing node.
- left_node_->add_link(newlink);
+void GTNETS_Link::print_link_status(){
+ XBT_DEBUG("****** link id: %d", ID_);
+ if (src_node_){
+ XBT_DEBUG("[src] id: %d, is it router?: %d",src_node_->id(), src_node_->is_router());
}
- if (side == LEFTSIDE){
- newlink->left_node_ = left_node_;
- //printf("link[%d] new left node: %d\n", link.ID, @left_node.ID)
- }else if (side == RIGHTSIDE){
- newlink->right_node_ = left_node_;
- //printf("link[%d] new left node: %d\n", link.ID, @left_node.ID)
- }else{
- cout << "should not come here. side: " << side << endl;
+ if (dst_node_){
+ XBT_DEBUG("[dst] id: %d, is it router?: %d",dst_node_->id(), dst_node_->is_router());
}
-
}
-void SGLink::add_right_link(SGLink* newlink, int side){
- if (!right_node_) {
- //if alllinks doesn't have a node, then copy it from
- //tmporary link.
- if (side == LEFTSIDE){
- right_node_ = newlink->left_node_;
- }else if (side == RIGHTSIDE){
- right_node_ = newlink->right_node_;
- }else{
- cout << "should not come here. side: " << side << endl;
- }
- }else{
- right_node_->add_link(newlink);
- }
+GTNETS_Node* GTNETS_Link::src_node(){
+ return src_node_;
+}
- if (side == LEFTSIDE){
- newlink->left_node_ = right_node_;
- //printf("link[%d] new left node: %d\n", link.ID, @right_node.ID)
- }else if (side == RIGHTSIDE){
- newlink->right_node_ = right_node_;
- //printf("link[%d] new right node: %d\n", link.ID, @right_node.ID)
- }else{
- cout << "should not come here. side: " << side << endl;
- }
+GTNETS_Node* GTNETS_Link::dst_node(){
+ return dst_node_;
}
-bool SGLink::is_inleft(SGLink* link){
- if (!left_node_)
- return false;
- else
- return left_node_->has_link(link);
+bool GTNETS_Link::route_exists(){
+ if (src_node_ && dst_node_) return true;
+ else return false;
}
-bool SGLink::is_inright(SGLink* link){
- if (!right_node_)
- return false;
- else
- return right_node_->has_link(link);
+// return the peer node id
+int GTNETS_Link::peer_node(int cur_id){
+ xbt_assert(((cur_id == src_node_->id())||(cur_id == dst_node_->id())), "Node not found");
+
+ if (cur_id == src_node_->id()) return dst_node_->id();
+ else if (cur_id == dst_node_->id()) return src_node_->id();
}
+int GTNETS_Link::add_src(GTNETS_Node* src){
+ src_node_ = src;
+}
-//return the pointer for the left link.
-SGLink* SGLink::left_link(){
- if (!left_node_){
- return NULL;
- }else{
- return left_node_->other_link(ID_);
- }
+int GTNETS_Link::add_dst(GTNETS_Node* dst){
+ dst_node_ = dst;
}
-SGLink* SGLink::right_link(){
- if (!right_node_){
- return NULL;
- }else{
- return right_node_->other_link(ID_);
- }
+//
+// GTNETS_Topology
+//
+
+// Constructor
+GTNETS_Topology::GTNETS_Topology(){
+ nodeID_ = 0;
}
-SGNode* SGLink::left_node(){
- return left_node_;
+// Destructor
+GTNETS_Topology::~GTNETS_Topology(){
+ map<int, GTNETS_Link*>::iterator it1;
+ for (it1 = links_.begin(); it1 != links_.end(); it1++){
+ delete it1->second;
+ }
+ vector<GTNETS_Node*>::iterator it2;
+ for (it2 = nodes_.begin(); it2 != nodes_.end(); it2++){
+ delete *it2;
+ }
}
-SGNode* SGLink::right_node(){
- return right_node_;
+int GTNETS_Topology::link_size(){
+ return links_.size();
+}
+
+int GTNETS_Topology::node_size(){
+ return nodes_.size();
}
+int GTNETS_Topology::add_link(int id){
+ map<int,GTNETS_Link*>::iterator iter = links_.find(id);
+ xbt_assert((iter == links_.end()), "Link %d already exists", id);
-void SGLink::print(){
- printf("link[%d]:\n", ID_);
- if (left_node_){
- printf(" left node: %d ", left_node_->id());
- left_node_->print_hosts();
- left_node_->print_links();
- }
-
- if (right_node_){
- printf(" right node: %d ", right_node_->id());
- right_node_->print_hosts();
- right_node_->print_links();
+ if(iter == links_.end()) {
+ GTNETS_Link* link= new GTNETS_Link(id);
+ links_[id] = link;
}
+ return 0;
}
+int GTNETS_Topology::add_router(int id){
+ set<int>::iterator iter = routers_.find(id);
+ if(iter == routers_.end()){
+ routers_.insert(id);
+ }else{
+ XBT_DEBUG("Router (#%d) already exists", id);
+ }
+ return 0;
+}
-SGTopology::SGTopology(){
- nodeID_ = 0;
+bool GTNETS_Topology::is_router(int id){
+ set<int>::iterator iter = routers_.find(id);
+ if(iter == routers_.end()) return false;
+ else return true;
}
-SGTopology::~SGTopology(){
+//return the node id of the peer of cur_id by linkid.
+int GTNETS_Topology::peer_node_id(int linkid, int cur_id){
+ GTNETS_Link* link = links_[linkid];
+ xbt_assert((link), "Link %d not found", linkid);
+ xbt_assert(!((cur_id < 0) || (cur_id > nodes_.size()-1)), "Node %d not found", cur_id);
+
+ int peer = link->peer_node(nodes_[cur_id]->id());
+ xbt_assert(!(peer < 0), "Peer not found");
+ return peer;
}
+int GTNETS_Topology::add_onehop_route(int src, int dst, int linkid){
+ GTNETS_Link* link;
-// TODO: assume that all router-route 1-hop routes are set.
-void SGTopology::add_link(int src, int dst, int* links, int nsize){
- if (nsize == 1){
- map<int, SGNode*>::iterator it;
- it = nodes_.find(src);
- //if not exists, add one.
- if (it == nodes_.end()){
- nodes_[src] = new SGNode(src, src);
- }
- it = nodes_.find(dst);
- //if not exists, add one.
- if (it == nodes_.end()){
- nodes_[dst] = new SGNode(dst, dst);
- }
+ map<int, GTNETS_Link*>::iterator iter = links_.find(linkid);
- map<int, SGLink*>::iterator itl;
- itl = links_.find(links[0]);
- //if not exists, add one.
- if (itl == links_.end()){
- links_[links[0]] = new SGLink(links[0], nodes_[src], nodes_[dst]);
- }
- }
-}
+ xbt_assert(!(iter == links_.end()), "Link %d not found", linkid);
+ link = iter->second;
+ XBT_DEBUG("Add onehop route, src (#%d), dst (#%d), linkid %d:(#%d)",src, dst, linkid, link->id());
-//create a temporary link set. (one route)
-// not used now. should clean up...
-void SGTopology::create_tmplink(int src, int dst, int* links, int nsize){
- map<int, SGLink*> tmplinks;
+ GTNETS_Node *src_node, *dst_node;
+ src_node = link->src_node();
+ dst_node = link->dst_node();
- SGNode* n1;
- SGNode* n2;
+ // If not exists a route, add one.
+ if (!link->route_exists()){
+ //check whether there exists a node for the src.
+ int s_node_id = nodeid_from_hostid(src);
+ int node_id;
- int cur = -1;
- int nex;
+ if (s_node_id < 0){//not exist, create one.
+ s_node_id = nodeID_;
+ GTNETS_Node* node1 = new GTNETS_Node(s_node_id);
+ nodes_.push_back(node1);
+ hosts_[src] = nodes_[s_node_id]->id();
- for (int i = 0; i < nsize; i++){
- if (i == 0) {
- nodeID_++; //new node
- n1 = new SGNode(nodeID_, src);
- }else
- n1 = n2; //current
-
- cur = links[i];
-
- if (i == (nsize-1)){
nodeID_++;
- n2 = new SGNode(nodeID_, dst);
- }else{
- nex = links[i+1];
- nodeID_++; //new node
- n2 = new SGNode(nodeID_, -1);
}
- tmplinks[cur] = new SGLink(cur, n1, n2);
- if (n1) n1->add_link(tmplinks[cur]);
- if (n2) n2->add_link(tmplinks[cur]);
- }
+ if (is_router(src))
+ nodes_[s_node_id]->add_router(src);
+ else
+ nodes_[s_node_id]->add_host(src);
- for (int i = 0; i < nsize; i++){
- //tmplinks[links[i]]->print();
- merge_link(tmplinks[links[i]]);
- }
- add_tmplink_to_links(tmplinks);
-}
+ link->add_src(nodes_[s_node_id]);
-void SGTopology::merge_link(SGLink* link){
- map<int, SGLink*>::iterator iter;
- iter = links_.find(link->id());
- if (iter == links_.end()){
- //if the link has not been added to the topology.links_, then
- //printf("link %d doesn't exist in alllinks. No action.\n", link->id());
- return;
- }else{
- int ncommon = 0;
- int comleft = -1; //if tmplink.left == @alllinks.link.left, 0, otherwise, 1.
- int comright = -1; //if tmplink.right == @alllinks.link.left, 0, otherwise, 1.
- //since link is from tmplinks, each link has at most two neibours.
-
- if (link->left_link()){
- //printf("common neibor: left_first: %d\n", link->left_link()->id());
- if (links_[link->id()]->is_inleft(link->left_link())){
- comleft = 0;
- ncommon += 1;
- }
- if (links_[link->id()]->is_inright(link->left_link())){
- comleft = 1;
- ncommon += 1;
- }
+ //check whether there exists a node for the dst host/router.
+ int d_node_id = nodeid_from_hostid(dst);
+ if (d_node_id < 0){//not exist, create one.
+ d_node_id = nodeID_;
+ GTNETS_Node* node2 = new GTNETS_Node(d_node_id);
+ nodes_.push_back(node2);
+ hosts_[dst] = nodes_[d_node_id]->id();
+ nodeID_++;
}
- if (link->right_link()){
- //printf("common neibor: right_first: %d\n", link->right_link()->id());
- if (links_[link->id()]->is_inleft(link->right_link())){
- comright = 0;
- ncommon += 1;
- }
- if (links_[link->id()]->is_inright(link->right_link())){
- comright = 1;
- ncommon += 1;
- }
- }
+ if (is_router(dst))
+ nodes_[d_node_id]->add_router(dst);
+ else
+ nodes_[d_node_id]->add_host(dst);
- //printf("common: %d, comright: %d, comleft: %d\n",ncommon, comright, comleft);
+ link->add_dst(nodes_[d_node_id]);
+ }else if (!(src_node && dst_node)){
+ xbt_assert((src_node && dst_node), "Either src or dst is null");
+ }
- if (ncommon == 0){
- //merge link.n1 with @alllink.n1, link.n2 with @alllink.n2
- if (link->left_link())
- links_[link->id()]->add_left_link(link->left_link(), RIGHTSIDE);
+ // case 1: link has two routers
+ else if (src_node->is_router() && dst_node->is_router()){
+ int tmpsrc1 = src_node->id();
+ int tmpsrc2 = nodeid_from_hostid(src);
+ int tmpdst1 = dst_node->id();
+ int tmpdst2 = nodeid_from_hostid(dst);
+ xbt_assert( (((tmpsrc1 == tmpsrc2) && (tmpdst1 == tmpdst2)) ||
+ ((tmpsrc1 == tmpdst2) && (tmpdst1 == tmpsrc2))), "Different one hop route defined");
+ }
- if (link->right_link())
- links_[link->id()]->add_right_link(link->right_link(), LEFTSIDE);
-
- }else if (ncommon == 1){
- printf("ncommon %d\n", links_[link->id()]->id());
- //left --> right
- if ((comleft == -1) && (comright == 0)){
- if (link->left_link())
- links_[link->id()]->add_right_link(link->left_link(), RIGHTSIDE);
- }else if ((comleft == -1) && (comright == 1)){
- //left --> left
- if (link->left_link())
- links_[link->id()]->add_left_link(link->left_link(), RIGHTSIDE);
- }else if ((comright == -1) && (comleft == 0)){
- //right --> right
- if (link->right_link())
- links_[link->id()]->add_right_link(link->right_link(), LEFTSIDE);
- }else if ((comright == -1) && (comleft == 1)){
- //right --> left
- if (link->right_link())
- links_[link->id()]->add_left_link(link->right_link(), LEFTSIDE);
- }else{
- fprintf(stderr, "should not come here\n");
- }
+ // case 2: link has one router and one host
+ else if (src_node->is_router() && !dst_node->is_router()){
+ int newsrc, newdst;
+ xbt_assert( ((is_router(src))||(is_router(dst))), "One of nodes should be a router");
+
+ if (is_router(src)){
+ newsrc = src;
+ newdst = dst;
+ }else if (is_router(dst)){
+ newsrc = dst;
+ newdst = src;
+ }
- }else if (ncommon == 2){
- //no change
+ xbt_assert(!(src_node->id() != nodeid_from_hostid(newsrc)), "The router should be identical");
- }else{
- fprintf(stderr, "error, common links are more than 2. %d\n", ncommon);
+ //now, to add dst to dst_node, dst should be a host.
+ xbt_assert(!(is_router(newdst)), "Dst %d is not an endpoint. cannot add it to dst_node", newdst);
+
+ if (!dst_node->include(newdst)){
+ dst_node->add_host(newdst);
+ hosts_[newdst] = dst_node->id();
}
}
-}
+ else if (!src_node->is_router() && dst_node->is_router()){
+ int newsrc, newdst;
+ xbt_assert(((is_router(src))||(is_router(dst))), "One of nodes should be a router");
+
+ if (is_router(src)){
+ newsrc = dst;
+ newdst = src;
+ }else if (is_router(dst)){
+ newsrc = src;
+ newdst = dst;
+ }
-void SGTopology::add_tmplink_to_links(map<int, SGLink*> tmplink){
- map<int, SGLink*>::iterator iter;
+ xbt_assert(!(dst_node->id() != hosts_[newdst]), "The router should be identical");
+ //now, to add dst to src_node, dst should be a host.
+ xbt_assert(!(is_router(newsrc)), "Src %d is not an endpoint. cannot add it to src_node", newsrc);
- for (iter = tmplink.begin(); iter != tmplink.end(); iter++){
- map<int, SGLink*>::iterator alliter = links_.find(iter->first);
- if (alliter == links_.end()){
- // cout << "tmplink " << iter->first << " not found in links_, adding."
- // << endl;
- links_[iter->first] = iter->second;
+ if (!src_node->include(newsrc)){
+ src_node->add_host(newsrc);
+ hosts_[newsrc] = src_node->id();
}
- // cout << "tmplink: " << iter->second->id() << endl;
}
-
-}
-void SGTopology::print_topology(){
- map<int, SGLink*>::iterator iter;
- for (iter = links_.begin(); iter != links_.end(); iter++){
- iter->second->print();
+ // case 3: link has two hosts
+ else if (!src_node->is_router() && !dst_node->is_router()){
+ xbt_assert(!(is_router(src) || is_router(dst)), "Cannot add a router to host-host link");
+
+ //if both are hosts, the order doesn't matter.
+ if (src_node->include(src)){
+ if (dst_node->include(dst)){
+ //nothing
+ }else{
+ dst_node->add_host(dst);
+ hosts_[dst] = dst_node->id();
+ }
+ }else if (src_node->include(dst)){
+ if (dst_node->include(src)){
+ //nothing
+ }else{
+ dst_node->add_host(src);
+ hosts_[src] = dst_node->id();
+ }
+ }else if (dst_node->include(src)){
+ if (src_node->include(dst)){
+ //nothing
+ }else{
+ src_node->add_host(dst);
+ hosts_[dst] = src_node->id();
+ }
+ }else if (dst_node->include(dst)){
+ if (src_node->include(src)){
+ //nothing
+ }else{
+ src_node->add_host(src);
+ hosts_[src] = src_node->id();
+ }
+ }else{
+ src_node->add_host(src);
+ dst_node->add_host(dst);
+ hosts_[src] = src_node->id();
+ hosts_[dst] = dst_node->id();
+ }
+
+ }
+ else{
+ xbt_die("Shouldn't be here");
}
+
+ return 0;
+}
+
+int GTNETS_Topology::nodeid_from_hostid(int hostid){
+ map<int,int>::iterator it = hosts_.find(hostid);
+ if (it == hosts_.end())
+ return -1;
+ else return it->second;
}
-void SGTopology::create_gtnets_topology(){
- map<int, SGLink*>::iterator it;
+void GTNETS_Topology::print_topology(){
+ XBT_DEBUG("<<<<<================================>>>>>");
+ XBT_DEBUG("Dumping GTNETS topollogy information");
+ map<int, GTNETS_Link*>::iterator it;
for (it = links_.begin(); it != links_.end(); it++){
-
+ it->second->print_link_status();
}
+ XBT_DEBUG(">>>>>================================<<<<<");
+ fflush(NULL);
+}
+
+const vector<GTNETS_Node*>& GTNETS_Topology::nodes(){
+ return nodes_;
}
-map<int, SGLink*>& SGTopology::get_links(){
+const map<int, GTNETS_Link*>& GTNETS_Topology::links(){
return links_;
}