3 /* Copyright (c) 2007 Kayo Fujiwara. All rights reserved. */
5 /* This program is free software; you can redistribute it and/or modify it
6 * under the terms of the license (GNU LGPL) which comes with this package. */
8 //GTNETS_Link, GTNETS_Node, GTNETS_Topology:
9 //Temporary classes for generating GTNetS topology
11 #include "gtnets_topology.h"
18 GTNETS_Node::GTNETS_Node(int id):ID_(id),is_router_(false){}
20 GTNETS_Node::GTNETS_Node(const GTNETS_Node& node){
22 is_router_ = node.is_router_;
26 GTNETS_Node::~GTNETS_Node(){
30 // hostid = network_card_id
31 int GTNETS_Node::add_host(int hostid){
33 fprintf(stderr, "Cannot add a host to a router node.\n");
36 hosts_.insert(hostid);
40 // Add a router. If this node already has a router/host,
42 int GTNETS_Node::add_router(int routerid){
43 if (hosts_.size() > 1){
44 fprintf(stderr, "Router node should have only one router.\n");
46 }else if (hosts_.size() == 1){
47 if (hosts_.find(routerid) != hosts_.end()){
48 //printf("the router already exists\n");
51 fprintf(stderr, "Node %d is a different router.\n");
56 hosts_.insert(routerid);
60 bool GTNETS_Node::is_router(){
64 bool GTNETS_Node::include(int hostid){
65 if (hosts_.find(hostid) == hosts_.end()) return false;
69 void GTNETS_Node::print_hosts(){
70 set<int>::iterator it;
72 for (it = hosts_.begin(); it != hosts_.end(); it++){
83 GTNETS_Link::GTNETS_Link(){
88 GTNETS_Link::GTNETS_Link(int id):ID_(id), src_node_(0), dst_node_(0){}
91 GTNETS_Link::GTNETS_Link(const GTNETS_Link& link){
93 src_node_ = link.src_node_;
94 dst_node_ = link.dst_node_;
97 GTNETS_Link::~GTNETS_Link(){
101 void GTNETS_Link::print_link_status(){
102 printf("== LINKID: %d\n", ID_);
104 printf(" [SRC] ID: %d, router?: %d, hosts[]: ",
105 src_node_->id(), src_node_->is_router());
106 src_node_->print_hosts();
111 printf(" [DST] ID: %d, router?: %d, hosts[]: ",
112 dst_node_->id(), dst_node_->is_router());
113 dst_node_->print_hosts();
118 GTNETS_Node* GTNETS_Link::src_node(){
122 GTNETS_Node* GTNETS_Link::dst_node(){
126 bool GTNETS_Link::route_exists(){
127 if (src_node_ && dst_node_) return true;
131 // return the peer node id
132 int GTNETS_Link::peer_node(int cur_id){
133 if (cur_id == src_node_->id()) return dst_node_->id();
134 else if (cur_id == dst_node_->id()) return src_node_->id();
136 fprintf(stderr, "node not found\n");
141 int GTNETS_Link::add_src(GTNETS_Node* src){
145 int GTNETS_Link::add_dst(GTNETS_Node* dst){
155 GTNETS_Topology::GTNETS_Topology(){
160 GTNETS_Topology::~GTNETS_Topology(){
161 map<int, GTNETS_Link*>::iterator it1;
162 for (it1 = links_.begin(); it1 != links_.end(); it1++){
165 vector<GTNETS_Node*>::iterator it2;
166 for (it2 = nodes_.begin(); it2 != nodes_.end(); it2++){
172 int GTNETS_Topology::link_size(){
173 return links_.size();
176 int GTNETS_Topology::node_size(){
177 return nodes_.size();
180 int GTNETS_Topology::add_link(int id){
181 map<int,GTNETS_Link*>::iterator iter = links_.find(id);
183 if(iter == links_.end()) {
184 GTNETS_Link* link= new GTNETS_Link(id);
185 //printf("link %d is added: %d\n", id, link->id());
186 //links_.insert(make_pair(id, link));
190 fprintf(stderr, "Link %d already exists.\n", id);
195 int GTNETS_Topology::add_router(int id){
196 set<int>::iterator iter = routers_.find(id);
198 if(iter == routers_.end()) {
199 //printf("router %d is inserted\n", id);
203 fprintf(stderr, "Router %d already exists.\n", id);
208 bool GTNETS_Topology::is_router(int id){
209 set<int>::iterator iter = routers_.find(id);
210 if(iter == routers_.end()) return false;
214 //return the node id of the peer of cur_id by linkid.
215 int GTNETS_Topology::peer_node_id(int linkid, int cur_id){
216 //printf("linkid: %d, cur_id: %d\n", linkid, cur_id);
217 GTNETS_Link* link = links_[linkid];
219 fprintf(stderr, "link %d not found\n", linkid);
222 if ((cur_id < 0) || (cur_id > nodes_.size()-1)){
223 fprintf(stderr, "node %d not found\n", cur_id);
226 int peer = link->peer_node(nodes_[cur_id]->id());
228 fprintf(stderr, "peer not found\n");
234 int GTNETS_Topology::add_onehop_route(int src, int dst, int linkid){
237 map<int, GTNETS_Link*>::iterator iter = links_.find(linkid);
239 if(iter == links_.end()) {
240 fprintf(stderr, "Link %d not found.\n", linkid);
246 // printf("add_onehop_route: src: %d, dst: %d, linkid: %d, %d\n",
247 // src, dst, linkid, link->id());
249 GTNETS_Node *src_node, *dst_node;
250 src_node = link->src_node();
251 dst_node = link->dst_node();
254 // If not exists a route, add one.
255 if (!link->route_exists()){
256 //check whether there exists a node for the src host/router.
257 int s_node_id = nodeid_from_hostid(src);
260 if (s_node_id < 0){//not exist, create one.
262 GTNETS_Node* node1 = new GTNETS_Node(s_node_id);
263 nodes_.push_back(node1);
264 hosts_[src] = nodes_[s_node_id]->id();
270 nodes_[s_node_id]->add_router(src);
272 nodes_[s_node_id]->add_host(src);
274 link->add_src(nodes_[s_node_id]);
276 //check whether there exists a node for the dst host/router.
277 int d_node_id = nodeid_from_hostid(dst);
278 if (d_node_id < 0){//not exist, create one.
280 GTNETS_Node* node2 = new GTNETS_Node(d_node_id);
281 nodes_.push_back(node2);
282 hosts_[dst] = nodes_[d_node_id]->id();
287 nodes_[d_node_id]->add_router(dst);
289 nodes_[d_node_id]->add_host(dst);
291 link->add_dst(nodes_[d_node_id]);
293 // other: has either src or dst (error)
294 }else if (!src_node || !dst_node){
295 fprintf(stderr, "Either src or dst is null\n");
299 // case 1: link has two routers
300 else if (src_node->is_router() && dst_node->is_router()){
301 int tmpsrc1 = src_node->id();
302 int tmpsrc2 = nodeid_from_hostid(src);
303 int tmpdst1 = dst_node->id();
304 int tmpdst2 = nodeid_from_hostid(dst);
305 if (((tmpsrc1 == tmpsrc2) && (tmpdst1 == tmpdst2)) ||
306 ((tmpsrc1 == tmpdst2) && (tmpdst1 == tmpsrc2))){
307 //fprintf(stderr, "Route already exists\n");
309 fprintf(stderr, "Different one hop route defined\n");
313 // case 2: link has one router and one host
314 else if (src_node->is_router() && !dst_node->is_router()){
319 }else if (is_router(dst)){
323 fprintf(stderr, "one of nodes should be a router\n");
327 if (src_node->id() != nodeid_from_hostid(newsrc)){
328 fprintf(stderr, "The router should be identical\n");
332 //now, to add dst to dst_node, dst should be a host.
334 if (is_router(newdst)){
335 fprintf(stderr, "dst %d is not an endpoint. cannot add it to dst_node\n");
339 if (!dst_node->include(newdst)){
340 dst_node->add_host(newdst);
341 hosts_[newdst] = dst_node->id();
344 else if (!src_node->is_router() && dst_node->is_router()){
349 }else if (is_router(dst)){
353 fprintf(stderr, "one of nodes should be a router\n");
358 if (dst_node->id() != hosts_[newdst]){
359 fprintf(stderr, "The router should be identical\n");
363 //now, to add dst to src_node, dst should be a host.
365 if (is_router(newsrc)){
366 fprintf(stderr, "dst %d is not an endpoint. cannot add it to src_node\n");
370 if (!src_node->include(newsrc)){
371 src_node->add_host(newsrc);
372 hosts_[newsrc] = src_node->id();
376 // case 3: link has two hosts
377 else if (!src_node->is_router() && !dst_node->is_router()){
379 if (is_router(src) || is_router(dst)){
380 fprintf(stderr, "Cannot add a router to host-host link\n");
384 //if both are hosts, the order doesn't matter.
385 if (src_node->include(src)){
386 if (dst_node->include(dst)){
389 dst_node->add_host(dst);
390 hosts_[dst] = dst_node->id();
392 }else if (src_node->include(dst)){
393 if (dst_node->include(src)){
396 dst_node->add_host(src);
397 hosts_[src] = dst_node->id();
399 }else if (dst_node->include(src)){
400 if (src_node->include(dst)){
403 src_node->add_host(dst);
404 hosts_[dst] = src_node->id();
406 }else if (dst_node->include(dst)){
407 if (src_node->include(src)){
410 src_node->add_host(src);
411 hosts_[src] = src_node->id();
414 src_node->add_host(src);
415 dst_node->add_host(dst);
416 hosts_[src] = src_node->id();
417 hosts_[dst] = dst_node->id();
422 fprintf(stderr, "Shouldn't be here\n");
428 int GTNETS_Topology::nodeid_from_hostid(int hostid){
429 map<int,int>::iterator it = hosts_.find(hostid);
430 if (it == hosts_.end())
432 else return it->second;
435 void GTNETS_Topology::print_topology(){
436 printf("<<<<<================================>>>>>\n");
437 printf("Dumping GTNETS topollogy information\n");
438 map<int, GTNETS_Link*>::iterator it;
439 for (it = links_.begin(); it != links_.end(); it++){
440 it->second->print_link_status();
442 printf(">>>>>================================<<<<<\n");
446 const vector<GTNETS_Node*>& GTNETS_Topology::nodes(){
450 const map<int, GTNETS_Link*>& GTNETS_Topology::links(){