Logo AND Algorithmique Numérique Distribuée

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