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

通讯编程

开发平台:

Visual C++

  1. /*
  2.  * nixnode.cc
  3.  * Copyright (C) 2000 by the University of Southern California
  4.  * $Id: nixnode.cc,v 1.9 2005/09/22 07:44:42 lacage Exp $
  5.  *
  6.  * This program is free software; you can redistribute it and/or
  7.  * modify it under the terms of the GNU General Public License,
  8.  * version 2, as published by the Free Software Foundation.
  9.  *
  10.  * This program is distributed in the hope that it will be useful,
  11.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13.  * GNU General Public License for more details.
  14.  *
  15.  * You should have received a copy of the GNU General Public License along
  16.  * with this program; if not, write to the Free Software Foundation, Inc.,
  17.  * 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
  18.  *
  19.  *
  20.  * The copyright of this module includes the following
  21.  * linking-with-specific-other-licenses addition:
  22.  *
  23.  * In addition, as a special exception, the copyright holders of
  24.  * this module give you permission to combine (via static or
  25.  * dynamic linking) this module with free software programs or
  26.  * libraries that are released under the GNU LGPL and with code
  27.  * included in the standard release of ns-2 under the Apache 2.0
  28.  * license or under otherwise-compatible licenses with advertising
  29.  * requirements (or modified versions of such code, with unchanged
  30.  * license).  You may copy and distribute such a system following the
  31.  * terms of the GNU GPL for this module and the licenses of the
  32.  * other code concerned, provided that you include the source code of
  33.  * that other code when and as the GNU GPL requires distribution of
  34.  * source code.
  35.  *
  36.  * Note that people who make modified versions of this module
  37.  * are not obligated to grant this special exception for their
  38.  * modified versions; it is their choice whether to do so.  The GNU
  39.  * General Public License gives permission to release a modified
  40.  * version without this exception; this exception also makes it
  41.  * possible to release a modified version which carries forward this
  42.  * exception.
  43.  *
  44.  */
  45. /*
  46.  * Nix-Vector routing capable node
  47.  * contributed to ns from 
  48.  * George F. Riley, Georgia Tech, Spring 2000
  49.  *
  50.  */
  51. #include "config.h"
  52. #ifdef HAVE_STL
  53. // STL includes
  54. #include <vector>
  55. #include "nix/nixnode.h"
  56. #include "routealgo/bfs.h"
  57. #include "nix/nixvec.h"
  58. #include "routealgo/routealgo.h"
  59. #include "nix/hdr_nv.h"
  60. static RNodeVec_t Nodes; // Vector of known nodes
  61. static int NVCount = 0;  // Number of nix vectors
  62. static Nixl_t NVMin = 0;    // Smallest nv
  63. static Nixl_t NVMax = 0;    // Largest nv
  64. static Nixl_t NVTot = 0;    // Total bitcount for all nv's (to compute avg)
  65. NixNode::NixNode() : RNode(), m_Map(-1), m_pNixVecs(0)
  66. {
  67. if(0)printf("Hello from NixNode Constructorn");
  68.   Nodes.push_back(this); // And save it
  69. }
  70. #ifdef MOVED_TO_NODE
  71. int NixNode::command(int argc, const char*const* argv)
  72. {
  73. if(0)printf("Hello from NixNode::Command argc %d argv[0] %s argv[1] %sn", 
  74.  argc, argv[0], argv[1]);
  75.   if (argc == 2)
  76.     {
  77.       Tcl& tcl = Tcl::instance();
  78.       if(strcmp(argv[1], "address?") == 0)
  79. {
  80. tcl.resultf("%d", address_);
  81. return TCL_OK;
  82. }
  83.       if(strcmp(argv[1], "report-id") == 0)
  84. {
  85. printf("Id is %ldn", m_id);
  86. return TCL_OK;
  87. }
  88.       if(strcmp(argv[1], "populate-objects") == 0)
  89. {
  90. PopulateObjects();
  91. return TCL_OK;
  92. }
  93.     }
  94. if (argc == 3)
  95. {
  96.       if (strcmp(argv[1], "get-nix-vector") == 0)
  97.         {
  98. GetNixVector(atol(argv[2]));
  99. return TCL_OK;
  100. }
  101.       if (strcmp(argv[1], "set-neighbor") == 0)
  102.         {
  103.           if(0)printf("Setting neighbor node %ld neighbor %sn",
  104.                  m_id, argv[2]);
  105.           AddAdj(atol(argv[2]));
  106.           return(TCL_OK);
  107.         }
  108.       if (strcmp(argv[1], "map-to") == 0)
  109.         {
  110.           m_Map = atol(argv[2]);
  111.           return(TCL_OK);
  112.         }
  113. }
  114.   return Node::command(argc,argv);
  115. }
  116. #endif
  117. void NixNode::AddAdj( // Add a new neighbor bit
  118.     nodeid_t WhichN)
  119. {    
  120.   Edge* pE;
  121.   if (0)
  122.     {
  123.       printf("Node %ld adding neighbor %ldn", m_id, WhichN);
  124.       fflush(stdout);
  125.     }
  126.   pE= new Edge(WhichN);
  127.   m_Adj.push_back(pE);
  128. }
  129. int NixNode::IsNeighbor( // TRUE neighbor bit set
  130.     nodeid_t WhichN)
  131. {    
  132.   for (EdgeVec_it i = m_Adj.begin(); i != m_Adj.end(); i++)
  133.     {
  134.       if ((*i)->m_n == WhichN) return(1); // Found it
  135.     }
  136.   return(0);
  137. }
  138. const NodeWeight_t NixNode::NextAdj( const NodeWeight_t& last)
  139. {
  140. Edge* pE;
  141.   static EdgeVec_it prev;
  142.   if (last.first == NODE_NONE)
  143.     {
  144.       prev = m_Adj.begin();
  145.       if (prev == (EdgeVec_it) NULL) // ! How can this happen?
  146.         return(NodeWeight_t(NODE_NONE, 0));
  147.       pE = *prev;
  148.       if(0)printf("NextAdj returning first edge %ldn",
  149.              pE->m_n);
  150.       return(NodeWeight_t(pE->m_n, 1));
  151.     }
  152.   else
  153.     { // See if last is prev
  154.       if (last.first == (*prev)->m_n)
  155.         { //Yep, just advance iterator
  156.           prev++;
  157.           if (prev == m_Adj.end())
  158.             { // No more
  159.               return(NodeWeight_t(NODE_NONE, 0));
  160.             }
  161.           else
  162.             {
  163.               pE = *prev;
  164.               if(0)printf("NextAdj returning next edge %ld w %dn",
  165.                      pE->m_n, 1);
  166.               return(NodeWeight_t(pE->m_n, 1));
  167.             }
  168.         }
  169.       else
  170.         { // Need to code this
  171.           printf("Non-linear advance of NextAdjn");
  172.           exit(5);
  173.         }
  174.     }
  175. }
  176. NixVec* NixNode::ComputeNixVector(nodeid_t t)
  177. { // Compute the NixVector to a target
  178. RoutingVec_t Parent;
  179. RoutingVec_t NextHop;
  180.   if(0)printf("Computing nixvector from %ld to %ldn", m_id,  t); 
  181.   BFS(Nodes, m_id, NextHop, Parent);
  182.   NixVec* pNv = new NixVec;
  183.   NixRoute(m_id, t, Parent, Nodes, *pNv);
  184.   return pNv;
  185. }
  186. NixPair_t NixNode::GetNix(nodeid_t t)  // Get neighbor index/length
  187. {
  188.   if(0)printf("Node %ld Getnix to target %ld, adjsize %lun",
  189.          m_id, t, (unsigned long)m_Adj.size());
  190.   Nixl_t l = GetNixl();
  191.   for (unsigned long i = 0; i < m_Adj.size(); i++)
  192.     {
  193.       if(0)printf("Node %ld checking nb %ldn", m_id, m_Adj[i]->m_n);
  194.       if (m_Adj[i]->m_n == t)
  195.         return(NixPair_t(i, l));  // Found it
  196.     }
  197.   return(NixPair_t(NIX_NONE, 0)); // Did not find it
  198. }
  199. Nixl_t NixNode::GetNixl()         // Get bits needed for nix entry
  200. {
  201.   return NixVec::GetBitl(m_Adj.size() - 1);
  202. }
  203. nodeid_t NixNode::GetNeighbor( Nix_t n, NixVec* pNv)
  204. { // Reconstruct a neighbor from the neighbor index
  205. if (n >= m_Adj.size())
  206. { // Foulup of some sort, print stuff out and abort
  207. printf("Nix %ld out of range (0 - %lun", n, (unsigned long)m_Adj.size());
  208. pNv->DBDump();
  209. exit(0);
  210. }
  211.   return(m_Adj[n]->m_n);
  212. }
  213. NsObject* NixNode::GetNsNeighbor(Nix_t n)   // Get the ns nexthop neighbor
  214. {
  215. if (n >= m_AdjObj.size()) return(NULL);   // Out of range
  216.   return(m_AdjObj[n]);
  217. }
  218. NixVec* NixNode::GetNixVector(nodeid_t t) // Get a nix vector for a target
  219. {
  220. NVMap_it i;
  221.  if (!m_pNixVecs)
  222.  { // No current list
  223.  m_pNixVecs = new NVMap_t;
  224.  }
  225.  
  226.  i = m_pNixVecs->find(t);
  227.  if (i == m_pNixVecs->end())
  228.  { // Does not exist, compute it and add to the hash-map
  229.  NixVec* pNv = ComputeNixVector(t);
  230.  // Debug statistics follow
  231.  if (NVCount == 0)
  232.  { // First one
  233.  NVMin = pNv->ALth();
  234.  NVMax = pNv->ALth();
  235.  }
  236.  else
  237.  {
  238.  NVMin = (pNv->ALth() < NVMin) ? pNv->ALth() : NVMin;
  239.  NVMax = (pNv->ALth() > NVMax) ? pNv->ALth() : NVMax;
  240.  }
  241.  NVCount++;
  242.  NVTot += pNv->ALth();
  243.  // End debug stats
  244. #ifdef TRY_DIFFERENT
  245.  m_pNixVecs[(const nodeid_t)t] = (const NixVec const *)pNv;
  246. #else
  247.  NVPair_t p = NVPair_t(t, pNv);
  248.                  //const pair <const nodeid_t, NixVec*> p1 = new pair<const nodeid_t, NixVec*>(t,pNv);
  249.  m_pNixVecs->insert(p);
  250. #endif
  251.  pNv->Reset();
  252.  // debug follows
  253. #ifdef DEBUG_VERBOSE
  254.  printf("Nixvec from %ld to %ldn", m_id, t);
  255.  pNv->DBDump();
  256. #endif
  257.  return(pNv); // Return a the vector
  258.  }
  259.  (*i).second->Reset();
  260.  return((*i).second); // Return the vector
  261. }
  262. void NixNode::PopulateObjects(void)
  263. {
  264. Edge*      pEdge;
  265. EdgeVec_it it;
  266. Tcl& tcl = Tcl::instance();
  267.   for (it = m_Adj.begin(); it != m_Adj.end(); it++)
  268. {
  269. pEdge = *it;
  270. if(0)printf("Node %ld processing edge %ldn", m_id, pEdge->m_n);
  271. tcl.evalf("[Simulator instance] get-link-head %d %d", m_id, pEdge->m_n);
  272. NsObject* pHead = (NsObject*)TclObject::lookup(tcl.result());
  273. if(0)printf("Found head at %sn", pHead->name());
  274. m_AdjObj.push_back(pHead); // And add it to vector
  275. if(0)tcl.evalf("%s info class", pHead->name());
  276. if(0)printf("Class is %sn", tcl.result());
  277. }
  278. // Static functions
  279. NixNode*   NixNode::GetNodeObject(nodeid_t n) // Get a node obj. based on id
  280. {
  281. if (n >= Nodes.size()) return(NULL); // Does not exist
  282. return((NixNode*)Nodes[n]);
  283. }
  284. void NixNode::PopulateAllObjects(void)
  285. {  // Called after $ns run, populates the next hop NS objects
  286. NixNode*    pN;
  287. RNodeVec_it it;
  288.   for (it = Nodes.begin(); it != Nodes.end(); it++)
  289. {
  290. pN = (NixNode*)*it;
  291. pN->PopulateObjects();
  292. }
  293. }
  294. // Global function (debug only)
  295. void ReportNixStats()
  296. {
  297. printf("Total NV %d Min %ld Max %ld Avg %fn", 
  298.  NVCount, NVMin, NVMax, (double)NVTot/(double)NVCount);
  299. }
  300. #endif /* STL */