rlookup.cc

Go to the documentation of this file.
00001 // Define classes for routing table representation and lookup
00002 // George F. Riley, Georgia Tech, Winter 2000
00003 
00004 // Defines several variations on routing table representations
00005 // and a method to determine the most memory efficient.
00006 
00007 #include "config.h"
00008 #ifdef HAVE_STL
00009 
00010 #include <stdio.h>
00011 #include <routealgo/rlookup.h>
00012 //#include <routealgo/rbitmap.h>
00013 
00014 // Static function for RLookup
00015 // Analyze  a routing table, find best default, and first/last non-default
00016 
00017 void RLookup::Analyze( // Analyze the next hop table
00018     RoutingVec_t& r,
00019     RoutingVec_t& p, // Population counts (returned)
00020     nodeid_t& d, // default(returned)
00021     nodeid_t& n, // number of default entries (returned)
00022     nodeid_t  o, // table's owner
00023     nodeid_t& f, // first non-default (returned)
00024     nodeid_t& l) // last  non-default (returned)
00025 {
00026   unsigned int i;
00027 
00028   p.erase(p.begin(), p.end());
00029   p.reserve(r.size()); // This is how many entries we need
00030   for (i = 0; i < r.size(); i++) p.push_back(0);
00031   for (i = 0; i < r.size(); i++)
00032     {
00033       if (i != o)
00034         p[r[i]]++; // Count occurrences of each (except oaner)
00035     }
00036   // Find the best default
00037   nodeid_t largest = NODE_NONE;
00038   if(0)printf("Pop size %lu\n", (unsigned long)p.size());
00039   nodeid_t nonzero = 0; // Number of non-zero entries
00040   for (i = 0; i < p.size(); i++)
00041     {
00042       if(0)printf("Pop %d = %ld\n", i, p[i]);
00043       if (p[i]) nonzero++; // Count non-zeros
00044       if (largest == NODE_NONE || p[i] > p[largest])
00045         largest = i;
00046     }
00047   d = largest; // Set the default
00048   if (nonzero == 0)
00049     d = NODE_NONE; // Pathological case, no routes at all
00050   n = p[largest]; // number of default
00051   f = NODE_NONE;
00052   l = NODE_NONE;
00053   if (nonzero == 1)
00054     { // Nothing but defaults, easy case
00055       return;
00056     }
00057   for (i = 0; i < r.size(); i++)
00058     {
00059       if (i != o)
00060         {
00061           if (r[i] != d && f == NODE_NONE) f = i;
00062           if (r[i] != d) l = i;
00063         }
00064     }
00065 }
00066 
00067 // RLookup constructor/destructor
00068 RLookup::RLookup()  { }
00069 RLookup::~RLookup() { }
00070 
00071 // Function to output a routing table on an ostream
00072 void RLookup::Log( ostream& os)
00073 {
00074   os << "LOG called";
00075 }
00076 
00077 void RLookup::Populate( istream& is)
00078 {
00079   printf("Populate(istream) called\n");
00080 }
00081 
00082 #ifdef OLD_WAY
00083 ostream& operator<<(ostream& os , const RLookup& R ) // Output a routing table
00084 {
00085   int w = R.WhatType();
00086   os << w ; // Log the type for reconstruction
00087   switch( w ) {
00088     case RL_FIXED :
00089       os << *((FRLookup*)&R);
00090       break;
00091     case RL_BITMAP :
00092       os << *((BMLookup*)&R);
00093       break;
00094     case RL_HASH :
00095       os << *((HMLookup*)&R);
00096       break;
00097     case RL_NEXTHOP :
00098       os << "NHLog not coded";
00099       break;
00100   }
00101   return os;
00102 }
00103 #endif
00104 
00105 // Null Routing methods
00106 
00107 NOLookup::NOLookup()
00108 {
00109   if(0)printf("Created NOLookup\n");
00110 }
00111 
00112 NOLookup::~NOLookup()
00113 {
00114 }
00115 
00116 void NOLookup::Populate(
00117     RoutingVec_t&,   // NextHop table
00118     RoutingVec_t&,   // Population counts
00119     nodeid_t,        // Default route
00120     nodeid_t,
00121     nodeid_t,
00122     nodeid_t)
00123 {
00124 
00125 }
00126 
00127 RLookup_Types NOLookup::WhatType(void) const // Identifies the type of lookup
00128 {
00129   return RL_NULL;
00130 }
00131 
00132 
00133 nodeid_t NOLookup::Lookup(nodeid_t)
00134 {
00135   return(NODE_NONE);
00136 }
00137 
00138 size_t   NOLookup::Size()
00139 {
00140   return(0);
00141 }
00142 
00143 void NOLookup::Log( ostream& os)
00144 {
00145   os << " " << (int)WhatType();
00146 }
00147 
00148 // Fixed Routing methods
00149 
00150 FRLookup::FRLookup() : m_Default(NODE_NONE)
00151 {
00152   if(0)printf("Created FRLookup\n");
00153 }
00154 
00155 FRLookup::~FRLookup()
00156 {
00157 }
00158 
00159 void FRLookup::Populate(
00160     RoutingVec_t&,   // NextHop table
00161     RoutingVec_t&,   // Population counts
00162     nodeid_t d,      // Default route
00163     nodeid_t,
00164     nodeid_t,
00165     nodeid_t)
00166 {
00167   m_Default = d;
00168 }
00169 
00170 RLookup_Types FRLookup::WhatType(void) const // Identifies the type of lookup
00171 {
00172   return RL_FIXED;
00173 }
00174 
00175 
00176 nodeid_t FRLookup::Lookup(nodeid_t)
00177 {
00178   return(m_Default);
00179 }
00180 
00181 size_t   FRLookup::Size()
00182 {
00183   return sizeof(m_Default);
00184 }
00185 
00186 size_t   FRLookup::EstimateSize(
00187     RoutingVec_t&,   // NextHop table
00188     RoutingVec_t&,   // Population counts
00189     nodeid_t,        // Default route
00190     nodeid_t,        // Number default
00191     nodeid_t,
00192     nodeid_t,
00193     nodeid_t)
00194 {
00195   return sizeof(u_long);
00196 }
00197 
00198 void FRLookup::Log( ostream& os)
00199 {
00200   os << " " << (int)WhatType();
00201   os << " " << Default();
00202 }
00203 
00204 class BitMap;
00205 
00206 // Bitmap routing methods
00207 
00208 BMLookup::BMLookup() : m_Default(NODE_NONE), m_FirstNonDefault(NODE_NONE), 
00209                        m_LastNonDefault(NODE_NONE), m_pBitMap(0)
00210 {
00211   if(0)printf("Created BMLookup\n");
00212 }
00213 
00214 BMLookup::~BMLookup()
00215 {
00216   if (m_pBitMap) delete m_pBitMap;
00217 }
00218 
00219 RLookup_Types BMLookup::WhatType(void) const // Identifies the type of lookup
00220 {
00221   return RL_BITMAP;
00222 }
00223 
00224 void BMLookup::Populate(
00225     RoutingVec_t& r, // NextHop table
00226     RoutingVec_t& p, // Population counts
00227     nodeid_t d, // Default route
00228     nodeid_t o,
00229     nodeid_t f,
00230     nodeid_t l)
00231 {
00232   unsigned int i;
00233 
00234   m_Default = d; // Set the default route
00235 
00236   // Now for each non-zero NH neighbor, create an entry in the NVec
00237   for (i = 0; i < p.size(); i++)
00238     {
00239       if (p[i])
00240         {
00241           m_NVec.push_back((nodeid_t)i);
00242           if(0)printf("Creating nix entry %d\n", i);
00243         }
00244     } 
00245   u_long c = l - f + 1; // How many entries we need
00246   if(0)printf("BMLookup::Populate..found %lu NHN\n", (unsigned long)m_NVec.size());
00247   m_pBitMap = new BitMap(c, BitMap::FindBPE(m_NVec.size()));
00248   
00249   // And populate the bitmap   
00250   for(u_long k = 0; k < c; k++)
00251     {
00252       u_long ind;
00253       for (ind = 0; ind < m_NVec.size(); ind++)
00254         {
00255           if (m_NVec[ind] == r[f+k]) break;
00256         }
00257       //RoutingVec_it v = find(m_NVec.begin(), m_NVec.end(), r[f + k]);
00258       m_pBitMap->Set(k, ind);
00259     }
00260   m_FirstNonDefault = f;
00261   m_LastNonDefault = l;
00262 }
00263 
00264 nodeid_t BMLookup::Lookup(nodeid_t t)
00265 {
00266 nodeid_t r;
00267 
00268   if (t < m_FirstNonDefault) return(m_Default);
00269   if (t > m_LastNonDefault ) return(m_Default);
00270   if (!m_pBitMap) return(NODE_NONE);
00271   u_long i = m_pBitMap->Get(t - m_FirstNonDefault); // Lookup neighbor index
00272   r = m_NVec[i];
00273   if(0)printf("BLookup lookedup entry %ld ind %ld, found %ld\n",
00274          t - m_FirstNonDefault, i, r);
00275   return(r);
00276 }
00277 
00278 size_t   BMLookup::Size()
00279 {
00280   return sizeof(nodeid_t) + //m_Default
00281          sizeof(nodeid_t) + // m_FirstNonDefault
00282          sizeof(nodeid_t) + // m_LastNonDefault)
00283          sizeof(BitMap*)  + // m_pBitMap)
00284          m_pBitMap->Size() + 
00285          sizeof(RoutingVec_t) + // m_NVec)
00286          sizeof(nodeid_t)*m_NVec.size();    // items in m_NVec
00287 }
00288 
00289 size_t   BMLookup::NumberEntries()
00290 {
00291   return(m_LastNonDefault - m_FirstNonDefault -1 );
00292 }
00293 
00294 size_t   BMLookup::EstimateSize(
00295     RoutingVec_t& r,   // NextHop table
00296     RoutingVec_t& p,   // Population counts
00297     nodeid_t d,        // Default route
00298     nodeid_t n,        // Number default
00299     nodeid_t o,
00300     nodeid_t f,
00301     nodeid_t l)
00302 {
00303 unsigned int i;
00304 unsigned int k = 0;
00305   // Count non-zero entries in pop vector
00306   for (i = 0; i < p.size(); i++)
00307     if (p[i]) k++;
00308 
00309   u_long c = l - f + 1; // How many entries we need
00310   return sizeof(nodeid_t) + //m_Default
00311          sizeof(nodeid_t) + // m_FirstNonDefault
00312          sizeof(nodeid_t) + // m_LastNonDefault)
00313          sizeof(BitMap*)  + // m_pBitMap)
00314          BitMap::EstimateSize(c, BitMap::FindBPE(k)) +
00315          sizeof(RoutingVec_t) + // m_NVec)
00316          sizeof(nodeid_t)*k;    // items in m_NVec
00317 }
00318 
00319 void BMLookup::Log( ostream& os)
00320 {
00321 RoutingVec_it i;
00322 
00323   os << " " << (int)WhatType();
00324   os << " " << m_Default;
00325   os << " " << m_FirstNonDefault;
00326   os << " " << m_LastNonDefault;
00327   os << " " << m_NVec.size();
00328   for (i = m_NVec.begin(); i != m_NVec.end(); i++)
00329     {
00330       os << " " << *i;
00331     }
00332   m_pBitMap->Log(os);
00333 }
00334 
00335 // Hashmap routing methods
00336 
00337 HMLookup::HMLookup() : m_Default(NODE_NONE)
00338 {
00339   if(0)printf("Created HMLookup\n");
00340 }
00341 
00342 HMLookup::~HMLookup()
00343 {
00344 }
00345 
00346 RLookup_Types HMLookup::WhatType(void) const // Identifies the type of lookup
00347 {
00348   return RL_HASH;
00349 }
00350 
00351 void HMLookup::Populate(
00352     RoutingVec_t& r, // NextHop table
00353     RoutingVec_t&,   // Population counts
00354     nodeid_t d,      // Default route
00355     nodeid_t,
00356     nodeid_t,
00357     nodeid_t)
00358 {
00359   unsigned int i;
00360 
00361   m_Default = d; // Set the default route
00362   for (i = 0; i < r.size(); i++)
00363     {
00364       if (r[i] != d && r[i] != NODE_NONE)
00365         { // Not the default, create a HT entry
00366 #ifdef CHANGED_DUE_TO_FREEBSD_PROB
00367           RoutePair_t* p = new RoutePair_t(i, r[i]);
00368           m_RouteMap.insert(*p);
00369 #else
00370           RoutePair_t p = RoutePair_t(i, r[i]);
00371           m_RouteMap.insert(p);
00372 #endif
00373         }
00374     }
00375 }
00376 
00377 nodeid_t HMLookup::Lookup(nodeid_t t)
00378 {
00379   RouteMap_it i;
00380 
00381   i = m_RouteMap.find(t);
00382   if (i == m_RouteMap.end()) return(m_Default);
00383   return((*i).second);
00384 }
00385 
00386 size_t   HMLookup::Size( void )
00387 {
00388   return sizeof(u_long) +      // m_Default
00389          sizeof(RouteMap_t) +  // m_RouteMap
00390          m_RouteMap.size() * sizeof(nodeid_t); // entries in hash table
00391 }
00392 
00393 size_t   HMLookup::NumberEntries()
00394 {
00395   return(m_RouteMap.size());
00396 }
00397 
00398 size_t   HMLookup::EstimateSize(
00399     RoutingVec_t& r, // NextHop table
00400     RoutingVec_t& p, // Population counts
00401     nodeid_t d,      // Default route
00402     nodeid_t n,      // Number default
00403     nodeid_t,
00404     nodeid_t,
00405     nodeid_t)
00406 {
00407   return sizeof(u_long) +      // m_Default
00408          sizeof(RouteMap_t) +  // m_RouteMap
00409          (r.size() - d) * sizeof(nodeid_t); // entries in hash table
00410 }
00411 
00412 void HMLookup::Log( ostream& os)
00413 {
00414 RouteMap_it i;
00415 
00416   os << " " << (int)WhatType();
00417   os << " " << m_Default;
00418   for (i = m_RouteMap.begin(); i != m_RouteMap.end(); i++)
00419     {
00420       os << " " << (*i).first << " " << (*i).second;
00421     }
00422 }
00423 
00424 // NextHop (inefficient) routing methods
00425 
00426 NHLookup::NHLookup()
00427 {
00428   if(0)printf("Created NHLookup\n");
00429 }
00430 
00431 NHLookup::~NHLookup()
00432 {
00433 }
00434 
00435 RLookup_Types NHLookup::WhatType(void) const // Identifies the type of lookup
00436 {
00437   return RL_NEXTHOP;
00438 }
00439 
00440 void NHLookup::Populate(
00441     RoutingVec_t& r, // NextHop table
00442     RoutingVec_t&,   // Population counts
00443     nodeid_t d,      // Default route
00444     nodeid_t,
00445     nodeid_t,
00446     nodeid_t)
00447 {
00448   unsigned int i;
00449 
00450   // Just copy the routing vector
00451   for (i = 0; i < r.size(); i++)
00452     {
00453       m_RouteTable.push_back(r[i]);
00454     }
00455 }
00456 
00457 void NHLookup::Populate(istream& is)
00458 { // Populate from log flie
00459 int count;
00460 
00461   is >> count;
00462   for (int i = 0; i < count; i++)
00463     {
00464       int j;
00465       is >> j;
00466       nodeid_t n;
00467       n = (j < 0) ? NODE_NONE : (nodeid_t)j;
00468       m_RouteTable.push_back(n);
00469     }
00470 }
00471 
00472 nodeid_t NHLookup::Lookup(nodeid_t t)
00473 {
00474   if (t >= m_RouteTable.size()) return(NODE_NONE);
00475   return(m_RouteTable[t]); // Just a table lookup
00476 }
00477 
00478 size_t   NHLookup::Size( void )
00479 {
00480   return sizeof(u_long) * m_RouteTable.size();
00481 }
00482 
00483 size_t   NHLookup::NumberEntries()
00484 {
00485   return(m_RouteTable.size());
00486 }
00487 
00488 void NHLookup::Log( ostream& os)
00489 {
00490 RoutingVec_it i;
00491 
00492   os << " " << (int)WhatType();
00493   os << " " << m_RouteTable.size();
00494   for (i = m_RouteTable.begin(); i != m_RouteTable.end(); i++)
00495     {
00496       if (*i == NODE_NONE)
00497         os << " " << -1; // The NODE_NONE representation is hard to read
00498       else
00499         os << " " << *i;
00500     }
00501 }
00502 
00503 size_t   NHLookup::EstimateSize(
00504     RoutingVec_t& r, // NextHop table
00505     RoutingVec_t&,   // Population counts
00506     nodeid_t d,      // Default route
00507     nodeid_t,
00508     nodeid_t,
00509     nodeid_t,
00510     nodeid_t)
00511 {
00512   return sizeof(u_long) * r.size();
00513 }
00514 
00515 #endif /* STL */

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