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"
16 #include "xbt/asserts.h"
18 XBT_LOG_NEW_DEFAULT_SUBCATEGORY(surf_network_gtnets_topology, surf_network_gtnets,
19 "Logging specific to the SURF network GTNetS simulator");
26 GTNETS_Node::GTNETS_Node(int id):ID_(id),is_router_(false){}
28 GTNETS_Node::GTNETS_Node(const GTNETS_Node& node){
30 is_router_ = node.is_router_;
34 GTNETS_Node::~GTNETS_Node(){
38 // hostid = network_card_id
39 int GTNETS_Node::add_host(int hostid){
40 xbt_assert0(!(is_router_), "Cannot add a host to a router node");
41 hosts_.insert(hostid);
45 // Add a router. If this node already has a router/host,
47 int GTNETS_Node::add_router(int routerid){
48 xbt_assert0(!(hosts_.size() > 1), "Router node should have only one router");
49 if (hosts_.size() == 1){
50 xbt_assert1((hosts_.find(routerid) != hosts_.end()), "Node %d is a different router", routerid);
54 hosts_.insert(routerid);
58 bool GTNETS_Node::is_router(){
62 bool GTNETS_Node::include(int hostid){
63 if (hosts_.find(hostid) == hosts_.end()) return false;
67 void GTNETS_Node::print_hosts(){
68 set<int>::iterator it;
69 for (it = hosts_.begin(); it != hosts_.end(); it++){
70 DEBUG1("host id %d", *it);
79 GTNETS_Link::GTNETS_Link(){
84 GTNETS_Link::GTNETS_Link(int id):ID_(id), src_node_(0), dst_node_(0){}
87 GTNETS_Link::GTNETS_Link(const GTNETS_Link& link){
89 src_node_ = link.src_node_;
90 dst_node_ = link.dst_node_;
93 GTNETS_Link::~GTNETS_Link(){
97 void GTNETS_Link::print_link_status(){
98 DEBUG1("link id: %d", ID_);
100 DEBUG2("[src] id: %d, is it router?: %d, host list: ",src_node_->id(), src_node_->is_router());
101 src_node_->print_hosts();
105 DEBUG2("[dst] id: %d, is it router?: %d, host list: ",dst_node_->id(), dst_node_->is_router());
106 dst_node_->print_hosts();
110 GTNETS_Node* GTNETS_Link::src_node(){
114 GTNETS_Node* GTNETS_Link::dst_node(){
118 bool GTNETS_Link::route_exists(){
119 if (src_node_ && dst_node_) return true;
123 // return the peer node id
124 int GTNETS_Link::peer_node(int cur_id){
125 xbt_assert0(((cur_id == src_node_->id())||(cur_id == dst_node_->id())), "Node not found");
127 if (cur_id == src_node_->id()) return dst_node_->id();
128 else if (cur_id == dst_node_->id()) return src_node_->id();
131 int GTNETS_Link::add_src(GTNETS_Node* src){
135 int GTNETS_Link::add_dst(GTNETS_Node* dst){
145 GTNETS_Topology::GTNETS_Topology(){
150 GTNETS_Topology::~GTNETS_Topology(){
151 map<int, GTNETS_Link*>::iterator it1;
152 for (it1 = links_.begin(); it1 != links_.end(); it1++){
155 vector<GTNETS_Node*>::iterator it2;
156 for (it2 = nodes_.begin(); it2 != nodes_.end(); it2++){
162 int GTNETS_Topology::link_size(){
163 return links_.size();
166 int GTNETS_Topology::node_size(){
167 return nodes_.size();
170 int GTNETS_Topology::add_link(int id){
171 map<int,GTNETS_Link*>::iterator iter = links_.find(id);
172 xbt_assert1((iter == links_.end()), "Link %d already exists", id);
174 if(iter == links_.end()) {
175 GTNETS_Link* link= new GTNETS_Link(id);
181 int GTNETS_Topology::add_router(int id){
182 set<int>::iterator iter = routers_.find(id);
183 if(iter == routers_.end()){
186 DEBUG1("Router (#%d) already exists", id);
191 bool GTNETS_Topology::is_router(int id){
192 set<int>::iterator iter = routers_.find(id);
193 if(iter == routers_.end()) return false;
197 //return the node id of the peer of cur_id by linkid.
198 int GTNETS_Topology::peer_node_id(int linkid, int cur_id){
199 GTNETS_Link* link = links_[linkid];
200 xbt_assert1((link), "Link %d not found", linkid);
201 xbt_assert1(!((cur_id < 0) || (cur_id > nodes_.size()-1)), "Node %d not found", cur_id);
203 int peer = link->peer_node(nodes_[cur_id]->id());
204 xbt_assert0(!(peer < 0), "Peer not found");
209 int GTNETS_Topology::add_onehop_route(int src, int dst, int linkid){
212 map<int, GTNETS_Link*>::iterator iter = links_.find(linkid);
214 xbt_assert1(!(iter == links_.end()), "Link %d not found", linkid);
217 DEBUG4("Add onehop route, src: %d, dst: %d, linkid: %d, %d",src, dst, linkid, link->id());
219 GTNETS_Node *src_node, *dst_node;
220 src_node = link->src_node();
221 dst_node = link->dst_node();
223 // If not exists a route, add one.
224 if (!link->route_exists()){
225 //check whether there exists a node for the src.
226 int s_node_id = nodeid_from_hostid(src);
229 if (s_node_id < 0){//not exist, create one.
231 GTNETS_Node* node1 = new GTNETS_Node(s_node_id);
232 nodes_.push_back(node1);
233 hosts_[src] = nodes_[s_node_id]->id();
239 nodes_[s_node_id]->add_router(src);
241 nodes_[s_node_id]->add_host(src);
243 link->add_src(nodes_[s_node_id]);
245 //check whether there exists a node for the dst host/router.
246 int d_node_id = nodeid_from_hostid(dst);
247 if (d_node_id < 0){//not exist, create one.
249 GTNETS_Node* node2 = new GTNETS_Node(d_node_id);
250 nodes_.push_back(node2);
251 hosts_[dst] = nodes_[d_node_id]->id();
256 nodes_[d_node_id]->add_router(dst);
258 nodes_[d_node_id]->add_host(dst);
260 link->add_dst(nodes_[d_node_id]);
261 }else if (!(src_node && dst_node)){
262 xbt_assert0((src_node && dst_node), "Either src or dst is null");
265 // case 1: link has two routers
266 else if (src_node->is_router() && dst_node->is_router()){
267 int tmpsrc1 = src_node->id();
268 int tmpsrc2 = nodeid_from_hostid(src);
269 int tmpdst1 = dst_node->id();
270 int tmpdst2 = nodeid_from_hostid(dst);
271 xbt_assert0( (((tmpsrc1 == tmpsrc2) && (tmpdst1 == tmpdst2)) ||
272 ((tmpsrc1 == tmpdst2) && (tmpdst1 == tmpsrc2))), "Different one hop route defined");
275 // case 2: link has one router and one host
276 else if (src_node->is_router() && !dst_node->is_router()){
278 xbt_assert0( ((is_router(src))||(is_router(dst))), "One of nodes should be a router");
283 }else if (is_router(dst)){
288 xbt_assert0(!(src_node->id() != nodeid_from_hostid(newsrc)), "The router should be identical");
290 //now, to add dst to dst_node, dst should be a host.
291 xbt_assert1(!(is_router(newdst)), "Dst %d is not an endpoint. cannot add it to dst_node", newdst);
293 if (!dst_node->include(newdst)){
294 dst_node->add_host(newdst);
295 hosts_[newdst] = dst_node->id();
298 else if (!src_node->is_router() && dst_node->is_router()){
300 xbt_assert0(((is_router(src))||(is_router(dst))), "One of nodes should be a router");
305 }else if (is_router(dst)){
310 xbt_assert0(!(dst_node->id() != hosts_[newdst]), "The router should be identical");
311 //now, to add dst to src_node, dst should be a host.
312 xbt_assert1(!(is_router(newsrc)), "Src %d is not an endpoint. cannot add it to src_node", newsrc);
314 if (!src_node->include(newsrc)){
315 src_node->add_host(newsrc);
316 hosts_[newsrc] = src_node->id();
320 // case 3: link has two hosts
321 else if (!src_node->is_router() && !dst_node->is_router()){
322 xbt_assert0(!(is_router(src) || is_router(dst)), "Cannot add a router to host-host link");
324 //if both are hosts, the order doesn't matter.
325 if (src_node->include(src)){
326 if (dst_node->include(dst)){
329 dst_node->add_host(dst);
330 hosts_[dst] = dst_node->id();
332 }else if (src_node->include(dst)){
333 if (dst_node->include(src)){
336 dst_node->add_host(src);
337 hosts_[src] = dst_node->id();
339 }else if (dst_node->include(src)){
340 if (src_node->include(dst)){
343 src_node->add_host(dst);
344 hosts_[dst] = src_node->id();
346 }else if (dst_node->include(dst)){
347 if (src_node->include(src)){
350 src_node->add_host(src);
351 hosts_[src] = src_node->id();
354 src_node->add_host(src);
355 dst_node->add_host(dst);
356 hosts_[src] = src_node->id();
357 hosts_[dst] = dst_node->id();
362 xbt_assert0(0, "Shouldn't be here");
365 if (XBT_LOG_ISENABLED(surf_network_gtnets_topology, xbt_log_priority_debug)) {
366 link->print_link_status();
367 src_node->print_hosts();
368 dst_node->print_hosts();
374 int GTNETS_Topology::nodeid_from_hostid(int hostid){
375 map<int,int>::iterator it = hosts_.find(hostid);
376 if (it == hosts_.end())
378 else return it->second;
381 void GTNETS_Topology::print_topology(){
382 DEBUG0("<<<<<================================>>>>>");
383 DEBUG0("Dumping GTNETS topollogy information");
384 map<int, GTNETS_Link*>::iterator it;
385 for (it = links_.begin(); it != links_.end(); it++){
386 it->second->print_link_status();
388 DEBUG0(">>>>>================================<<<<<");
392 const vector<GTNETS_Node*>& GTNETS_Topology::nodes(){
396 const map<int, GTNETS_Link*>& GTNETS_Topology::links(){