Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Merge branch 'master' into vmtrace
[simgrid.git] / src / surf / gtnets / gtnets_topology.cc
1 /* Copyright (c) 2007 Kayo Fujiwara. All rights reserved.                  */
2
3 /* This program is free software; you can redistribute it and/or modify it
4  * under the terms of the license (GNU LGPL) which comes with this package. */
5
6 //GTNETS_Link, GTNETS_Node, GTNETS_Topology: 
7 //Temporary classes for generating GTNetS topology
8
9 #include "gtnets_topology.h"
10 #ifdef XBT_DEBUG
11         #undef XBT_DEBUG
12 #endif
13 #include "xbt/log.h"
14 #include "xbt/asserts.h"
15 #include <stdio.h> //for fflush in print_topology
16
17 XBT_LOG_NEW_DEFAULT_SUBCATEGORY(surf_network_gtnets_topology, surf_network_gtnets,
18                                 "Logging specific to the SURF network GTNetS simulator");
19
20 // 
21 //  GTNETS_Node
22 // 
23
24 // Constructor
25 GTNETS_Node::GTNETS_Node(int id):ID_(id),is_router_(false){}
26 // Copy constructor
27 GTNETS_Node::GTNETS_Node(const GTNETS_Node& node){
28   ID_ = node.ID_;
29   is_router_ = node.is_router_;
30   hosts_ = node.hosts_;
31 }
32
33 GTNETS_Node::~GTNETS_Node(){
34
35 }
36
37 // hostid = network_card_id
38 int GTNETS_Node::add_host(int hostid){
39   xbt_assert(!(is_router_), "Cannot add a host to a router node");
40   hosts_.insert(hostid);
41   return 0;
42 }
43
44 // Add a router. If this node already has a router/host,
45 // return -1.
46 int GTNETS_Node::add_router(int routerid){
47   xbt_assert(!(hosts_.size() > 1), "Router node should have only one router");
48   if (hosts_.size() == 1){
49           xbt_assert((hosts_.find(routerid) != hosts_.end()), "Node %d is a different router", routerid);
50           return 0;
51   }
52   is_router_ = true;
53   hosts_.insert(routerid);
54   return 0;
55 }
56
57 bool GTNETS_Node::is_router(){
58   return is_router_;
59 }
60
61 bool GTNETS_Node::include(int hostid){
62   if (hosts_.find(hostid) == hosts_.end()) return false;
63   else return true;
64 }
65
66 void GTNETS_Node::print_hosts(){
67   set<int>::iterator it;
68   for (it = hosts_.begin(); it != hosts_.end(); it++){
69     XBT_DEBUG("host id %d", *it);
70   }
71 }
72
73 //
74 //  GTNETS_Link
75 //
76
77 // Constructor
78 GTNETS_Link::GTNETS_Link(){
79   ID_=-1;
80   src_node_ = 0;
81   dst_node_ = 0;
82 }
83 GTNETS_Link::GTNETS_Link(int id):ID_(id), src_node_(0), dst_node_(0){}
84
85 // Copy constructor
86 GTNETS_Link::GTNETS_Link(const GTNETS_Link& link){
87   ID_ = link.ID_;
88   src_node_ = link.src_node_;
89   dst_node_ = link.dst_node_;
90 }
91
92 GTNETS_Link::~GTNETS_Link(){
93   
94 }
95
96 void GTNETS_Link::print_link_status(){
97   XBT_DEBUG("****** link id: %d", ID_);
98   if (src_node_){
99     XBT_DEBUG("[src] id: %d, is it router?: %d",src_node_->id(), src_node_->is_router());
100   }
101
102   if (dst_node_){
103     XBT_DEBUG("[dst] id: %d, is it router?: %d",dst_node_->id(), dst_node_->is_router());
104   }
105 }
106
107 GTNETS_Node* GTNETS_Link::src_node(){
108   return src_node_;
109 }
110
111 GTNETS_Node* GTNETS_Link::dst_node(){
112   return dst_node_;
113 }
114
115 bool GTNETS_Link::route_exists(){
116   if (src_node_ && dst_node_) return true;
117   else return false;
118 }
119
120 // return the peer node id
121 int GTNETS_Link::peer_node(int cur_id){
122   xbt_assert(((cur_id ==  src_node_->id())||(cur_id == dst_node_->id())), "Node not found");
123
124   if (cur_id ==  src_node_->id()) return dst_node_->id();
125   else if (cur_id == dst_node_->id()) return src_node_->id();
126 }
127
128 int GTNETS_Link::add_src(GTNETS_Node* src){
129   src_node_ = src;
130 }
131
132 int GTNETS_Link::add_dst(GTNETS_Node* dst){
133   dst_node_ = dst;
134 }
135
136
137 //
138 //  GTNETS_Topology
139 //
140
141 // Constructor
142 GTNETS_Topology::GTNETS_Topology(){
143   nodeID_ = 0;
144 }
145
146 // Destructor
147 GTNETS_Topology::~GTNETS_Topology(){
148   map<int, GTNETS_Link*>::iterator it1;
149   for (it1 = links_.begin(); it1 != links_.end(); it1++){
150     delete it1->second;
151   }
152   vector<GTNETS_Node*>::iterator it2;
153   for (it2 = nodes_.begin(); it2 != nodes_.end(); it2++){
154     delete *it2;
155   }
156 }
157
158
159 int GTNETS_Topology::link_size(){
160   return links_.size();
161 }
162
163 int GTNETS_Topology::node_size(){
164   return nodes_.size();
165 }
166
167 int GTNETS_Topology::add_link(int id){
168   map<int,GTNETS_Link*>::iterator iter = links_.find(id);
169   xbt_assert((iter == links_.end()), "Link %d already exists", id);
170
171   if(iter == links_.end()) {
172     GTNETS_Link* link= new GTNETS_Link(id);
173     links_[id] = link;
174   }
175   return 0;
176 }
177
178 int GTNETS_Topology::add_router(int id){
179   set<int>::iterator iter = routers_.find(id);
180   if(iter == routers_.end()){
181           routers_.insert(id);
182   }else{
183           XBT_DEBUG("Router (#%d) already exists", id);
184   }
185   return 0;
186 }
187
188 bool GTNETS_Topology::is_router(int id){
189   set<int>::iterator iter = routers_.find(id);
190   if(iter == routers_.end()) return false;
191   else return true;
192 }
193
194 //return the node id of the peer of cur_id by linkid.
195 int GTNETS_Topology::peer_node_id(int linkid, int cur_id){
196   GTNETS_Link* link = links_[linkid];
197   xbt_assert((link), "Link %d not found", linkid);
198   xbt_assert(!((cur_id < 0) || (cur_id > nodes_.size()-1)), "Node %d not found", cur_id);
199
200   int peer  = link->peer_node(nodes_[cur_id]->id());
201   xbt_assert(!(peer < 0), "Peer not found");
202
203   return peer;
204 }
205
206 int GTNETS_Topology::add_onehop_route(int src, int dst, int linkid){
207   GTNETS_Link* link;
208
209   map<int, GTNETS_Link*>::iterator iter = links_.find(linkid);
210
211   xbt_assert(!(iter == links_.end()), "Link %d not found", linkid);
212   link = iter->second;
213
214   XBT_DEBUG("Add onehop route, src (#%d), dst (#%d), linkid %d:(#%d)",src, dst, linkid, link->id());
215
216   GTNETS_Node *src_node, *dst_node;
217   src_node = link->src_node();
218   dst_node = link->dst_node();
219
220   // If not exists a route, add one.
221   if (!link->route_exists()){
222     //check whether there exists a node for the src.
223     int s_node_id = nodeid_from_hostid(src);
224     int node_id;
225
226     if (s_node_id < 0){//not exist, create one.
227       s_node_id = nodeID_;
228       GTNETS_Node* node1 = new GTNETS_Node(s_node_id);
229       nodes_.push_back(node1);
230       hosts_[src] = nodes_[s_node_id]->id();
231
232       nodeID_++;
233     }
234
235     if (is_router(src))
236       nodes_[s_node_id]->add_router(src);
237     else
238       nodes_[s_node_id]->add_host(src);
239
240     link->add_src(nodes_[s_node_id]);
241
242     //check whether there exists a node for the dst host/router.
243     int d_node_id = nodeid_from_hostid(dst);
244     if (d_node_id < 0){//not exist, create one.
245       d_node_id = nodeID_;
246       GTNETS_Node* node2 = new GTNETS_Node(d_node_id);
247       nodes_.push_back(node2);
248       hosts_[dst] = nodes_[d_node_id]->id();
249       nodeID_++;
250     }
251
252     if (is_router(dst))
253       nodes_[d_node_id]->add_router(dst);
254     else
255       nodes_[d_node_id]->add_host(dst);
256
257     link->add_dst(nodes_[d_node_id]);
258   }else if (!(src_node && dst_node)){
259       xbt_assert((src_node && dst_node), "Either src or dst is null");
260   }
261
262   // case 1: link has two routers
263   else if (src_node->is_router() && dst_node->is_router()){
264     int tmpsrc1 = src_node->id();
265     int tmpsrc2 = nodeid_from_hostid(src);
266     int tmpdst1 = dst_node->id();
267     int tmpdst2 = nodeid_from_hostid(dst);
268     xbt_assert( (((tmpsrc1 == tmpsrc2) && (tmpdst1 == tmpdst2)) ||
269         ((tmpsrc1 == tmpdst2) && (tmpdst1 == tmpsrc2))), "Different one hop route defined");
270   }
271
272   // case 2: link has one router and one host
273   else if (src_node->is_router() && !dst_node->is_router()){
274     int newsrc, newdst;
275     xbt_assert( ((is_router(src))||(is_router(dst))), "One of nodes should be a router");
276
277     if (is_router(src)){
278       newsrc = src;
279       newdst = dst;
280     }else if (is_router(dst)){
281       newsrc = dst;
282       newdst = src;
283     }
284
285     xbt_assert(!(src_node->id() != nodeid_from_hostid(newsrc)), "The router should be identical");
286
287     //now, to add dst to dst_node, dst should be a host.
288     xbt_assert(!(is_router(newdst)), "Dst %d is not an endpoint. cannot add it to dst_node", newdst);
289
290     if (!dst_node->include(newdst)){
291       dst_node->add_host(newdst);
292       hosts_[newdst] = dst_node->id();
293     }
294   }
295   else if (!src_node->is_router() && dst_node->is_router()){
296     int newsrc, newdst;
297     xbt_assert(((is_router(src))||(is_router(dst))), "One of nodes should be a router");
298
299     if (is_router(src)){
300       newsrc = dst;
301       newdst = src;
302     }else if (is_router(dst)){
303       newsrc = src;
304       newdst = dst;
305     }
306
307     xbt_assert(!(dst_node->id() != hosts_[newdst]), "The router should be identical");
308     //now, to add dst to src_node, dst should be a host.
309     xbt_assert(!(is_router(newsrc)), "Src %d is not an endpoint. cannot add it to src_node", newsrc);
310
311     if (!src_node->include(newsrc)){
312       src_node->add_host(newsrc);
313       hosts_[newsrc] = src_node->id();
314     }
315   }
316
317   // case 3: link has two hosts
318   else if (!src_node->is_router() && !dst_node->is_router()){
319         xbt_assert(!(is_router(src) || is_router(dst)), "Cannot add a router to host-host link");
320
321     //if both are hosts, the order doesn't matter.
322     if (src_node->include(src)){
323       if (dst_node->include(dst)){
324             //nothing
325       }else{
326             dst_node->add_host(dst);
327             hosts_[dst] = dst_node->id();
328       }
329     }else if (src_node->include(dst)){
330       if (dst_node->include(src)){
331             //nothing
332       }else{
333             dst_node->add_host(src);
334             hosts_[src] = dst_node->id();
335       }
336     }else if (dst_node->include(src)){
337       if (src_node->include(dst)){
338             //nothing
339       }else{
340             src_node->add_host(dst);
341             hosts_[dst] = src_node->id();
342       }
343     }else if (dst_node->include(dst)){
344       if (src_node->include(src)){
345             //nothing
346       }else{
347             src_node->add_host(src);
348             hosts_[src] = src_node->id();
349       }
350     }else{
351       src_node->add_host(src);
352       dst_node->add_host(dst);
353       hosts_[src] = src_node->id();
354       hosts_[dst] = dst_node->id();
355     }   
356       
357   }
358   else{
359     xbt_die("Shouldn't be here");
360   }
361
362   return 0;
363 }
364
365 int GTNETS_Topology::nodeid_from_hostid(int hostid){
366   map<int,int>::iterator it = hosts_.find(hostid);
367   if (it == hosts_.end())
368     return -1;
369   else return it->second;
370 }
371
372 void GTNETS_Topology::print_topology(){
373   XBT_DEBUG("<<<<<================================>>>>>");
374   XBT_DEBUG("Dumping GTNETS topollogy information");
375   map<int, GTNETS_Link*>::iterator it;
376   for (it = links_.begin(); it != links_.end(); it++){
377     it->second->print_link_status();
378   }
379   XBT_DEBUG(">>>>>================================<<<<<");
380   fflush(NULL);
381 }
382
383 const vector<GTNETS_Node*>& GTNETS_Topology::nodes(){
384   return nodes_;
385 }
386
387 const map<int, GTNETS_Link*>& GTNETS_Topology::links(){
388   return links_;
389 }
390