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

通讯编程

开发平台:

Visual C++

  1. // Define classes for routing table representation and lookup
  2. // George F. Riley, Georgia Tech, Winter 2000
  3. // Defines several variations on routing table representations
  4. // and a method to determine the most memory efficient.
  5. #include "config.h"
  6. #ifdef HAVE_STL
  7. #include <stdio.h>
  8. #include <routealgo/rlookup.h>
  9. //#include <routealgo/rbitmap.h>
  10. // Static function for RLookup
  11. // Analyze  a routing table, find best default, and first/last non-default
  12. void RLookup::Analyze( // Analyze the next hop table
  13.     RoutingVec_t& r,
  14.     RoutingVec_t& p, // Population counts (returned)
  15.     nodeid_t& d, // default(returned)
  16.     nodeid_t& n, // number of default entries (returned)
  17.     nodeid_t  o, // table's owner
  18.     nodeid_t& f, // first non-default (returned)
  19.     nodeid_t& l) // last  non-default (returned)
  20. {
  21.   unsigned int i;
  22.   p.erase(p.begin(), p.end());
  23.   p.reserve(r.size()); // This is how many entries we need
  24.   for (i = 0; i < r.size(); i++) p.push_back(0);
  25.   for (i = 0; i < r.size(); i++)
  26.     {
  27.       if (i != o)
  28.         p[r[i]]++; // Count occurrences of each (except oaner)
  29.     }
  30.   // Find the best default
  31.   nodeid_t largest = NODE_NONE;
  32.   if(0)printf("Pop size %lun", (unsigned long)p.size());
  33.   nodeid_t nonzero = 0; // Number of non-zero entries
  34.   for (i = 0; i < p.size(); i++)
  35.     {
  36.       if(0)printf("Pop %d = %ldn", i, p[i]);
  37.       if (p[i]) nonzero++; // Count non-zeros
  38.       if (largest == NODE_NONE || p[i] > p[largest])
  39.         largest = i;
  40.     }
  41.   d = largest; // Set the default
  42.   if (nonzero == 0)
  43.     d = NODE_NONE; // Pathological case, no routes at all
  44.   n = p[largest]; // number of default
  45.   f = NODE_NONE;
  46.   l = NODE_NONE;
  47.   if (nonzero == 1)
  48.     { // Nothing but defaults, easy case
  49.       return;
  50.     }
  51.   for (i = 0; i < r.size(); i++)
  52.     {
  53.       if (i != o)
  54.         {
  55.           if (r[i] != d && f == NODE_NONE) f = i;
  56.           if (r[i] != d) l = i;
  57.         }
  58.     }
  59. }
  60. // RLookup constructor/destructor
  61. RLookup::RLookup()  { }
  62. RLookup::~RLookup() { }
  63. // Function to output a routing table on an ostream
  64. void RLookup::Log( ostream& os)
  65. {
  66.   os << "LOG called";
  67. }
  68. void RLookup::Populate( istream& is)
  69. {
  70.   printf("Populate(istream) calledn");
  71. }
  72. #ifdef OLD_WAY
  73. ostream& operator<<(ostream& os , const RLookup& R ) // Output a routing table
  74. {
  75.   int w = R.WhatType();
  76.   os << w ; // Log the type for reconstruction
  77.   switch( w ) {
  78.     case RL_FIXED :
  79.       os << *((FRLookup*)&R);
  80.       break;
  81.     case RL_BITMAP :
  82.       os << *((BMLookup*)&R);
  83.       break;
  84.     case RL_HASH :
  85.       os << *((HMLookup*)&R);
  86.       break;
  87.     case RL_NEXTHOP :
  88.       os << "NHLog not coded";
  89.       break;
  90.   }
  91.   return os;
  92. }
  93. #endif
  94. // Null Routing methods
  95. NOLookup::NOLookup()
  96. {
  97.   if(0)printf("Created NOLookupn");
  98. }
  99. NOLookup::~NOLookup()
  100. {
  101. }
  102. void NOLookup::Populate(
  103.     RoutingVec_t&,   // NextHop table
  104.     RoutingVec_t&,   // Population counts
  105.     nodeid_t,        // Default route
  106.     nodeid_t,
  107.     nodeid_t,
  108.     nodeid_t)
  109. {
  110. }
  111. RLookup_Types NOLookup::WhatType(void) const // Identifies the type of lookup
  112. {
  113.   return RL_NULL;
  114. }
  115. nodeid_t NOLookup::Lookup(nodeid_t)
  116. {
  117.   return(NODE_NONE);
  118. }
  119. size_t   NOLookup::Size()
  120. {
  121.   return(0);
  122. }
  123. void NOLookup::Log( ostream& os)
  124. {
  125.   os << " " << (int)WhatType();
  126. }
  127. // Fixed Routing methods
  128. FRLookup::FRLookup() : m_Default(NODE_NONE)
  129. {
  130.   if(0)printf("Created FRLookupn");
  131. }
  132. FRLookup::~FRLookup()
  133. {
  134. }
  135. void FRLookup::Populate(
  136.     RoutingVec_t&,   // NextHop table
  137.     RoutingVec_t&,   // Population counts
  138.     nodeid_t d,      // Default route
  139.     nodeid_t,
  140.     nodeid_t,
  141.     nodeid_t)
  142. {
  143.   m_Default = d;
  144. }
  145. RLookup_Types FRLookup::WhatType(void) const // Identifies the type of lookup
  146. {
  147.   return RL_FIXED;
  148. }
  149. nodeid_t FRLookup::Lookup(nodeid_t)
  150. {
  151.   return(m_Default);
  152. }
  153. size_t   FRLookup::Size()
  154. {
  155.   return sizeof(m_Default);
  156. }
  157. size_t   FRLookup::EstimateSize(
  158.     RoutingVec_t&,   // NextHop table
  159.     RoutingVec_t&,   // Population counts
  160.     nodeid_t,        // Default route
  161.     nodeid_t,        // Number default
  162.     nodeid_t,
  163.     nodeid_t,
  164.     nodeid_t)
  165. {
  166.   return sizeof(u_long);
  167. }
  168. void FRLookup::Log( ostream& os)
  169. {
  170.   os << " " << (int)WhatType();
  171.   os << " " << Default();
  172. }
  173. class BitMap;
  174. // Bitmap routing methods
  175. BMLookup::BMLookup() : m_Default(NODE_NONE), m_FirstNonDefault(NODE_NONE), 
  176.                        m_LastNonDefault(NODE_NONE), m_pBitMap(0)
  177. {
  178.   if(0)printf("Created BMLookupn");
  179. }
  180. BMLookup::~BMLookup()
  181. {
  182.   if (m_pBitMap) delete m_pBitMap;
  183. }
  184. RLookup_Types BMLookup::WhatType(void) const // Identifies the type of lookup
  185. {
  186.   return RL_BITMAP;
  187. }
  188. void BMLookup::Populate(
  189.     RoutingVec_t& r, // NextHop table
  190.     RoutingVec_t& p, // Population counts
  191.     nodeid_t d, // Default route
  192.     nodeid_t o,
  193.     nodeid_t f,
  194.     nodeid_t l)
  195. {
  196.   unsigned int i;
  197.   m_Default = d; // Set the default route
  198.   // Now for each non-zero NH neighbor, create an entry in the NVec
  199.   for (i = 0; i < p.size(); i++)
  200.     {
  201.       if (p[i])
  202.         {
  203.           m_NVec.push_back((nodeid_t)i);
  204.           if(0)printf("Creating nix entry %dn", i);
  205.         }
  206.     } 
  207.   u_long c = l - f + 1; // How many entries we need
  208.   if(0)printf("BMLookup::Populate..found %lu NHNn", (unsigned long)m_NVec.size());
  209.   m_pBitMap = new BitMap(c, BitMap::FindBPE(m_NVec.size()));
  210.   
  211.   // And populate the bitmap   
  212.   for(u_long k = 0; k < c; k++)
  213.     {
  214.       u_long ind;
  215.       for (ind = 0; ind < m_NVec.size(); ind++)
  216.         {
  217.           if (m_NVec[ind] == r[f+k]) break;
  218.         }
  219.       //RoutingVec_it v = find(m_NVec.begin(), m_NVec.end(), r[f + k]);
  220.       m_pBitMap->Set(k, ind);
  221.     }
  222.   m_FirstNonDefault = f;
  223.   m_LastNonDefault = l;
  224. }
  225. nodeid_t BMLookup::Lookup(nodeid_t t)
  226. {
  227. nodeid_t r;
  228.   if (t < m_FirstNonDefault) return(m_Default);
  229.   if (t > m_LastNonDefault ) return(m_Default);
  230.   if (!m_pBitMap) return(NODE_NONE);
  231.   u_long i = m_pBitMap->Get(t - m_FirstNonDefault); // Lookup neighbor index
  232.   r = m_NVec[i];
  233.   if(0)printf("BLookup lookedup entry %ld ind %ld, found %ldn",
  234.          t - m_FirstNonDefault, i, r);
  235.   return(r);
  236. }
  237. size_t   BMLookup::Size()
  238. {
  239.   return sizeof(nodeid_t) + //m_Default
  240.          sizeof(nodeid_t) + // m_FirstNonDefault
  241.          sizeof(nodeid_t) + // m_LastNonDefault)
  242.          sizeof(BitMap*)  + // m_pBitMap)
  243.          m_pBitMap->Size() + 
  244.          sizeof(RoutingVec_t) + // m_NVec)
  245.          sizeof(nodeid_t)*m_NVec.size();    // items in m_NVec
  246. }
  247. size_t   BMLookup::NumberEntries()
  248. {
  249.   return(m_LastNonDefault - m_FirstNonDefault -1 );
  250. }
  251. size_t   BMLookup::EstimateSize(
  252.     RoutingVec_t& r,   // NextHop table
  253.     RoutingVec_t& p,   // Population counts
  254.     nodeid_t d,        // Default route
  255.     nodeid_t n,        // Number default
  256.     nodeid_t o,
  257.     nodeid_t f,
  258.     nodeid_t l)
  259. {
  260. unsigned int i;
  261. unsigned int k = 0;
  262.   // Count non-zero entries in pop vector
  263.   for (i = 0; i < p.size(); i++)
  264.     if (p[i]) k++;
  265.   u_long c = l - f + 1; // How many entries we need
  266.   return sizeof(nodeid_t) + //m_Default
  267.          sizeof(nodeid_t) + // m_FirstNonDefault
  268.          sizeof(nodeid_t) + // m_LastNonDefault)
  269.          sizeof(BitMap*)  + // m_pBitMap)
  270.          BitMap::EstimateSize(c, BitMap::FindBPE(k)) +
  271.          sizeof(RoutingVec_t) + // m_NVec)
  272.          sizeof(nodeid_t)*k;    // items in m_NVec
  273. }
  274. void BMLookup::Log( ostream& os)
  275. {
  276. RoutingVec_it i;
  277.   os << " " << (int)WhatType();
  278.   os << " " << m_Default;
  279.   os << " " << m_FirstNonDefault;
  280.   os << " " << m_LastNonDefault;
  281.   os << " " << m_NVec.size();
  282.   for (i = m_NVec.begin(); i != m_NVec.end(); i++)
  283.     {
  284.       os << " " << *i;
  285.     }
  286.   m_pBitMap->Log(os);
  287. }
  288. // Hashmap routing methods
  289. HMLookup::HMLookup() : m_Default(NODE_NONE)
  290. {
  291.   if(0)printf("Created HMLookupn");
  292. }
  293. HMLookup::~HMLookup()
  294. {
  295. }
  296. RLookup_Types HMLookup::WhatType(void) const // Identifies the type of lookup
  297. {
  298.   return RL_HASH;
  299. }
  300. void HMLookup::Populate(
  301.     RoutingVec_t& r, // NextHop table
  302.     RoutingVec_t&,   // Population counts
  303.     nodeid_t d,      // Default route
  304.     nodeid_t,
  305.     nodeid_t,
  306.     nodeid_t)
  307. {
  308.   unsigned int i;
  309.   m_Default = d; // Set the default route
  310.   for (i = 0; i < r.size(); i++)
  311.     {
  312.       if (r[i] != d && r[i] != NODE_NONE)
  313.         { // Not the default, create a HT entry
  314. #ifdef CHANGED_DUE_TO_FREEBSD_PROB
  315.           RoutePair_t* p = new RoutePair_t(i, r[i]);
  316.           m_RouteMap.insert(*p);
  317. #else
  318.           RoutePair_t p = RoutePair_t(i, r[i]);
  319.           m_RouteMap.insert(p);
  320. #endif
  321.         }
  322.     }
  323. }
  324. nodeid_t HMLookup::Lookup(nodeid_t t)
  325. {
  326.   RouteMap_it i;
  327.   i = m_RouteMap.find(t);
  328.   if (i == m_RouteMap.end()) return(m_Default);
  329.   return((*i).second);
  330. }
  331. size_t   HMLookup::Size( void )
  332. {
  333.   return sizeof(u_long) +      // m_Default
  334.          sizeof(RouteMap_t) +  // m_RouteMap
  335.          m_RouteMap.size() * sizeof(nodeid_t); // entries in hash table
  336. }
  337. size_t   HMLookup::NumberEntries()
  338. {
  339.   return(m_RouteMap.size());
  340. }
  341. size_t   HMLookup::EstimateSize(
  342.     RoutingVec_t& r, // NextHop table
  343.     RoutingVec_t& p, // Population counts
  344.     nodeid_t d,      // Default route
  345.     nodeid_t n,      // Number default
  346.     nodeid_t,
  347.     nodeid_t,
  348.     nodeid_t)
  349. {
  350.   return sizeof(u_long) +      // m_Default
  351.          sizeof(RouteMap_t) +  // m_RouteMap
  352.          (r.size() - d) * sizeof(nodeid_t); // entries in hash table
  353. }
  354. void HMLookup::Log( ostream& os)
  355. {
  356. RouteMap_it i;
  357.   os << " " << (int)WhatType();
  358.   os << " " << m_Default;
  359.   for (i = m_RouteMap.begin(); i != m_RouteMap.end(); i++)
  360.     {
  361.       os << " " << (*i).first << " " << (*i).second;
  362.     }
  363. }
  364. // NextHop (inefficient) routing methods
  365. NHLookup::NHLookup()
  366. {
  367.   if(0)printf("Created NHLookupn");
  368. }
  369. NHLookup::~NHLookup()
  370. {
  371. }
  372. RLookup_Types NHLookup::WhatType(void) const // Identifies the type of lookup
  373. {
  374.   return RL_NEXTHOP;
  375. }
  376. void NHLookup::Populate(
  377.     RoutingVec_t& r, // NextHop table
  378.     RoutingVec_t&,   // Population counts
  379.     nodeid_t d,      // Default route
  380.     nodeid_t,
  381.     nodeid_t,
  382.     nodeid_t)
  383. {
  384.   unsigned int i;
  385.   // Just copy the routing vector
  386.   for (i = 0; i < r.size(); i++)
  387.     {
  388.       m_RouteTable.push_back(r[i]);
  389.     }
  390. }
  391. void NHLookup::Populate(istream& is)
  392. { // Populate from log flie
  393. int count;
  394.   is >> count;
  395.   for (int i = 0; i < count; i++)
  396.     {
  397.       int j;
  398.       is >> j;
  399.       nodeid_t n;
  400.       n = (j < 0) ? NODE_NONE : (nodeid_t)j;
  401.       m_RouteTable.push_back(n);
  402.     }
  403. }
  404. nodeid_t NHLookup::Lookup(nodeid_t t)
  405. {
  406.   if (t >= m_RouteTable.size()) return(NODE_NONE);
  407.   return(m_RouteTable[t]); // Just a table lookup
  408. }
  409. size_t   NHLookup::Size( void )
  410. {
  411.   return sizeof(u_long) * m_RouteTable.size();
  412. }
  413. size_t   NHLookup::NumberEntries()
  414. {
  415.   return(m_RouteTable.size());
  416. }
  417. void NHLookup::Log( ostream& os)
  418. {
  419. RoutingVec_it i;
  420.   os << " " << (int)WhatType();
  421.   os << " " << m_RouteTable.size();
  422.   for (i = m_RouteTable.begin(); i != m_RouteTable.end(); i++)
  423.     {
  424.       if (*i == NODE_NONE)
  425.         os << " " << -1; // The NODE_NONE representation is hard to read
  426.       else
  427.         os << " " << *i;
  428.     }
  429. }
  430. size_t   NHLookup::EstimateSize(
  431.     RoutingVec_t& r, // NextHop table
  432.     RoutingVec_t&,   // Population counts
  433.     nodeid_t d,      // Default route
  434.     nodeid_t,
  435.     nodeid_t,
  436.     nodeid_t,
  437.     nodeid_t)
  438. {
  439.   return sizeof(u_long) * r.size();
  440. }
  441. #endif /* STL */