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.39 2005/09/12 04:34:16 tomh 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             return (TCL_OK);
00178         } else if (strcmp(argv[1], "hier-lookup") == 0) {
00179             int nh;
00180             int res = lookup_hier((char*)argv[2], (char*)argv[3],
00181                           nh);
00182             return res;
00183         } else if (strcmp(argv[1], "reset") == 0) {
00184             int src = atoi(argv[2]) + 1;
00185             int dst = atoi(argv[3]) + 1;
00186             if (src <= 0 || dst <= 0) {
00187                 tcl.result("negative node number");
00188                 return (TCL_ERROR);
00189             }
00190             reset(src, dst);
00191             return (TCL_OK);
00192         } else if (strcmp(argv[1], "lookup") == 0) {
00193             int nh;
00194             int res = lookup_flat((char*)argv[2], (char*)argv[3], 
00195                           nh);
00196             if (res == TCL_OK)
00197                 tcl.resultf("%d", nh);
00198             return res;
00199         }
00200     }
00201     return (TclObject::command(argc, argv));
00202 }
00203 
00204 // xxx: using references as in this result is bogus---use pointers!
00205 int RouteLogic::lookup_flat(char* asrc, char* adst, int& result) {
00206     Tcl& tcl = Tcl::instance();
00207     int src = atoi(asrc) + 1;
00208     int dst = atoi(adst) + 1;
00209 
00210     if (route_ == 0) {
00211         // routes are computed only after the simulator is running
00212         // ($ns run).
00213         tcl.result("routes not yet computed");
00214         return (TCL_ERROR);
00215     }
00216     if (src >= size_ || dst >= size_) {
00217         tcl.result("node out of range");
00218         return (TCL_ERROR);
00219     }
00220     result = route_[INDEX(src, dst, size_)].next_hop - 1;
00221     return TCL_OK;
00222 }
00223 
00224 //added for pushback. a method callable from c++ code. 
00225 //probably could have been concocted from already existing methods - ratul
00226 int RouteLogic::lookup_flat(int sid, int did) {
00227     int src = sid+1;
00228     int dst = did+1;
00229     if (route_ == 0) {
00230         // routes are computed only after the simulator is running
00231         // ($ns run).
00232         printf("routes not yet computed\n");
00233         return (-1);
00234     }
00235     if (src >= size_ || dst >= size_) {
00236         printf("node out of range\n");
00237         return (-2);
00238     }
00239     return route_[INDEX(src, dst, size_)].next_hop - 1;
00240 }
00241 
00242 // xxx: using references as in this result is bogus---use pointers!
00243 int RouteLogic::lookup_hier(char* asrc, char* adst, int& result) {
00244     int i;
00245     int src[SMALL_LEN], dst[SMALL_LEN];
00246     Tcl& tcl = Tcl::instance();
00247 
00248     if ( hroute_ == 0) {
00249         tcl.result("Required Hier_data not sent");
00250         return TCL_ERROR;
00251     }
00252       
00253     ns_strtok(asrc, src);
00254     ns_strtok(adst, dst);
00255 
00256     for (i=0; i < level_; i++)
00257         if (src[i] <= 0) {
00258             tcl.result("negative src node number");
00259             return TCL_ERROR;
00260         }
00261     if (dst[0] <= 0) {
00262         tcl.result("negative dst domain number");
00263         return TCL_ERROR;
00264     }
00265 
00266     int d = src[0];
00267     int index = INDEX(src[0], src[1], Cmax_);
00268     int size = cluster_size_[index];
00269 
00270     if (hsize_[index] == 0) {
00271         tcl.result("Routes not computed");
00272         return TCL_ERROR;
00273     }
00274     if ((src[0] < D_) || (dst[0] < D_)) {
00275         if((src[1] < C_[d]) || (dst[1] < C_[dst[0]]))
00276             if((src[2] <= size) ||
00277                (dst[2]<=cluster_size_[INDEX(dst[0],dst[1],Cmax_)]))
00278                 ;
00279     } else { 
00280         tcl.result("node out of range");
00281         return TCL_ERROR;
00282     }
00283     int next_hop = 0;
00284     /* if node-domain lookup */
00285     if (((dst[1] <= 0) && (dst[2] <= 0)) ||
00286         (src[0] != dst[0])){
00287         next_hop = hroute_[index][N_D_INDEX(src[2], dst[0], size, C_[d], D_)];
00288     }
00289     /* if node-cluster lookup */
00290     else if ((dst[2] <= 0) || (src[1] != dst[1])) {
00291         next_hop = hroute_[index][N_C_INDEX(src[2], dst[1], size, C_[d], D_)];
00292     }
00293     /* if node-node lookup */
00294     else {
00295         next_hop = hroute_[index][N_N_INDEX(src[2], dst[2], size, C_[d], D_)];  
00296     }
00297     
00298     char target[SMALL_LEN];
00299     if (next_hop > 0) {
00300         get_address(target, next_hop, index, d, size, src);
00301         tcl.result(target);
00302         result= Address::instance().str2addr(target);
00303     } else {
00304         tcl.result("-1");
00305         result = -1;
00306     }
00307     return TCL_OK;
00308 }
00309 
00310 RouteLogic::RouteLogic()
00311 {
00312     size_ = 0;
00313     adj_ = 0;
00314     route_ = 0;
00315     /* additions for hierarchical routing extension */
00316     C_ = 0;
00317     D_ = 0;
00318     Cmax_ = 0;
00319     level_ = 0;
00320     hsize_ = 0;
00321     hadj_ = 0;
00322     hroute_ = 0;
00323     hconnect_ = 0;
00324     cluster_size_ = 0;
00325 }
00326     
00327 RouteLogic::~RouteLogic()
00328 {
00329     delete[] adj_;
00330     delete[] route_;
00331 
00332     for (int i = 0; i < (Cmax_ * D_); i++) {
00333         for (int j = 0; j < (Cmax_ + D_) * (cluster_size_[i]+1); j++) {
00334             if (hconnect_[i][j] != NULL)
00335                 delete [] hconnect_[i][j];
00336         }
00337         delete [] hconnect_[i];
00338     }
00339 
00340     for (int n =0; n < (Cmax_ * D_); n++) {
00341         if (hadj_[n] != NULL)
00342             delete [] hadj_[n];
00343         if (hroute_[n] != NULL)
00344             delete [] hroute_[n];
00345     }
00346 
00347     delete [] C_;
00348     delete [] hsize_;
00349     delete [] cluster_size_;
00350     delete hadj_;
00351     delete hroute_;
00352     delete hconnect_;
00353 }
00354 
00355 void RouteLogic::alloc(int n)
00356 {
00357     size_ = n;
00358     n *= n;
00359     adj_ = new adj_entry[n];
00360     for (int i = 0; i < n; ++i) {
00361         adj_[i].cost = INFINITY;
00362         adj_[i].entry = 0;
00363     }
00364 }
00365 
00366 /*
00367  * Check that we have enough storage in the adjacency array
00368  * to hold a node numbered "n"
00369  */
00370 void RouteLogic::check(int n)
00371 {
00372     if (n < size_)
00373         return;
00374 
00375     adj_entry* old = adj_;
00376     int osize = size_;
00377     int m = osize;
00378     if (m == 0)
00379         m = 16;
00380     while (m <= n)
00381         m <<= 1;
00382 
00383     alloc(m);
00384     for (int i = 0; i < osize; ++i) {
00385         for (int j = 0; j < osize; ++j)
00386             adj_[INDEX(i, j, m)].cost =old[INDEX(i, j, osize)].cost;
00387     }
00388     size_ = m;
00389     delete[] old;
00390 }
00391 
00392 void RouteLogic::insert(int src, int dst, double cost)
00393 {
00394     check(src);
00395     check(dst);
00396     adj_[INDEX(src, dst, size_)].cost = cost;
00397 }
00398 void RouteLogic::insert(int src, int dst, double cost, void* entry_)
00399 {
00400     check(src);
00401     check(dst);
00402     adj_[INDEX(src, dst, size_)].cost = cost;
00403     adj_[INDEX(src, dst, size_)].entry = entry_;
00404 }
00405 
00406 void RouteLogic::reset(int src, int dst)
00407 {
00408     assert(src < size_);
00409     assert(dst < size_);
00410     adj_[INDEX(src, dst, size_)].cost = INFINITY;
00411 }
00412 
00413 void RouteLogic::compute_routes()
00414 {
00415     int n = size_;
00416     int* parent = new int[n];
00417     double* hopcnt = new double[n];
00418 #define ADJ(i, j) adj_[INDEX(i, j, size_)].cost
00419 #define ADJ_ENTRY(i, j) adj_[INDEX(i, j, size_)].entry
00420 #define ROUTE(i, j) route_[INDEX(i, j, size_)].next_hop
00421 #define ROUTE_ENTRY(i, j) route_[INDEX(i, j, size_)].entry
00422     delete[] route_;
00423     route_ = new route_entry[n * n];
00424     memset((char *)route_, 0, n * n * sizeof(route_[0]));
00425 
00426     /* do for all the sources */
00427     int k;
00428     for (k = 1; k < n; ++k) {
00429         int v;
00430         for (v = 0; v < n; v++)
00431             parent[v] = v;
00432     
00433         /* set the route for all neighbours first */
00434         for (v = 1; v < n; ++v) {
00435             if (parent[v] != k) {
00436                 hopcnt[v] = ADJ(k, v);
00437                 if (hopcnt[v] != INFINITY) {
00438                     ROUTE(k, v) = v;
00439                     ROUTE_ENTRY(k, v) = ADJ_ENTRY(k, v);
00440                 }
00441             }
00442         }
00443         for (v = 1; v < n; ++v) {
00444             /*
00445              * w is the node that is the nearest to the subtree
00446              * that has been routed
00447              */
00448             int o = 0;
00449             /* XXX */
00450             hopcnt[0] = INFINITY;
00451             int w;
00452             for (w = 1; w < n; w++)
00453                 if (parent[w] != k && hopcnt[w] < hopcnt[o])
00454                     o = w;
00455             parent[o] = k;
00456             /*
00457              * update distance counts for the nodes that are
00458              * adjacent to o
00459              */
00460             if (o == 0)
00461                 continue;
00462             for (w = 1; w < n; w++) {
00463                 if (parent[w] != k &&
00464                     hopcnt[o] + ADJ(o, w) < hopcnt[w]) {
00465                     ROUTE(k, w) = ROUTE(k, o);
00466                     ROUTE_ENTRY(k, w) = 
00467                         ROUTE_ENTRY(k, o);
00468                     hopcnt[w] = hopcnt[o] + ADJ(o, w);
00469                 }
00470             }
00471         }
00472     }
00473     /*
00474      * The route to yourself is yourself.
00475      */
00476     for (k = 1; k < n; ++k) {
00477         ROUTE(k, k) = k;
00478         ROUTE_ENTRY(k, k) = 0; // This should not matter
00479     }
00480 
00481     delete[] hopcnt;
00482     delete[] parent;
00483 }
00484 
00485 /* hierarchical routing support */
00486 
00487 /*
00488  * This function creates adjacency matrix for each cluster at the lowest level
00489  * of the hierarchy for every node in the cluster, for every other cluster in 
00490  * the domain, and every other domain. can be extended from 3-level hierarchy 
00491  * to n-level along similar lines
00492  */
00493 void RouteLogic::hier_alloc(int i)
00494 {
00495     hsize_[i] = cluster_size_[i]+ Cmax_+ D_ ;
00496     hsize_[i] *= hsize_[i];
00497     hadj_[i] = new int[hsize_[i]];
00498     hroute_[i] = new int[hsize_[i]];
00499     hconnect_[i] = new char*[(Cmax_ + D_) * (cluster_size_[i]+1)];
00500     for (int n = 0; n < hsize_[i]; n++){
00501         hadj_[i][n] = INFINITY;
00502         hroute_[i][n] = INFINITY;
00503     }
00504 }
00505 
00506 void RouteLogic::hier_check(int i)
00507 {
00508     if(hsize_[i] > 0)
00509         return;
00510     else
00511         hier_alloc(i);
00512 }
00513 
00514 void RouteLogic::hier_init(void) 
00515 {
00516     int i;
00517 
00518     for (i = 1; i < D_; i++) {
00519         Cmax_ = C_[i] > Cmax_ ? C_[i]: Cmax_;
00520     }
00521     int arr_size = Cmax_ * D_ ;
00522     cluster_size_ = new int[arr_size]; 
00523     hsize_ = new int[arr_size];
00524     for (i = 0; i < arr_size; i++)
00525         hsize_[i] = 0;
00526     hadj_ = new int*[arr_size];
00527     hroute_ = new int*[arr_size];
00528     hconnect_ = new char**[arr_size];
00529 }
00530 
00531 
00532 int RouteLogic::domain_size(int domain) { 
00533     return (C_[domain+1]-1); 
00534 }
00535 int RouteLogic::cluster_size(int d, int c) {
00536     d += 1;
00537     c += 1;
00538     return (cluster_size_[INDEX(d, c, Cmax_)]);
00539 }
00540 
00541 int RouteLogic::elements_in_level(int *addr, int level) {
00542     if (level == 1)
00543         return (domains());
00544     else if (level == 2)
00545         return (domain_size(addr[0]));
00546     else if (level == 3) {
00547         return (cluster_size(addr[0], addr[1]));
00548     }
00549     return (-1);
00550 }
00551 
00552 void RouteLogic::str2address(const char*const* argv, int *src_addr, int *dst_addr)
00553 {
00554     char src[SMALL_LEN];
00555     char dst[SMALL_LEN];
00556 
00557     strcpy(src, argv[2]);
00558     strcpy(dst, argv[3]);
00559 
00560     ns_strtok(src, src_addr);
00561     ns_strtok(dst, dst_addr);
00562 }
00563 
00564 void RouteLogic::ns_strtok(char *addr, int *addrstr)
00565 {
00566     int i;
00567     char    tmpstr[SMALL_LEN];
00568     char    *next, *index;
00569     
00570     i = 0;
00571     strcpy(tmpstr, addr);
00572     next = tmpstr;
00573     while(*next){
00574         index = strstr(next, ".");
00575         if (index != NULL){
00576             next[index - next] = '\0';
00577             addrstr[i] = atoi(next) + 1;
00578             next = index + 1;
00579             i++;
00580         }
00581         else {
00582             if (*next != '\0') //damn that ending point
00583                 addrstr[i] = atoi(next) + 1;
00584             break;
00585         }
00586     }
00587 }
00588 
00589 
00590 void RouteLogic::get_address(char *address, int next_hop, int index, int d, 
00591                  int size, int *src)
00592 {
00593     if (next_hop <= size) {
00594         sprintf(address,"%d.%d.%d", src[0]-1, src[1]-1, next_hop-1);
00595     }
00596     else if ((next_hop > size) && (next_hop < (size + C_[d]))) {
00597         int temp = next_hop - size;
00598         int I = src[2] * (C_[d] + D_) + temp;
00599         strcpy(address, hconnect_[index][I]);
00600     }
00601     else {
00602         int temp = next_hop - size - (C_[d] - 1);
00603         int I = src[2] * (C_[d] + D_) + (C_[d] - 1 + temp);
00604         strcpy(address,hconnect_[index][I]);
00605     }
00606 }
00607 
00608 void RouteLogic::hier_reset(int *src, int *dst)
00609 {
00610     int i, d, n;
00611     d = src[0];
00612     if (src[0] == dst[0])
00613         if (src[1] == dst[1]) {
00614             i = INDEX(src[0], src[1], Cmax_);
00615             n = cluster_size_[i];
00616             hadj_[i][N_N_INDEX(src[2], dst[2], n, C_[d], D_)] = INFINITY;
00617         } else {
00618             for (int y=1; y < C_[d]; y++) { 
00619                 i = INDEX(src[0], y, Cmax_);
00620                 n = cluster_size_[i];
00621                 hadj_[i][C_C_INDEX(src[1], dst[1], n, C_[d], D_)] = INFINITY;
00622                 if (y == src[1])
00623                     hadj_[i][N_C_INDEX(src[2], dst[1], n, C_[d], D_)] = INFINITY; 
00624             }
00625         }
00626     else {
00627         for (int x=1; x < D_; x++)
00628             for (int y=1; y < C_[x]; y++) {
00629                 i = INDEX(x, y, Cmax_);
00630                 n = cluster_size_[i];
00631                 hadj_[i][D_D_INDEX(src[0], dst[0], n, C_[x], D_)] = INFINITY;
00632                 if ( x == src[0] ){
00633                     hadj_[i][C_D_INDEX(src[1], dst[0], n, C_[x], D_)] = INFINITY;
00634                     if (y == src[1])
00635                         hadj_[i][N_D_INDEX(src[2], dst[0], n, C_[x], D_)] = INFINITY;
00636                 }
00637             }
00638     }
00639 }
00640 
00641 void RouteLogic::hier_insert(int *src_addr, int *dst_addr, int cost)
00642 {
00643     int X1 = src_addr[0];
00644     int Y1 = src_addr[1];
00645     int Z1 = src_addr[2];
00646     int X2 = dst_addr[0];
00647     int Y2 = dst_addr[1];
00648     int Z2 = dst_addr[2];
00649     int n, i;
00650 
00651     if ( X1 == X2)
00652         if (Y1 == Y2){ 
00653             /*
00654              * For the same domain & cluster 
00655              */
00656             i = INDEX(X1, Y1, Cmax_);
00657             n = cluster_size_[i];
00658             hier_check(i);
00659             hadj_[i][N_N_INDEX(Z1, Z2, n, C_[X1], D_)] = cost;
00660         } else { 
00661             /* 
00662              * For the same domain but diff clusters 
00663              */
00664             for (int y=1; y < C_[X1]; y++) { /* insert cluster connectivity */
00665                 i = INDEX(X1, y, Cmax_);
00666                 n = cluster_size_[i];
00667                 hier_check(i);
00668                 hadj_[i][C_C_INDEX(Y1, Y2, n, C_[X1], D_)] = cost;
00669 
00670                 if (y == Y1) {  /* insert node conn. */
00671                     hadj_[i][N_C_INDEX(Z1, Y2, n, C_[X1], D_)] = cost;
00672                     int I = Z1 * (C_[X1]+ D_) + Y2;
00673                     hconnect_[i][I] = new char[SMALL_LEN];
00674                     sprintf(hconnect_[i][I],"%d.%d.%d",X2-1,Y2-1,Z2-1);
00675                 }
00676             }
00677         }
00678     else { 
00679         /* 
00680          * For different domains 
00681          */
00682         for (int x=1; x < D_; x++) { /* inset domain connectivity */
00683             for (int y=1; y < C_[x]; y++) {
00684                 i = INDEX(x, y, Cmax_);
00685                 n = cluster_size_[i];
00686                 hier_check(i);
00687                 hadj_[i][D_D_INDEX(X1, X2, n, C_[x], D_)] = cost;
00688             }
00689         }
00690         for (int y=1; y < C_[X1]; y++) { /* insert cluster connectivity */
00691             i = INDEX(X1, y, Cmax_);
00692             n = cluster_size_[i];
00693             hier_check(i);
00694             hadj_[i][C_D_INDEX(Y1, X2, n, C_[X1], D_)] = cost;
00695         }
00696         /* insert node connectivity */
00697         i = INDEX(X1, Y1, Cmax_);
00698         n = cluster_size_[i]; 
00699         hadj_[i][N_D_INDEX(Z1, X2, n, C_[X1], D_)] = cost;
00700         int I = Z1 * (C_[X1] + D_) + (C_[X1] - 1 + X2);
00701         hconnect_[i][I] = new char[SMALL_LEN];
00702         sprintf(hconnect_[i][I],"%d.%d.%d",X2-1,Y2-1,Z2-1);
00703     }
00704 }
00705 
00706 void RouteLogic::hier_compute_routes(int i, int j)
00707 {
00708     int size = (cluster_size_[i] + C_[j] + D_);
00709     int n = size ;
00710     double* hopcnt = new double[n];
00711 #define HADJ(i, j) adj_[INDEX(i, j, size)].cost
00712 #define HROUTE(i, j) route_[INDEX(i, j, size)].next_hop
00713     delete[] route_;
00714     route_ = new route_entry[n * n];
00715     int* parent = new int[n];
00716     memset((char *)route_, 0, n * n * sizeof(route_[0]));
00717 
00718     /* do for all the sources */
00719     int k;
00720     for (k = 1; k < n; ++k) {
00721         int v;
00722         for (v = 0; v < n; v++)
00723             parent[v] = v;
00724 
00725         /* set the route for all neighbours first */
00726         for (v = 1; v < n; ++v) {
00727             if (parent[v] != k) {
00728                 hopcnt[v] = HADJ(k, v);
00729                 if (hopcnt[v] != INFINITY)
00730                     HROUTE(k, v) = v;
00731             }
00732         }
00733         for (v = 1; v < n; ++v) {
00734             /*
00735              * w is the node that is the nearest to the subtree
00736              * that has been routed
00737              */
00738             int o = 0;
00739             /* XXX */
00740             hopcnt[0] = INFINITY;
00741             int w;
00742             for (w = 1; w < n; w++)
00743                 if (parent[w] != k && hopcnt[w] < hopcnt[o])
00744                     o = w;
00745             parent[o] = k;
00746             /*
00747              * update distance counts for the nodes that are
00748              * adjacent to o
00749              */
00750             if (o == 0)
00751                 continue;
00752             for (w = 1; w < n; w++) {
00753                 if (parent[w] != k &&
00754                     hopcnt[o] + HADJ(o, w) < hopcnt[w]) {
00755                     HROUTE(k, w) = HROUTE(k, o);
00756                     hopcnt[w] = hopcnt[o] + HADJ(o, w);
00757                 }
00758             }
00759         }
00760     }
00761     /*
00762      * The route to yourself is yourself.
00763      */
00764     for (k = 1; k < n; ++k)
00765         HROUTE(k, k) = k;
00766 
00767     delete[] hopcnt;
00768     delete[] parent;
00769 }
00770 
00771 /* function to check the adjacency matrices created */
00772 void RouteLogic::hier_print_hadj() {
00773     int i, j, k;
00774 
00775     for (j=1; j < D_; j++) 
00776         for (k=1; k < C_[j]; k++) {
00777             i = INDEX(j, k, Cmax_);
00778             int s = (cluster_size_[i] + C_[j] + D_);
00779             printf("ADJ MATRIX[%d] for cluster %d.%d :\n",i,j,k);
00780             int temp = 1;
00781             printf(" ");
00782             while(temp < s){
00783                 printf(" %d",temp);
00784                 temp++;
00785             }
00786             printf("\n");
00787             for(int n=1; n < s;n++){
00788                 printf("%d ",n);
00789                 for(int m=1;m < s;m++){
00790                     if(hadj_[i][INDEX(n,m,s)] == INFINITY)
00791                         printf("~ ");
00792                     else
00793                         printf("%d ",hadj_[i][INDEX(n,m,s)]);
00794                 }
00795                 printf("\n");
00796             }
00797             printf("\n\n");
00798         }
00799 }
00800 
00801 void RouteLogic::hier_compute()
00802 {
00803     int i, j, k, m, n;
00804     for (j=1; j < D_; j++) 
00805         for (k=1; k < C_[j]; k++) {
00806             i = INDEX(j, k, Cmax_);
00807             int s = (cluster_size_[i] + C_[j] + D_);
00808             adj_ = new adj_entry[(s * s)];
00809             memset((char *)adj_, 0, s * s * sizeof(adj_[0]));
00810             for (n=0; n < s; n++)
00811                 for(m=0; m < s; m++)
00812                     adj_[INDEX(n, m, s)].cost = hadj_[i][INDEX(n, m, s)];
00813             hier_compute_routes(i, j);
00814     
00815             for (n=0; n < s; n++)
00816                 for(m=0; m < s; m++)
00817                     hroute_[i][INDEX(n, m, s)] = route_[INDEX(n, m, s)].next_hop;
00818             delete [] adj_;
00819         }
00820 }
00821 
00822 /*
00823  * Prints routing table - debugging function
00824  */
00825 void RouteLogic::hier_print_route()
00826 {
00827     for (int j=1; j < D_; j++) 
00828         for (int k=1; k < C_[j]; k++) {
00829             int i = INDEX(j, k, Cmax_);
00830             int s = (cluster_size_[i]+C_[j]+D_);
00831             printf("ROUTE_TABLE[%d] for cluster %d.%d :\n",i,j,k);
00832             int temp = 1;
00833             printf(" ");
00834             while(temp < s){
00835                 printf(" %d",temp);
00836                 temp++;
00837             }
00838             printf("\n");
00839             for(int n=1; n < s; n++){
00840                 printf("%d ",n);
00841                 for(int m=1; m < s; m++)
00842                     printf("%d ",hroute_[i][INDEX(n, m, s)]);
00843                 printf("\n");
00844             }
00845             printf("\n\n");
00846         }
00847 }
00848 
00849 static class RouteLogicAlgoClass : public TclClass {
00850 public:
00851     RouteLogicAlgoClass() : TclClass("RouteLogic/Algorithmic") {}
00852     TclObject* create(int, const char*const*) {
00853         return (new RouteLogicAlgo);
00854     }
00855 } class_routelogic_algo;

Generated on Tue Mar 6 16:47:50 2007 for ns2 Network Simulator 2.29 by  doxygen 1.4.6