route.cc
上传用户:rrhhcc
上传日期:2015-12-11
资源大小:54129k
文件大小:21k
源码类别:

通讯编程

开发平台:

Visual C++

  1. /* -*- Mode:C++; c-basic-offset:8; tab-width:8; indent-tabs-mode:t -*- */
  2. /*
  3.  * Copyright (c) 1991-1994 Regents of the University of California.
  4.  * All rights reserved.
  5.  *
  6.  * Redistribution and use in source and binary forms, with or without
  7.  * modification, are permitted provided that the following conditions
  8.  * are met:
  9.  * 1. Redistributions of source code must retain the above copyright
  10.  *    notice, this list of conditions and the following disclaimer.
  11.  * 2. Redistributions in binary form must reproduce the above copyright
  12.  *    notice, this list of conditions and the following disclaimer in the
  13.  *    documentation and/or other materials provided with the distribution.
  14.  * 3. All advertising materials mentioning features or use of this software
  15.  *    must display the following acknowledgement:
  16.  * This product includes software developed by the University of
  17.  * California, Berkeley and the Network Research Group at
  18.  * Lawrence Berkeley Laboratory.
  19.  * 4. Neither the name of the University nor of the Laboratory may be used
  20.  *    to endorse or promote products derived from this software without
  21.  *    specific prior written permission.
  22.  *
  23.  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  24.  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  25.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  26.  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  27.  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  28.  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  29.  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  30.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  31.  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  32.  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  33.  * SUCH DAMAGE.
  34.  *
  35.  * Routing code for general topologies based on min-cost routing algorithm in
  36.  * Bertsekas' book.  Written originally by S. Keshav, 7/18/88
  37.  * (his work covered by identical UC Copyright)
  38.  */
  39. #ifndef lint
  40. static const char rcsid[] =
  41. "@(#) $Header: /cvsroot/nsnam/ns-2/routing/route.cc,v 1.39 2005/09/12 04:34:16 tomh Exp $ (LBL)";
  42. #endif
  43. #include <stdlib.h>
  44. #include <assert.h>
  45. #include "config.h"
  46. #include "route.h"
  47. #include "address.h"
  48. class RouteLogicClass : public TclClass {
  49. public:
  50. RouteLogicClass() : TclClass("RouteLogic") {}
  51. TclObject* create(int, const char*const*) {
  52. return (new RouteLogic());
  53. }
  54. } routelogic_class;
  55. void RouteLogic::reset_all()
  56. {
  57. delete[] adj_;
  58. delete[] route_;
  59. adj_ = 0; 
  60. route_ = 0;
  61. size_ = 0;
  62. }
  63. int RouteLogic::command(int argc, const char*const* argv)
  64. {
  65. Tcl& tcl = Tcl::instance();
  66. if (argc == 2) {
  67. if (strcmp(argv[1], "compute") == 0) {
  68. if (adj_ == 0)
  69. return (TCL_OK);
  70. compute_routes();
  71. return (TCL_OK);
  72. } else if (strcmp(argv[1], "hier-compute") == 0) {
  73. if (hadj_ == 0) {
  74. return (TCL_OK);
  75. }
  76. hier_compute();
  77. return (TCL_OK);
  78. } else if (strcmp(argv[1], "hier-print") == 0) {
  79. hier_print_hadj();
  80. return (TCL_OK);
  81. } else if (strcmp(argv[1], "hier-print-route") == 0) {
  82. hier_print_route();
  83. return (TCL_OK);
  84. } else if (strcmp(argv[1], "reset") == 0) {
  85. reset_all();
  86. return (TCL_OK);
  87. }
  88. } else if (argc > 2) {
  89. if (strcmp(argv[1], "insert") == 0) {
  90. int src = atoi(argv[2]) + 1;
  91. int dst = atoi(argv[3]) + 1;
  92. if (src <= 0 || dst <= 0) {
  93. tcl.result("negative node number");
  94. return (TCL_ERROR);
  95. }
  96. double cost = (argc == 5 ? atof(argv[4]) : 1);
  97. insert(src, dst, cost);
  98. return (TCL_OK);
  99. } else if (strcmp(argv[1], "hlevel-is") == 0) {
  100. level_ = atoi(argv[2]);
  101. if (level_ < 1) {
  102. tcl.result("send-hlevel: # hierarchy levels should be non-zero");
  103. return (TCL_ERROR);
  104. }
  105. return (TCL_OK);
  106. } else if (strcmp(argv[1], "send-num-of-domains") == 0) {
  107. D_ = atoi(argv[2]) + 1;
  108. if (D_ <= 1) {
  109. tcl.result("send-num-of-domains: # domains should be larger than 1");
  110. return (TCL_ERROR);
  111. }
  112. return (TCL_OK);
  113. } else if (strcmp(argv[1], "send-num-of-clusters") == 0) {
  114. if (argc != D_ + 1) {
  115. tcl.resultf("send-num-of-clusters: # of "
  116.     "clusters %d != domain (%d) + 1n",
  117.     argc, D_);
  118. return (TCL_ERROR);
  119. }
  120. C_ = new int[D_];
  121. int i, j = 2;
  122. for (i = 1; i < D_; i++) {
  123. C_[i] = atoi(argv[j]) + 1;
  124. j++;
  125. }
  126. hier_init();
  127. return (TCL_OK);
  128. } else if(strcmp(argv[1], "send-num-of-nodes") == 0) {
  129. int i, j, k=2, Ctotal=0 ;
  130. for (i=1; i < D_; i++)
  131. Ctotal = Ctotal + (C_[i]-1);
  132. if (argc != (Ctotal + 2)) {
  133. tcl.result("send-hlastdata: # args do not match");
  134. return (TCL_ERROR);
  135. }
  136. for (i=1; i < D_; i++)
  137. for (j=1; (j < C_[i]); j++) {
  138. cluster_size_[INDEX(i, j, Cmax_)] = atoi(argv[k]);
  139. k++;
  140. }
  141. return (TCL_OK);
  142. } else if (strcmp(argv[1], "hier-insert") == 0) {
  143. if(Cmax_== 0 || D_== 0) {
  144. tcl.result("Required Hier_data not sent");
  145. return (TCL_ERROR);
  146. }
  147. int i;
  148. int src_addr[SMALL_LEN], dst_addr[SMALL_LEN];
  149. str2address(argv, src_addr, dst_addr);
  150. for (i=0; i < level_; i++)
  151. if (src_addr[i]<=0 || dst_addr[i]<=0){
  152. tcl.result ("negative node number");
  153. return (TCL_ERROR);
  154. }
  155. int cost = (argc == 5 ? atoi(argv[4]) : 1);
  156. hier_insert(src_addr, dst_addr, cost);
  157. return (TCL_OK);
  158. } else if (strcmp(argv[1], "hier-reset") == 0) {
  159. int i;
  160. int  src_addr[SMALL_LEN], dst_addr[SMALL_LEN];
  161. str2address(argv, src_addr, dst_addr);
  162. // assuming node-node addresses (instead of 
  163. // node-cluster or node-domain pair) 
  164. // are sent for hier_reset  
  165. for (i=0; i < level_; i++)
  166. if (src_addr[i]<=0 || dst_addr[i]<=0){
  167. tcl.result ("negative node number");
  168. return (TCL_ERROR);
  169. }
  170. hier_reset(src_addr, dst_addr);
  171. return (TCL_OK);
  172. } else if (strcmp(argv[1], "hier-lookup") == 0) {
  173. int nh;
  174. int res = lookup_hier((char*)argv[2], (char*)argv[3],
  175.       nh);
  176. return res;
  177. } else if (strcmp(argv[1], "reset") == 0) {
  178. int src = atoi(argv[2]) + 1;
  179. int dst = atoi(argv[3]) + 1;
  180. if (src <= 0 || dst <= 0) {
  181. tcl.result("negative node number");
  182. return (TCL_ERROR);
  183. }
  184. reset(src, dst);
  185. return (TCL_OK);
  186. } else if (strcmp(argv[1], "lookup") == 0) {
  187. int nh;
  188. int res = lookup_flat((char*)argv[2], (char*)argv[3], 
  189.       nh);
  190. if (res == TCL_OK)
  191. tcl.resultf("%d", nh);
  192. return res;
  193. }
  194. }
  195. return (TclObject::command(argc, argv));
  196. }
  197. // xxx: using references as in this result is bogus---use pointers!
  198. int RouteLogic::lookup_flat(char* asrc, char* adst, int& result) {
  199. Tcl& tcl = Tcl::instance();
  200. int src = atoi(asrc) + 1;
  201. int dst = atoi(adst) + 1;
  202. if (route_ == 0) {
  203. // routes are computed only after the simulator is running
  204. // ($ns run).
  205. tcl.result("routes not yet computed");
  206. return (TCL_ERROR);
  207. }
  208. if (src >= size_ || dst >= size_) {
  209. tcl.result("node out of range");
  210. return (TCL_ERROR);
  211. }
  212. result = route_[INDEX(src, dst, size_)].next_hop - 1;
  213. return TCL_OK;
  214. }
  215. //added for pushback. a method callable from c++ code. 
  216. //probably could have been concocted from already existing methods - ratul
  217. int RouteLogic::lookup_flat(int sid, int did) {
  218. int src = sid+1;
  219. int dst = did+1;
  220. if (route_ == 0) {
  221. // routes are computed only after the simulator is running
  222. // ($ns run).
  223. printf("routes not yet computedn");
  224. return (-1);
  225. }
  226. if (src >= size_ || dst >= size_) {
  227. printf("node out of rangen");
  228. return (-2);
  229. }
  230. return route_[INDEX(src, dst, size_)].next_hop - 1;
  231. }
  232. // xxx: using references as in this result is bogus---use pointers!
  233. int RouteLogic::lookup_hier(char* asrc, char* adst, int& result) {
  234. int i;
  235. int src[SMALL_LEN], dst[SMALL_LEN];
  236. Tcl& tcl = Tcl::instance();
  237. if ( hroute_ == 0) {
  238. tcl.result("Required Hier_data not sent");
  239. return TCL_ERROR;
  240. }
  241.       
  242. ns_strtok(asrc, src);
  243. ns_strtok(adst, dst);
  244. for (i=0; i < level_; i++)
  245. if (src[i] <= 0) {
  246. tcl.result("negative src node number");
  247. return TCL_ERROR;
  248. }
  249. if (dst[0] <= 0) {
  250. tcl.result("negative dst domain number");
  251. return TCL_ERROR;
  252. }
  253. int d = src[0];
  254. int index = INDEX(src[0], src[1], Cmax_);
  255. int size = cluster_size_[index];
  256. if (hsize_[index] == 0) {
  257. tcl.result("Routes not computed");
  258. return TCL_ERROR;
  259. }
  260. if ((src[0] < D_) || (dst[0] < D_)) {
  261. if((src[1] < C_[d]) || (dst[1] < C_[dst[0]]))
  262. if((src[2] <= size) ||
  263.    (dst[2]<=cluster_size_[INDEX(dst[0],dst[1],Cmax_)]))
  264. ;
  265. } else { 
  266. tcl.result("node out of range");
  267. return TCL_ERROR;
  268. }
  269. int next_hop = 0;
  270. /* if node-domain lookup */
  271. if (((dst[1] <= 0) && (dst[2] <= 0)) ||
  272.     (src[0] != dst[0])){
  273. next_hop = hroute_[index][N_D_INDEX(src[2], dst[0], size, C_[d], D_)];
  274. }
  275. /* if node-cluster lookup */
  276. else if ((dst[2] <= 0) || (src[1] != dst[1])) {
  277. next_hop = hroute_[index][N_C_INDEX(src[2], dst[1], size, C_[d], D_)];
  278. }
  279. /* if node-node lookup */
  280. else {
  281. next_hop = hroute_[index][N_N_INDEX(src[2], dst[2], size, C_[d], D_)];
  282. }
  283. char target[SMALL_LEN];
  284. if (next_hop > 0) {
  285. get_address(target, next_hop, index, d, size, src);
  286. tcl.result(target);
  287. result= Address::instance().str2addr(target);
  288. } else {
  289. tcl.result("-1");
  290. result = -1;
  291. }
  292. return TCL_OK;
  293. }
  294. RouteLogic::RouteLogic()
  295. {
  296. size_ = 0;
  297. adj_ = 0;
  298. route_ = 0;
  299. /* additions for hierarchical routing extension */
  300. C_ = 0;
  301. D_ = 0;
  302. Cmax_ = 0;
  303. level_ = 0;
  304. hsize_ = 0;
  305. hadj_ = 0;
  306. hroute_ = 0;
  307. hconnect_ = 0;
  308. cluster_size_ = 0;
  309. }
  310. RouteLogic::~RouteLogic()
  311. {
  312. delete[] adj_;
  313. delete[] route_;
  314. for (int i = 0; i < (Cmax_ * D_); i++) {
  315. for (int j = 0; j < (Cmax_ + D_) * (cluster_size_[i]+1); j++) {
  316. if (hconnect_[i][j] != NULL)
  317. delete [] hconnect_[i][j];
  318. }
  319. delete [] hconnect_[i];
  320. }
  321. for (int n =0; n < (Cmax_ * D_); n++) {
  322. if (hadj_[n] != NULL)
  323. delete [] hadj_[n];
  324. if (hroute_[n] != NULL)
  325. delete [] hroute_[n];
  326. }
  327. delete [] C_;
  328. delete [] hsize_;
  329. delete [] cluster_size_;
  330. delete hadj_;
  331. delete hroute_;
  332. delete hconnect_;
  333. }
  334. void RouteLogic::alloc(int n)
  335. {
  336. size_ = n;
  337. n *= n;
  338. adj_ = new adj_entry[n];
  339. for (int i = 0; i < n; ++i) {
  340. adj_[i].cost = INFINITY;
  341. adj_[i].entry = 0;
  342. }
  343. }
  344. /*
  345.  * Check that we have enough storage in the adjacency array
  346.  * to hold a node numbered "n"
  347.  */
  348. void RouteLogic::check(int n)
  349. {
  350. if (n < size_)
  351. return;
  352. adj_entry* old = adj_;
  353. int osize = size_;
  354. int m = osize;
  355. if (m == 0)
  356. m = 16;
  357. while (m <= n)
  358. m <<= 1;
  359. alloc(m);
  360. for (int i = 0; i < osize; ++i) {
  361. for (int j = 0; j < osize; ++j)
  362. adj_[INDEX(i, j, m)].cost =old[INDEX(i, j, osize)].cost;
  363. }
  364. size_ = m;
  365. delete[] old;
  366. }
  367. void RouteLogic::insert(int src, int dst, double cost)
  368. {
  369. check(src);
  370. check(dst);
  371. adj_[INDEX(src, dst, size_)].cost = cost;
  372. }
  373. void RouteLogic::insert(int src, int dst, double cost, void* entry_)
  374. {
  375. check(src);
  376. check(dst);
  377. adj_[INDEX(src, dst, size_)].cost = cost;
  378. adj_[INDEX(src, dst, size_)].entry = entry_;
  379. }
  380. void RouteLogic::reset(int src, int dst)
  381. {
  382. assert(src < size_);
  383. assert(dst < size_);
  384. adj_[INDEX(src, dst, size_)].cost = INFINITY;
  385. }
  386. void RouteLogic::compute_routes()
  387. {
  388. int n = size_;
  389. int* parent = new int[n];
  390. double* hopcnt = new double[n];
  391. #define ADJ(i, j) adj_[INDEX(i, j, size_)].cost
  392. #define ADJ_ENTRY(i, j) adj_[INDEX(i, j, size_)].entry
  393. #define ROUTE(i, j) route_[INDEX(i, j, size_)].next_hop
  394. #define ROUTE_ENTRY(i, j) route_[INDEX(i, j, size_)].entry
  395. delete[] route_;
  396. route_ = new route_entry[n * n];
  397. memset((char *)route_, 0, n * n * sizeof(route_[0]));
  398. /* do for all the sources */
  399. int k;
  400. for (k = 1; k < n; ++k) {
  401. int v;
  402. for (v = 0; v < n; v++)
  403. parent[v] = v;
  404. /* set the route for all neighbours first */
  405. for (v = 1; v < n; ++v) {
  406. if (parent[v] != k) {
  407. hopcnt[v] = ADJ(k, v);
  408. if (hopcnt[v] != INFINITY) {
  409. ROUTE(k, v) = v;
  410. ROUTE_ENTRY(k, v) = ADJ_ENTRY(k, v);
  411. }
  412. }
  413. }
  414. for (v = 1; v < n; ++v) {
  415. /*
  416.  * w is the node that is the nearest to the subtree
  417.  * that has been routed
  418.  */
  419. int o = 0;
  420. /* XXX */
  421. hopcnt[0] = INFINITY;
  422. int w;
  423. for (w = 1; w < n; w++)
  424. if (parent[w] != k && hopcnt[w] < hopcnt[o])
  425. o = w;
  426. parent[o] = k;
  427. /*
  428.  * update distance counts for the nodes that are
  429.  * adjacent to o
  430.  */
  431. if (o == 0)
  432. continue;
  433. for (w = 1; w < n; w++) {
  434. if (parent[w] != k &&
  435.     hopcnt[o] + ADJ(o, w) < hopcnt[w]) {
  436. ROUTE(k, w) = ROUTE(k, o);
  437. ROUTE_ENTRY(k, w) = 
  438.     ROUTE_ENTRY(k, o);
  439. hopcnt[w] = hopcnt[o] + ADJ(o, w);
  440. }
  441. }
  442. }
  443. }
  444. /*
  445.  * The route to yourself is yourself.
  446.  */
  447. for (k = 1; k < n; ++k) {
  448. ROUTE(k, k) = k;
  449. ROUTE_ENTRY(k, k) = 0; // This should not matter
  450. }
  451. delete[] hopcnt;
  452. delete[] parent;
  453. }
  454. /* hierarchical routing support */
  455. /*
  456.  * This function creates adjacency matrix for each cluster at the lowest level
  457.  * of the hierarchy for every node in the cluster, for every other cluster in 
  458.  * the domain, and every other domain. can be extended from 3-level hierarchy 
  459.  * to n-level along similar lines
  460.  */
  461. void RouteLogic::hier_alloc(int i)
  462. {
  463. hsize_[i] = cluster_size_[i]+ Cmax_+ D_ ;
  464. hsize_[i] *= hsize_[i];
  465. hadj_[i] = new int[hsize_[i]];
  466. hroute_[i] = new int[hsize_[i]];
  467. hconnect_[i] = new char*[(Cmax_ + D_) * (cluster_size_[i]+1)];
  468. for (int n = 0; n < hsize_[i]; n++){
  469. hadj_[i][n] = INFINITY;
  470. hroute_[i][n] = INFINITY;
  471. }
  472. }
  473. void RouteLogic::hier_check(int i)
  474. {
  475. if(hsize_[i] > 0)
  476. return;
  477. else
  478. hier_alloc(i);
  479. }
  480. void RouteLogic::hier_init(void) 
  481. {
  482. int i;
  483. for (i = 1; i < D_; i++) {
  484. Cmax_ = C_[i] > Cmax_ ? C_[i]: Cmax_;
  485. }
  486. int arr_size = Cmax_ * D_ ;
  487. cluster_size_ = new int[arr_size]; 
  488. hsize_ = new int[arr_size];
  489. for (i = 0; i < arr_size; i++)
  490. hsize_[i] = 0;
  491. hadj_ = new int*[arr_size];
  492. hroute_ = new int*[arr_size];
  493. hconnect_ = new char**[arr_size];
  494. }
  495. int RouteLogic::domain_size(int domain) { 
  496. return (C_[domain+1]-1); 
  497. }
  498. int RouteLogic::cluster_size(int d, int c) {
  499. d += 1;
  500. c += 1;
  501. return (cluster_size_[INDEX(d, c, Cmax_)]);
  502. }
  503. int RouteLogic::elements_in_level(int *addr, int level) {
  504. if (level == 1)
  505. return (domains());
  506. else if (level == 2)
  507. return (domain_size(addr[0]));
  508. else if (level == 3) {
  509. return (cluster_size(addr[0], addr[1]));
  510. }
  511. return (-1);
  512. }
  513. void RouteLogic::str2address(const char*const* argv, int *src_addr, int *dst_addr)
  514. {
  515. char src[SMALL_LEN];
  516. char dst[SMALL_LEN];
  517. strcpy(src, argv[2]);
  518. strcpy(dst, argv[3]);
  519. ns_strtok(src, src_addr);
  520. ns_strtok(dst, dst_addr);
  521. }
  522. void RouteLogic::ns_strtok(char *addr, int *addrstr)
  523. {
  524. int i;
  525. char tmpstr[SMALL_LEN];
  526. char *next, *index;
  527. i = 0;
  528. strcpy(tmpstr, addr);
  529. next = tmpstr;
  530. while(*next){
  531. index = strstr(next, ".");
  532. if (index != NULL){
  533. next[index - next] = '';
  534. addrstr[i] = atoi(next) + 1;
  535. next = index + 1;
  536. i++;
  537. }
  538. else {
  539. if (*next != '') //damn that ending point
  540. addrstr[i] = atoi(next) + 1;
  541. break;
  542. }
  543. }
  544. }
  545. void RouteLogic::get_address(char *address, int next_hop, int index, int d, 
  546.      int size, int *src)
  547. {
  548. if (next_hop <= size) {
  549. sprintf(address,"%d.%d.%d", src[0]-1, src[1]-1, next_hop-1);
  550. }
  551. else if ((next_hop > size) && (next_hop < (size + C_[d]))) {
  552. int temp = next_hop - size;
  553. int I = src[2] * (C_[d] + D_) + temp;
  554. strcpy(address, hconnect_[index][I]);
  555. }
  556. else {
  557. int temp = next_hop - size - (C_[d] - 1);
  558. int I = src[2] * (C_[d] + D_) + (C_[d] - 1 + temp);
  559. strcpy(address,hconnect_[index][I]);
  560. }
  561. }
  562. void RouteLogic::hier_reset(int *src, int *dst)
  563. {
  564. int i, d, n;
  565. d = src[0];
  566. if (src[0] == dst[0])
  567. if (src[1] == dst[1]) {
  568. i = INDEX(src[0], src[1], Cmax_);
  569. n = cluster_size_[i];
  570. hadj_[i][N_N_INDEX(src[2], dst[2], n, C_[d], D_)] = INFINITY;
  571. } else {
  572. for (int y=1; y < C_[d]; y++) { 
  573. i = INDEX(src[0], y, Cmax_);
  574. n = cluster_size_[i];
  575. hadj_[i][C_C_INDEX(src[1], dst[1], n, C_[d], D_)] = INFINITY;
  576. if (y == src[1])
  577. hadj_[i][N_C_INDEX(src[2], dst[1], n, C_[d], D_)] = INFINITY; 
  578. }
  579. }
  580. else {
  581. for (int x=1; x < D_; x++)
  582. for (int y=1; y < C_[x]; y++) {
  583. i = INDEX(x, y, Cmax_);
  584. n = cluster_size_[i];
  585. hadj_[i][D_D_INDEX(src[0], dst[0], n, C_[x], D_)] = INFINITY;
  586. if ( x == src[0] ){
  587. hadj_[i][C_D_INDEX(src[1], dst[0], n, C_[x], D_)] = INFINITY;
  588. if (y == src[1])
  589. hadj_[i][N_D_INDEX(src[2], dst[0], n, C_[x], D_)] = INFINITY;
  590. }
  591. }
  592. }
  593. }
  594. void RouteLogic::hier_insert(int *src_addr, int *dst_addr, int cost)
  595. {
  596. int X1 = src_addr[0];
  597. int Y1 = src_addr[1];
  598. int Z1 = src_addr[2];
  599. int X2 = dst_addr[0];
  600. int Y2 = dst_addr[1];
  601. int Z2 = dst_addr[2];
  602. int n, i;
  603. if ( X1 == X2)
  604. if (Y1 == Y2){ 
  605. /*
  606.  * For the same domain & cluster 
  607.  */
  608. i = INDEX(X1, Y1, Cmax_);
  609. n = cluster_size_[i];
  610. hier_check(i);
  611. hadj_[i][N_N_INDEX(Z1, Z2, n, C_[X1], D_)] = cost;
  612. } else { 
  613. /* 
  614.  * For the same domain but diff clusters 
  615.  */
  616. for (int y=1; y < C_[X1]; y++) { /* insert cluster connectivity */
  617. i = INDEX(X1, y, Cmax_);
  618. n = cluster_size_[i];
  619. hier_check(i);
  620. hadj_[i][C_C_INDEX(Y1, Y2, n, C_[X1], D_)] = cost;
  621. if (y == Y1) {  /* insert node conn. */
  622. hadj_[i][N_C_INDEX(Z1, Y2, n, C_[X1], D_)] = cost;
  623. int I = Z1 * (C_[X1]+ D_) + Y2;
  624. hconnect_[i][I] = new char[SMALL_LEN];
  625. sprintf(hconnect_[i][I],"%d.%d.%d",X2-1,Y2-1,Z2-1);
  626. }
  627. }
  628. }
  629. else { 
  630. /* 
  631.  * For different domains 
  632.  */
  633. for (int x=1; x < D_; x++) { /* inset domain connectivity */
  634. for (int y=1; y < C_[x]; y++) {
  635. i = INDEX(x, y, Cmax_);
  636. n = cluster_size_[i];
  637. hier_check(i);
  638. hadj_[i][D_D_INDEX(X1, X2, n, C_[x], D_)] = cost;
  639. }
  640. }
  641. for (int y=1; y < C_[X1]; y++) { /* insert cluster connectivity */
  642. i = INDEX(X1, y, Cmax_);
  643. n = cluster_size_[i];
  644. hier_check(i);
  645. hadj_[i][C_D_INDEX(Y1, X2, n, C_[X1], D_)] = cost;
  646. }
  647. /* insert node connectivity */
  648. i = INDEX(X1, Y1, Cmax_);
  649. n = cluster_size_[i]; 
  650. hadj_[i][N_D_INDEX(Z1, X2, n, C_[X1], D_)] = cost;
  651. int I = Z1 * (C_[X1] + D_) + (C_[X1] - 1 + X2);
  652. hconnect_[i][I] = new char[SMALL_LEN];
  653. sprintf(hconnect_[i][I],"%d.%d.%d",X2-1,Y2-1,Z2-1);
  654. }
  655. }
  656. void RouteLogic::hier_compute_routes(int i, int j)
  657. {
  658. int size = (cluster_size_[i] + C_[j] + D_);
  659. int n = size ;
  660. double* hopcnt = new double[n];
  661. #define HADJ(i, j) adj_[INDEX(i, j, size)].cost
  662. #define HROUTE(i, j) route_[INDEX(i, j, size)].next_hop
  663. delete[] route_;
  664. route_ = new route_entry[n * n];
  665. int* parent = new int[n];
  666. memset((char *)route_, 0, n * n * sizeof(route_[0]));
  667. /* do for all the sources */
  668. int k;
  669. for (k = 1; k < n; ++k) {
  670. int v;
  671. for (v = 0; v < n; v++)
  672. parent[v] = v;
  673. /* set the route for all neighbours first */
  674. for (v = 1; v < n; ++v) {
  675. if (parent[v] != k) {
  676. hopcnt[v] = HADJ(k, v);
  677. if (hopcnt[v] != INFINITY)
  678. HROUTE(k, v) = v;
  679. }
  680. }
  681. for (v = 1; v < n; ++v) {
  682. /*
  683.  * w is the node that is the nearest to the subtree
  684.  * that has been routed
  685.  */
  686. int o = 0;
  687. /* XXX */
  688. hopcnt[0] = INFINITY;
  689. int w;
  690. for (w = 1; w < n; w++)
  691. if (parent[w] != k && hopcnt[w] < hopcnt[o])
  692. o = w;
  693. parent[o] = k;
  694. /*
  695.  * update distance counts for the nodes that are
  696.  * adjacent to o
  697.  */
  698. if (o == 0)
  699. continue;
  700. for (w = 1; w < n; w++) {
  701. if (parent[w] != k &&
  702.     hopcnt[o] + HADJ(o, w) < hopcnt[w]) {
  703. HROUTE(k, w) = HROUTE(k, o);
  704. hopcnt[w] = hopcnt[o] + HADJ(o, w);
  705. }
  706. }
  707. }
  708. }
  709. /*
  710.  * The route to yourself is yourself.
  711.  */
  712. for (k = 1; k < n; ++k)
  713. HROUTE(k, k) = k;
  714. delete[] hopcnt;
  715. delete[] parent;
  716. }
  717. /* function to check the adjacency matrices created */
  718. void RouteLogic::hier_print_hadj() {
  719. int i, j, k;
  720. for (j=1; j < D_; j++) 
  721. for (k=1; k < C_[j]; k++) {
  722. i = INDEX(j, k, Cmax_);
  723. int s = (cluster_size_[i] + C_[j] + D_);
  724. printf("ADJ MATRIX[%d] for cluster %d.%d :n",i,j,k);
  725. int temp = 1;
  726. printf(" ");
  727. while(temp < s){
  728. printf(" %d",temp);
  729. temp++;
  730. }
  731. printf("n");
  732. for(int n=1; n < s;n++){
  733. printf("%d ",n);
  734. for(int m=1;m < s;m++){
  735. if(hadj_[i][INDEX(n,m,s)] == INFINITY)
  736. printf("~ ");
  737. else
  738. printf("%d ",hadj_[i][INDEX(n,m,s)]);
  739. }
  740. printf("n");
  741. }
  742. printf("nn");
  743. }
  744. }
  745. void RouteLogic::hier_compute()
  746. {
  747. int i, j, k, m, n;
  748. for (j=1; j < D_; j++) 
  749. for (k=1; k < C_[j]; k++) {
  750. i = INDEX(j, k, Cmax_);
  751. int s = (cluster_size_[i] + C_[j] + D_);
  752. adj_ = new adj_entry[(s * s)];
  753. memset((char *)adj_, 0, s * s * sizeof(adj_[0]));
  754. for (n=0; n < s; n++)
  755. for(m=0; m < s; m++)
  756. adj_[INDEX(n, m, s)].cost = hadj_[i][INDEX(n, m, s)];
  757. hier_compute_routes(i, j);
  758. for (n=0; n < s; n++)
  759. for(m=0; m < s; m++)
  760. hroute_[i][INDEX(n, m, s)] = route_[INDEX(n, m, s)].next_hop;
  761. delete [] adj_;
  762. }
  763. }
  764. /*
  765.  * Prints routing table - debugging function
  766.  */
  767. void RouteLogic::hier_print_route()
  768. {
  769. for (int j=1; j < D_; j++) 
  770. for (int k=1; k < C_[j]; k++) {
  771. int i = INDEX(j, k, Cmax_);
  772. int s = (cluster_size_[i]+C_[j]+D_);
  773. printf("ROUTE_TABLE[%d] for cluster %d.%d :n",i,j,k);
  774. int temp = 1;
  775. printf(" ");
  776. while(temp < s){
  777. printf(" %d",temp);
  778. temp++;
  779. }
  780. printf("n");
  781. for(int n=1; n < s; n++){
  782. printf("%d ",n);
  783. for(int m=1; m < s; m++)
  784. printf("%d ",hroute_[i][INDEX(n, m, s)]);
  785. printf("n");
  786. }
  787. printf("nn");
  788. }
  789. }
  790. static class RouteLogicAlgoClass : public TclClass {
  791. public:
  792. RouteLogicAlgoClass() : TclClass("RouteLogic/Algorithmic") {}
  793. TclObject* create(int, const char*const*) {
  794. return (new RouteLogicAlgo);
  795. }
  796. } class_routelogic_algo;