Main Page | Namespace List | Class Hierarchy | Alphabetical List | Compound List | File List | Compound Members | File Members

route.cc

Go to the documentation of this file.
00001 /* -*-  Mode:C++; c-basic-offset:8; tab-width:8; indent-tabs-mode:t -*- */
00002 /*
00003  * Copyright (c) 1991-1994 Regents of the University of California.
00004  * All rights reserved.
00005  *
00006  * Redistribution and use in source and binary forms, with or without
00007  * modification, are permitted provided that the following conditions
00008  * are met:
00009  * 1. Redistributions of source code must retain the above copyright
00010  *    notice, this list of conditions and the following disclaimer.
00011  * 2. Redistributions in binary form must reproduce the above copyright
00012  *    notice, this list of conditions and the following disclaimer in the
00013  *    documentation and/or other materials provided with the distribution.
00014  * 3. All advertising materials mentioning features or use of this software
00015  *    must display the following acknowledgement:
00016  *      This product includes software developed by the University of
00017  *      California, Berkeley and the Network Research Group at
00018  *      Lawrence Berkeley Laboratory.
00019  * 4. Neither the name of the University nor of the Laboratory may be used
00020  *    to endorse or promote products derived from this software without
00021  *    specific prior written permission.
00022  *
00023  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
00024  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00025  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00026  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
00027  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00028  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
00029  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00030  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00031  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
00032  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00033  * SUCH DAMAGE.
00034  *
00035  * Routing code for general topologies based on min-cost routing algorithm in
00036  * Bertsekas' book.  Written originally by S. Keshav, 7/18/88
00037  * (his work covered by identical UC Copyright)
00038  */
00039 
00040 #ifndef lint
00041 static const char rcsid[] =
00042 "@(#) $Header: /nfs/jade/vint/CVSROOT/ns-2/routing/route.cc,v 1.38 2001/02/22 19:45:39 haldar Exp $ (LBL)";
00043 #endif
00044 
00045 #include <stdlib.h>
00046 #include <assert.h>
00047 #include "config.h"
00048 #include "route.h"
00049 #include "address.h"
00050 
00051 class RouteLogicClass : public TclClass {
00052 public:
00053         RouteLogicClass() : TclClass("RouteLogic") {}
00054         TclObject* create(int, const char*const*) {
00055                 return (new RouteLogic());
00056         }
00057 } routelogic_class;
00058 
00059 void RouteLogic::reset_all()
00060 {
00061         delete[] adj_;
00062         delete[] route_;
00063         adj_ = 0; 
00064         route_ = 0;
00065         size_ = 0;
00066 }
00067 
00068 int RouteLogic::command(int argc, const char*const* argv)
00069 {
00070         Tcl& tcl = Tcl::instance();
00071         if (argc == 2) {
00072                 if (strcmp(argv[1], "compute") == 0) {
00073                         if (adj_ == 0)
00074                                 return (TCL_OK);
00075                         compute_routes();
00076                         return (TCL_OK);
00077                 } else if (strcmp(argv[1], "hier-compute") == 0) {
00078                         if (hadj_ == 0) {
00079                                 return (TCL_OK);
00080                         }
00081                         hier_compute();
00082                         return (TCL_OK);
00083                 } else if (strcmp(argv[1], "hier-print") == 0) {
00084                         hier_print_hadj();
00085                         return (TCL_OK);
00086                 } else if (strcmp(argv[1], "hier-print-route") == 0) {
00087                         hier_print_route();
00088                         return (TCL_OK);
00089                 } else if (strcmp(argv[1], "reset") == 0) {
00090                         reset_all();
00091                         return (TCL_OK);
00092                 }
00093         } else if (argc > 2) {
00094                 if (strcmp(argv[1], "insert") == 0) {
00095                         int src = atoi(argv[2]) + 1;
00096                         int dst = atoi(argv[3]) + 1;
00097                         if (src <= 0 || dst <= 0) {
00098                                 tcl.result("negative node number");
00099                                 return (TCL_ERROR);
00100                         }
00101                         double cost = (argc == 5 ? atof(argv[4]) : 1);
00102                         insert(src, dst, cost);
00103                         return (TCL_OK);
00104                 } else if (strcmp(argv[1], "hlevel-is") == 0) {
00105                         level_ = atoi(argv[2]);
00106                         if (level_ < 1) {
00107                                 tcl.result("send-hlevel: # hierarchy levels should be non-zero");
00108                                 return (TCL_ERROR);
00109                         }
00110                         return (TCL_OK);
00111                 } else if (strcmp(argv[1], "send-num-of-domains") == 0) {
00112                         D_ = atoi(argv[2]) + 1;
00113                         if (D_ <= 1) {
00114                                 tcl.result("send-num-of-domains: # domains should be larger than 1");
00115                                 return (TCL_ERROR);
00116                         }
00117                         return (TCL_OK);
00118                 } else if (strcmp(argv[1], "send-num-of-clusters") == 0) {
00119                         if (argc != D_ + 1) {
00120                                 tcl.resultf("send-num-of-clusters: # of "
00121                                             "clusters %d != domain (%d) + 1\n",
00122                                             argc, D_);
00123                                 return (TCL_ERROR);
00124                         }
00125                         C_ = new int[D_];
00126                         int i, j = 2;
00127                         for (i = 1; i < D_; i++) {
00128                                 C_[i] = atoi(argv[j]) + 1;
00129                                 j++;
00130                         }
00131                         hier_init();
00132                         return (TCL_OK);
00133                 } else if(strcmp(argv[1], "send-num-of-nodes") == 0) {
00134                         int i, j, k=2, Ctotal=0 ;
00135                         for (i=1; i < D_; i++)
00136                                 Ctotal = Ctotal + (C_[i]-1);
00137                         if (argc != (Ctotal + 2)) {
00138                                 tcl.result("send-hlastdata: # args do not match");
00139                                 return (TCL_ERROR);
00140                         }
00141                         for (i=1; i < D_; i++)
00142                                 for (j=1; (j < C_[i]); j++) {
00143                                         cluster_size_[INDEX(i, j, Cmax_)] = atoi(argv[k]);
00144                                         k++;
00145                                 }
00146                         return (TCL_OK);
00147                 } else if (strcmp(argv[1], "hier-insert") == 0) {
00148                         if(Cmax_== 0 || D_== 0) {
00149                                 tcl.result("Required Hier_data not sent");
00150                                 return (TCL_ERROR);
00151                         }
00152                         int i;
00153                         int src_addr[SMALL_LEN], dst_addr[SMALL_LEN];
00154                         str2address(argv, src_addr, dst_addr);
00155                         for (i=0; i < level_; i++)
00156                                 if (src_addr[i]<=0 || dst_addr[i]<=0){
00157                                         tcl.result ("negative node number");
00158                                         return (TCL_ERROR);
00159                                 }
00160                         int cost = (argc == 5 ? atoi(argv[4]) : 1);
00161                         hier_insert(src_addr, dst_addr, cost);
00162                         return (TCL_OK);
00163                 } else if (strcmp(argv[1], "hier-reset") == 0) {
00164                         int i;
00165                         int  src_addr[SMALL_LEN], dst_addr[SMALL_LEN];
00166                         
00167                         str2address(argv, src_addr, dst_addr);
00168                         // assuming node-node addresses (instead of 
00169                         // node-cluster or node-domain pair) 
00170                         // are sent for hier_reset  
00171                         for (i=0; i < level_; i++)
00172                                 if (src_addr[i]<=0 || dst_addr[i]<=0){
00173                                         tcl.result ("negative node number");
00174                                         return (TCL_ERROR);
00175                                 }
00176                         hier_reset(src_addr, dst_addr);
00177                 } else if (strcmp(argv[1], "hier-lookup") == 0) {
00178                         int nh;
00179                         int res = lookup_hier((char*)argv[2], (char*)argv[3],
00180                                               nh);
00181                         return res;
00182                 } else if (strcmp(argv[1], "reset") == 0) {
00183                         int src = atoi(argv[2]) + 1;
00184                         int dst = atoi(argv[3]) + 1;
00185                         if (src <= 0 || dst <= 0) {
00186                                 tcl.result("negative node number");
00187                                 return (TCL_ERROR);
00188                         }
00189                         reset(src, dst);
00190                         return (TCL_OK);
00191                 } else if (strcmp(argv[1], "lookup") == 0) {
00192                         int nh;
00193                         int res = lookup_flat((char*)argv[2], (char*)argv[3], 
00194                                               nh);
00195                         if (res == TCL_OK)
00196                                 tcl.resultf("%d", nh);
00197                         return res;
00198                 }
00199         }
00200         return (TclObject::command(argc, argv));
00201 }
00202 
00203 // xxx: using references as in this result is bogus---use pointers!
00204 int RouteLogic::lookup_flat(char* asrc, char* adst, int& result) {
00205         Tcl& tcl = Tcl::instance();
00206         int src = atoi(asrc) + 1;
00207         int dst = atoi(adst) + 1;
00208 
00209         if (route_ == 0) {
00210                 // routes are computed only after the simulator is running
00211                 // ($ns run).
00212                 tcl.result("routes not yet computed");
00213                 return (TCL_ERROR);
00214         }
00215         if (src >= size_ || dst >= size_) {
00216                 tcl.result("node out of range");
00217                 return (TCL_ERROR);
00218         }
00219         result = route_[INDEX(src, dst, size_)].next_hop - 1;
00220         return TCL_OK;
00221 }
00222 
00223 //added for pushback. a method callable from c++ code. 
00224 //probably could have been concocted from already existing methods - ratul
00225 int RouteLogic::lookup_flat(int sid, int did) {
00226         int src = sid+1;
00227         int dst = did+1;
00228         if (route_ == 0) {
00229                 // routes are computed only after the simulator is running
00230                 // ($ns run).
00231                 printf("routes not yet computed\n");
00232                 return (-1);
00233         }
00234         if (src >= size_ || dst >= size_) {
00235                 printf("node out of range\n");
00236                 return (-2);
00237         }
00238         return route_[INDEX(src, dst, size_)].next_hop - 1;
00239 }
00240 
00241 // xxx: using references as in this result is bogus---use pointers!
00242 int RouteLogic::lookup_hier(char* asrc, char* adst, int& result) {
00243         int i;
00244         int src[SMALL_LEN], dst[SMALL_LEN];
00245         Tcl& tcl = Tcl::instance();
00246 
00247         if ( hroute_ == 0) {
00248                 tcl.result("Required Hier_data not sent");
00249                 return TCL_ERROR;
00250         }
00251       
00252         ns_strtok(asrc, src);
00253         ns_strtok(adst, dst);
00254 
00255         for (i=0; i < level_; i++)
00256                 if (src[i] <= 0) {
00257                         tcl.result("negative src node number");
00258                         return TCL_ERROR;
00259                 }
00260         if (dst[0] <= 0) {
00261                 tcl.result("negative dst domain number");
00262                 return TCL_ERROR;
00263         }
00264 
00265         int d = src[0];
00266         int index = INDEX(src[0], src[1], Cmax_);
00267         int size = cluster_size_[index];
00268 
00269         if (hsize_[index] == 0) {
00270                 tcl.result("Routes not computed");
00271                 return TCL_ERROR;
00272         }
00273         if ((src[0] < D_) || (dst[0] < D_)) {
00274                 if((src[1] < C_[d]) || (dst[1] < C_[dst[0]]))
00275                         if((src[2] <= size) ||
00276                            (dst[2]<=cluster_size_[INDEX(dst[0],dst[1],Cmax_)]))
00277                                 ;
00278         } else { 
00279                 tcl.result("node out of range");
00280                 return TCL_ERROR;
00281         }
00282         int next_hop = 0;
00283         /* if node-domain lookup */
00284         if (((dst[1] <= 0) && (dst[2] <= 0)) ||
00285             (src[0] != dst[0])){
00286                 next_hop = hroute_[index][N_D_INDEX(src[2], dst[0], size, C_[d], D_)];
00287         }
00288         /* if node-cluster lookup */
00289         else if ((dst[2] <= 0) || (src[1] != dst[1])) {
00290                 next_hop = hroute_[index][N_C_INDEX(src[2], dst[1], size, C_[d], D_)];
00291         }
00292         /* if node-node lookup */
00293         else {
00294                 next_hop = hroute_[index][N_N_INDEX(src[2], dst[2], size, C_[d], D_)];  
00295         }
00296         
00297         char target[SMALL_LEN];
00298         if (next_hop > 0) {
00299                 get_address(target, next_hop, index, d, size, src);
00300                 tcl.result(target);
00301                 result= Address::instance().str2addr(target);
00302         } else {
00303                 tcl.result("-1");
00304                 result = -1;
00305         }
00306         return TCL_OK;
00307 }
00308 
00309 RouteLogic::RouteLogic()
00310 {
00311         size_ = 0;
00312         adj_ = 0;
00313         route_ = 0;
00314         /* additions for hierarchical routing extension */
00315         C_ = 0;
00316         D_ = 0;
00317         Cmax_ = 0;
00318         level_ = 0;
00319         hsize_ = 0;
00320         hadj_ = 0;
00321         hroute_ = 0;
00322         hconnect_ = 0;
00323         cluster_size_ = 0;
00324 }
00325         
00326 RouteLogic::~RouteLogic()
00327 {
00328         delete[] adj_;
00329         delete[] route_;
00330 
00331         for (int i = 0; i < (Cmax_ * D_); i++) {
00332                 for (int j = 0; j < (Cmax_ + D_) * (cluster_size_[i]+1); j++) {
00333                         if (hconnect_[i][j] != NULL)
00334                                 delete [] hconnect_[i][j];
00335                 }
00336                 delete [] hconnect_[i];
00337         }
00338 
00339         for (int n =0; n < (Cmax_ * D_); n++) {
00340                 if (hadj_[n] != NULL)
00341                         delete [] hadj_[n];
00342                 if (hroute_[n] != NULL)
00343                         delete [] hroute_[n];
00344         }
00345 
00346         delete [] C_;
00347         delete [] hsize_;
00348         delete [] cluster_size_;
00349         delete hadj_;
00350         delete hroute_;
00351         delete hconnect_;
00352 }
00353 
00354 void RouteLogic::alloc(int n)
00355 {
00356         size_ = n;
00357         n *= n;
00358         adj_ = new adj_entry[n];
00359         for (int i = 0; i < n; ++i) {
00360                 adj_[i].cost = INFINITY;
00361                 adj_[i].entry = 0;
00362         }
00363 }
00364 
00365 /*
00366  * Check that we have enough storage in the adjacency array
00367  * to hold a node numbered "n"
00368  */
00369 void RouteLogic::check(int n)
00370 {
00371         if (n < size_)
00372                 return;
00373 
00374         adj_entry* old = adj_;
00375         int osize = size_;
00376         int m = osize;
00377         if (m == 0)
00378                 m = 16;
00379         while (m <= n)
00380                 m <<= 1;
00381 
00382         alloc(m);
00383         for (int i = 0; i < osize; ++i) {
00384                 for (int j = 0; j < osize; ++j)
00385                         adj_[INDEX(i, j, m)].cost =old[INDEX(i, j, osize)].cost;
00386         }
00387         size_ = m;
00388         delete[] old;
00389 }
00390 
00391 void RouteLogic::insert(int src, int dst, double cost)
00392 {
00393         check(src);
00394         check(dst);
00395         adj_[INDEX(src, dst, size_)].cost = cost;
00396 }
00397 void RouteLogic::insert(int src, int dst, double cost, void* entry_)
00398 {
00399         check(src);
00400         check(dst);
00401         adj_[INDEX(src, dst, size_)].cost = cost;
00402         adj_[INDEX(src, dst, size_)].entry = entry_;
00403 }
00404 
00405 void RouteLogic::reset(int src, int dst)
00406 {
00407         assert(src < size_);
00408         assert(dst < size_);
00409         adj_[INDEX(src, dst, size_)].cost = INFINITY;
00410 }
00411 
00412 void RouteLogic::compute_routes()
00413 {
00414         int n = size_;
00415         int* parent = new int[n];
00416         double* hopcnt = new double[n];
00417 #define ADJ(i, j) adj_[INDEX(i, j, size_)].cost
00418 #define ADJ_ENTRY(i, j) adj_[INDEX(i, j, size_)].entry
00419 #define ROUTE(i, j) route_[INDEX(i, j, size_)].next_hop
00420 #define ROUTE_ENTRY(i, j) route_[INDEX(i, j, size_)].entry
00421         delete[] route_;
00422         route_ = new route_entry[n * n];
00423         memset((char *)route_, 0, n * n * sizeof(route_[0]));
00424 
00425         /* do for all the sources */
00426         int k;
00427         for (k = 1; k < n; ++k) {
00428                 int v;
00429                 for (v = 0; v < n; v++)
00430                         parent[v] = v;
00431         
00432                 /* set the route for all neighbours first */
00433                 for (v = 1; v < n; ++v) {
00434                         if (parent[v] != k) {
00435                                 hopcnt[v] = ADJ(k, v);
00436                                 if (hopcnt[v] != INFINITY) {
00437                                         ROUTE(k, v) = v;
00438                                         ROUTE_ENTRY(k, v) = ADJ_ENTRY(k, v);
00439                                 }
00440                         }
00441                 }
00442                 for (v = 1; v < n; ++v) {
00443                         /*
00444                          * w is the node that is the nearest to the subtree
00445                          * that has been routed
00446                          */
00447                         int o = 0;
00448                         /* XXX */
00449                         hopcnt[0] = INFINITY;
00450                         int w;
00451                         for (w = 1; w < n; w++)
00452                                 if (parent[w] != k && hopcnt[w] < hopcnt[o])
00453                                         o = w;
00454                         parent[o] = k;
00455                         /*
00456                          * update distance counts for the nodes that are
00457                          * adjacent to o
00458                          */
00459                         if (o == 0)
00460                                 continue;
00461                         for (w = 1; w < n; w++) {
00462                                 if (parent[w] != k &&
00463                                     hopcnt[o] + ADJ(o, w) < hopcnt[w]) {
00464                                         ROUTE(k, w) = ROUTE(k, o);
00465                                         ROUTE_ENTRY(k, w) = 
00466                                             ROUTE_ENTRY(k, o);
00467                                         hopcnt[w] = hopcnt[o] + ADJ(o, w);
00468                                 }
00469                         }
00470                 }
00471         }
00472         /*
00473          * The route to yourself is yourself.
00474          */
00475         for (k = 1; k < n; ++k) {
00476                 ROUTE(k, k) = k;
00477                 ROUTE_ENTRY(k, k) = 0; // This should not matter
00478         }
00479 
00480         delete[] hopcnt;
00481         delete[] parent;
00482 }
00483 
00484 /* hierarchical routing support */
00485 
00486 /*
00487  * This function creates adjacency matrix for each cluster at the lowest level
00488  * of the hierarchy for every node in the cluster, for every other cluster in 
00489  * the domain, and every other domain. can be extended from 3-level hierarchy 
00490  * to n-level along similar lines
00491  */
00492 void RouteLogic::hier_alloc(int i)
00493 {
00494         hsize_[i] = cluster_size_[i]+ Cmax_+ D_ ;
00495         hsize_[i] *= hsize_[i];
00496         hadj_[i] = new int[hsize_[i]];
00497         hroute_[i] = new int[hsize_[i]];
00498         hconnect_[i] = new char*[(Cmax_ + D_) * (cluster_size_[i]+1)];
00499         for (int n = 0; n < hsize_[i]; n++){
00500                 hadj_[i][n] = INFINITY;
00501                 hroute_[i][n] = INFINITY;
00502         }
00503 }
00504 
00505 void RouteLogic::hier_check(int i)
00506 {
00507         if(hsize_[i] > 0)
00508                 return;
00509         else
00510                 hier_alloc(i);
00511 }
00512 
00513 void RouteLogic::hier_init(void) 
00514 {
00515         int i;
00516 
00517         for (i = 1; i < D_; i++) {
00518                 Cmax_ = C_[i] > Cmax_ ? C_[i]: Cmax_;
00519         }
00520         int arr_size = Cmax_ * D_ ;
00521         cluster_size_ = new int[arr_size]; 
00522         hsize_ = new int[arr_size];
00523         for (i = 0; i < arr_size; i++)
00524                 hsize_[i] = 0;
00525         hadj_ = new int*[arr_size];
00526         hroute_ = new int*[arr_size];
00527         hconnect_ = new char**[arr_size];
00528 }
00529 
00530 
00531 int RouteLogic::domain_size(int domain) { 
00532         return (C_[domain+1]-1); 
00533 }
00534 int RouteLogic::cluster_size(int d, int c) {
00535         d += 1;
00536         c += 1;
00537         return (cluster_size_[INDEX(d, c, Cmax_)]);
00538 }
00539 
00540 int RouteLogic::elements_in_level(int *addr, int level) {
00541         if (level == 1)
00542                 return (domains());
00543         else if (level == 2)
00544                 return (domain_size(addr[0]));
00545         else if (level == 3) {
00546                 return (cluster_size(addr[0], addr[1]));
00547         }
00548         return (-1);
00549 }
00550 
00551 void RouteLogic::str2address(const char*const* argv, int *src_addr, int *dst_addr)
00552 {
00553         char src[SMALL_LEN];
00554         char dst[SMALL_LEN];
00555 
00556         strcpy(src, argv[2]);
00557         strcpy(dst, argv[3]);
00558 
00559         ns_strtok(src, src_addr);
00560         ns_strtok(dst, dst_addr);
00561 }
00562 
00563 void RouteLogic::ns_strtok(char *addr, int *addrstr)
00564 {
00565         int     i;
00566         char    tmpstr[SMALL_LEN];
00567         char    *next, *index;
00568         
00569         i = 0;
00570         strcpy(tmpstr, addr);
00571         next = tmpstr;
00572         while(*next){
00573                 index = strstr(next, ".");
00574                 if (index != NULL){
00575                         next[index - next] = '\0';
00576                         addrstr[i] = atoi(next) + 1;
00577                         next = index + 1;
00578                         i++;
00579                 }
00580                 else {
00581                         if (*next != '\0') //damn that ending point
00582                                 addrstr[i] = atoi(next) + 1;
00583                         break;
00584                 }
00585         }
00586 }
00587 
00588 
00589 void RouteLogic::get_address(char *address, int next_hop, int index, int d, 
00590                              int size, int *src)
00591 {
00592         if (next_hop <= size) {
00593                 sprintf(address,"%d.%d.%d", src[0]-1, src[1]-1, next_hop-1);
00594         }
00595         else if ((next_hop > size) && (next_hop < (size + C_[d]))) {
00596                 int temp = next_hop - size;
00597                 int I = src[2] * (C_[d] + D_) + temp;
00598                 strcpy(address, hconnect_[index][I]);
00599         }
00600         else {
00601                 int temp = next_hop - size - (C_[d] - 1);
00602                 int I = src[2] * (C_[d] + D_) + (C_[d] - 1 + temp);
00603                 strcpy(address,hconnect_[index][I]);
00604         }
00605 }
00606 
00607 void RouteLogic::hier_reset(int *src, int *dst)
00608 {
00609         int i, d, n;
00610         d = src[0];
00611         if (src[0] == dst[0])
00612                 if (src[1] == dst[1]) {
00613                         i = INDEX(src[0], src[1], Cmax_);
00614                         n = cluster_size_[i];
00615                         hadj_[i][N_N_INDEX(src[2], dst[2], n, C_[d], D_)] = INFINITY;
00616                 } else {
00617                         for (int y=1; y < C_[d]; y++) { 
00618                                 i = INDEX(src[0], y, Cmax_);
00619                                 n = cluster_size_[i];
00620                                 hadj_[i][C_C_INDEX(src[1], dst[1], n, C_[d], D_)] = INFINITY;
00621                                 if (y == src[1])
00622                                         hadj_[i][N_C_INDEX(src[2], dst[1], n, C_[d], D_)] = INFINITY; 
00623                         }
00624                 }
00625         else {
00626                 for (int x=1; x < D_; x++)
00627                         for (int y=1; y < C_[x]; y++) {
00628                                 i = INDEX(x, y, Cmax_);
00629                                 n = cluster_size_[i];
00630                                 hadj_[i][D_D_INDEX(src[0], dst[0], n, C_[x], D_)] = INFINITY;
00631                                 if ( x == src[0] ){
00632                                         hadj_[i][C_D_INDEX(src[1], dst[0], n, C_[x], D_)] = INFINITY;
00633                                         if (y == src[1])
00634                                                 hadj_[i][N_D_INDEX(src[2], dst[0], n, C_[x], D_)] = INFINITY;
00635                                 }
00636                         }
00637         }
00638 }
00639 
00640 void RouteLogic::hier_insert(int *src_addr, int *dst_addr, int cost)
00641 {
00642         int X1 = src_addr[0];
00643         int Y1 = src_addr[1];
00644         int Z1 = src_addr[2];
00645         int X2 = dst_addr[0];
00646         int Y2 = dst_addr[1];
00647         int Z2 = dst_addr[2];
00648         int n, i;
00649 
00650         if ( X1 == X2)
00651                 if (Y1 == Y2){ 
00652                         /*
00653                          * For the same domain & cluster 
00654                          */
00655                         i = INDEX(X1, Y1, Cmax_);
00656                         n = cluster_size_[i];
00657                         hier_check(i);
00658                         hadj_[i][N_N_INDEX(Z1, Z2, n, C_[X1], D_)] = cost;
00659                 } else { 
00660                         /* 
00661                          * For the same domain but diff clusters 
00662                          */
00663                         for (int y=1; y < C_[X1]; y++) { /* insert cluster connectivity */
00664                                 i = INDEX(X1, y, Cmax_);
00665                                 n = cluster_size_[i];
00666                                 hier_check(i);
00667                                 hadj_[i][C_C_INDEX(Y1, Y2, n, C_[X1], D_)] = cost;
00668 
00669                                 if (y == Y1) {  /* insert node conn. */
00670                                         hadj_[i][N_C_INDEX(Z1, Y2, n, C_[X1], D_)] = cost;
00671                                         int I = Z1 * (C_[X1]+ D_) + Y2;
00672                                         hconnect_[i][I] = new char[SMALL_LEN];
00673                                         sprintf(hconnect_[i][I],"%d.%d.%d",X2-1,Y2-1,Z2-1);
00674                                 }
00675                         }
00676                 }
00677         else { 
00678                 /* 
00679                  * For different domains 
00680                  */
00681                 for (int x=1; x < D_; x++) { /* inset domain connectivity */
00682                         for (int y=1; y < C_[x]; y++) {
00683                                 i = INDEX(x, y, Cmax_);
00684                                 n = cluster_size_[i];
00685                                 hier_check(i);
00686                                 hadj_[i][D_D_INDEX(X1, X2, n, C_[x], D_)] = cost;
00687                         }
00688                 }
00689                 for (int y=1; y < C_[X1]; y++) { /* insert cluster connectivity */
00690                         i = INDEX(X1, y, Cmax_);
00691                         n = cluster_size_[i];
00692                         hier_check(i);
00693                         hadj_[i][C_D_INDEX(Y1, X2, n, C_[X1], D_)] = cost;
00694                 }
00695                 /* insert node connectivity */
00696                 i = INDEX(X1, Y1, Cmax_);
00697                 n = cluster_size_[i]; 
00698                 hadj_[i][N_D_INDEX(Z1, X2, n, C_[X1], D_)] = cost;
00699                 int I = Z1 * (C_[X1] + D_) + (C_[X1] - 1 + X2);
00700                 hconnect_[i][I] = new char[SMALL_LEN];
00701                 sprintf(hconnect_[i][I],"%d.%d.%d",X2-1,Y2-1,Z2-1);
00702         }
00703 }
00704 
00705 void RouteLogic::hier_compute_routes(int i, int j)
00706 {
00707         int size = (cluster_size_[i] + C_[j] + D_);
00708         int n = size ;
00709         double* hopcnt = new double[n];
00710 #define HADJ(i, j) adj_[INDEX(i, j, size)].cost
00711 #define HROUTE(i, j) route_[INDEX(i, j, size)].next_hop
00712         delete[] route_;
00713         route_ = new route_entry[n * n];
00714         int* parent = new int[n];
00715         memset((char *)route_, 0, n * n * sizeof(route_[0]));
00716 
00717         /* do for all the sources */
00718         int k;
00719         for (k = 1; k < n; ++k) {
00720                 int v;
00721                 for (v = 0; v < n; v++)
00722                         parent[v] = v;
00723 
00724                 /* set the route for all neighbours first */
00725                 for (v = 1; v < n; ++v) {
00726                         if (parent[v] != k) {
00727                                 hopcnt[v] = HADJ(k, v);
00728                                 if (hopcnt[v] != INFINITY)
00729                                         HROUTE(k, v) = v;
00730                         }
00731                 }
00732                 for (v = 1; v < n; ++v) {
00733                         /*
00734                          * w is the node that is the nearest to the subtree
00735                          * that has been routed
00736                          */
00737                         int o = 0;
00738                         /* XXX */
00739                         hopcnt[0] = INFINITY;
00740                         int w;
00741                         for (w = 1; w < n; w++)
00742                                 if (parent[w] != k && hopcnt[w] < hopcnt[o])
00743                                         o = w;
00744                         parent[o] = k;
00745                         /*
00746                          * update distance counts for the nodes that are
00747                          * adjacent to o
00748                          */
00749                         if (o == 0)
00750                                 continue;
00751                         for (w = 1; w < n; w++) {
00752                                 if (parent[w] != k &&
00753                                     hopcnt[o] + HADJ(o, w) < hopcnt[w]) {
00754                                         HROUTE(k, w) = HROUTE(k, o);
00755                                         hopcnt[w] = hopcnt[o] + HADJ(o, w);
00756                                 }
00757                         }
00758                 }
00759         }
00760         /*
00761          * The route to yourself is yourself.
00762          */
00763         for (k = 1; k < n; ++k)
00764                 HROUTE(k, k) = k;
00765 
00766         delete[] hopcnt;
00767         delete[] parent;
00768 }
00769 
00770 /* function to check the adjacency matrices created */
00771 void RouteLogic::hier_print_hadj() {
00772         int i, j, k;
00773 
00774         for (j=1; j < D_; j++) 
00775                 for (k=1; k < C_[j]; k++) {
00776                         i = INDEX(j, k, Cmax_);
00777                         int s = (cluster_size_[i] + C_[j] + D_);
00778                         printf("ADJ MATRIX[%d] for cluster %d.%d :\n",i,j,k);
00779                         int temp = 1;
00780                         printf(" ");
00781                         while(temp < s){
00782                                 printf(" %d",temp);
00783                                 temp++;
00784                         }
00785                         printf("\n");
00786                         for(int n=1; n < s;n++){
00787                                 printf("%d ",n);
00788                                 for(int m=1;m < s;m++){
00789                                         if(hadj_[i][INDEX(n,m,s)] == INFINITY)
00790                                                 printf("~ ");
00791                                         else
00792                                                 printf("%d ",hadj_[i][INDEX(n,m,s)]);
00793                                 }
00794                                 printf("\n");
00795                         }
00796                         printf("\n\n");
00797                 }
00798 }
00799 
00800 void RouteLogic::hier_compute()
00801 {
00802         int i, j, k, m, n;
00803         for (j=1; j < D_; j++) 
00804                 for (k=1; k < C_[j]; k++) {
00805                         i = INDEX(j, k, Cmax_);
00806                         int s = (cluster_size_[i] + C_[j] + D_);
00807                         adj_ = new adj_entry[(s * s)];
00808                         memset((char *)adj_, 0, s * s * sizeof(adj_[0]));
00809                         for (n=0; n < s; n++)
00810                                 for(m=0; m < s; m++)
00811                                         adj_[INDEX(n, m, s)].cost = hadj_[i][INDEX(n, m, s)];
00812                         hier_compute_routes(i, j);
00813         
00814                         for (n=0; n < s; n++)
00815                                 for(m=0; m < s; m++)
00816                                         hroute_[i][INDEX(n, m, s)] = route_[INDEX(n, m, s)].next_hop;
00817                         delete [] adj_;
00818                 }
00819 }
00820 
00821 /*
00822  * Prints routing table - debugging function
00823  */
00824 void RouteLogic::hier_print_route()
00825 {
00826         for (int j=1; j < D_; j++) 
00827                 for (int k=1; k < C_[j]; k++) {
00828                         int i = INDEX(j, k, Cmax_);
00829                         int s = (cluster_size_[i]+C_[j]+D_);
00830                         printf("ROUTE_TABLE[%d] for cluster %d.%d :\n",i,j,k);
00831                         int temp = 1;
00832                         printf(" ");
00833                         while(temp < s){
00834                                 printf(" %d",temp);
00835                                 temp++;
00836                         }
00837                         printf("\n");
00838                         for(int n=1; n < s; n++){
00839                                 printf("%d ",n);
00840                                 for(int m=1; m < s; m++)
00841                                         printf("%d ",hroute_[i][INDEX(n, m, s)]);
00842                                 printf("\n");
00843                         }
00844                         printf("\n\n");
00845                 }
00846 }
00847 
00848 static class RouteLogicAlgoClass : public TclClass {
00849 public:
00850         RouteLogicAlgoClass() : TclClass("RouteLogic/Algorithmic") {}
00851         TclObject* create(int, const char*const*) {
00852                 return (new RouteLogicAlgo);
00853         }
00854 } class_routelogic_algo;

Generated on Tue Apr 20 12:14:29 2004 for NS2.26SourcesOriginal by doxygen 1.3.3