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

通讯编程

开发平台:

Visual C++

  1. /*
  2.  * nixvec.cc
  3.  * Copyright (C) 2000 by the University of Southern California
  4.  * $Id: nixvec.cc,v 1.5 2005/08/25 18:58:10 johnh 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.  * Support for NixVector routing
  47.  * contributed to ns from 
  48.  * George F. Riley, Georgia Tech, Spring 2000
  49.  *
  50.  */
  51. #include "config.h"
  52. #ifdef HAVE_STL
  53. #include <string.h> // for memcpy
  54. #include <stdio.h>
  55. #include "nix/nixvec.h"
  56. #ifndef TEST_NIXVEC
  57. // Constructor from existing
  58. NixVec::NixVec(NixVec* p) : m_used(0), m_alth(p->m_alth)
  59. {
  60.   if (Lth() > NIX_BPW)
  61.     { // Need to allocate storage
  62.       m_pNV = new Nix_t[Lth() / NIX_BPW];
  63.       memcpy(m_pNV, p->m_pNV, Lth()/8);
  64.     }
  65.   else
  66.     { // Just use the pointer
  67.       m_pNV = p->m_pNV;
  68.     }
  69. }
  70. NixVec::~NixVec()
  71. { // Destructor 
  72.   if(0)printf("Hello from nixvec destructorn");
  73.   if (Lth() > NIX_BPW) delete [] m_pNV;  // Delete the allocated memory
  74. }
  75. void NixVec::Add( NixPair_t p)
  76. { // Add some bits to the nix vector
  77.   Nixl_t newused;
  78.   Nix_t  newbits;
  79.   Nixl_t newlth;
  80.   if (p.second == 0) return; // Not really possible!
  81. #ifdef NEED_DEBUG
  82.   // debug follows
  83.   Nix_t db;
  84.   if (Lth() == NIX_BPW)
  85.     db = (Nix_t)m_pNV;
  86.   else
  87.     db = m_pNV[0];
  88.   db = ((db & 0xfffffff0) ^ 0x00038520);
  89.   if (!db)
  90.     {
  91.       printf("Adding %ld lth %ldn", p.first, p.second);
  92.       DBDump();
  93.     }
  94.   // end debug
  95. #endif
  96.   newused = m_used + p.second;
  97.   if (newused > Lth())
  98.     { // Need more room
  99.       newlth = Lth() + NIX_BPW;
  100.       Nix_t* pNew = new Nix_t[newlth / NIX_BPW];
  101.       if (Lth() == NIX_BPW)
  102.         { // Old is not pointer, just transfer
  103.           pNew[0] = (Nix_t)m_pNV;
  104.         }
  105.       else
  106.         {
  107.           for (unsigned long k = 0; k < Lth() / NIX_BPW; k++)
  108.             pNew[k] = m_pNV[k];
  109.         }
  110.       pNew[newlth / NIX_BPW - 1] = 0;
  111.       if (Lth() != NIX_BPW)
  112.         delete [] m_pNV;
  113.       m_pNV = pNew;
  114.       if (m_used == Lth())
  115.         { // No overlap, just use the new entry
  116.           newbits = p.first << (NIX_BPW - m_used + (newlth - 32)  - p.second);
  117.           Nixl_t i = (m_used / NIX_BPW);
  118.           m_pNV[i] |= newbits;
  119.         }
  120.       else
  121.         {
  122.           // Fill in remaining of previous word
  123.           Nixl_t left = Lth() - m_used;
  124.           newbits = p.first >> (p.second - left);
  125.           Nixl_t i = (m_used / NIX_BPW);
  126.           m_pNV[i] |= newbits;
  127.           // And the next word
  128.           newbits = p.first << (NIX_BPW - (p.second - left));
  129.           i = (m_used / NIX_BPW) + 1;
  130.           m_pNV[i] |= newbits;
  131.         }
  132.       //     Lth() = newlth;
  133.     }
  134.   else
  135.     {
  136.       newbits = p.first << (NIX_BPW - m_used + (Lth() - 32)  - p.second);
  137.       if (Lth() == NIX_BPW)
  138.         { // Not a pointer, just the vector
  139.           Nix_t n = (Nix_t)m_pNV;
  140.           n |= newbits;
  141.           m_pNV = (Nix_t*)n;
  142.         }
  143.       else
  144.         { // Pointer, find the correct index
  145.           Nixl_t i = (m_used / NIX_BPW);
  146.           m_pNV[i] |= newbits;
  147.         }
  148.     }
  149.   m_used = newused;
  150.   if (m_used > m_alth) m_alth = m_used;
  151. #ifdef NEED_DEBUG
  152.   if (!db)
  153.     {
  154.       printf("Added  %ld lth %ldn", p.first, p.second);
  155.       DBDump();
  156.     }
  157. #endif
  158. }
  159. Nix_t NixVec::Extract(Nixl_t n)
  160. { // Extract using built in "m_used"
  161.   return(Extract(n, &m_used));
  162. }
  163. Nix_t NixVec::Extract(Nixl_t n, Nixl_t* pUsed)
  164. { // Get the next "n" bits from the vec
  165.   Nixl_t used = *pUsed;
  166.   
  167.   Nixl_t word = used / NIX_BPW;
  168.   Nixl_t bit  = used - (word * NIX_BPW);
  169.   long  m     = 0x80000000; // n bit mask
  170.   Nix_t  w;
  171.   if(0)printf("Extracting %ld bits, used %ld lth %ld alth %ldn", 
  172.          n, used, Lth(), m_alth);
  173.    if ((used + n) > m_alth) return(NIX_NONE); // Overflow
  174.    if ((bit + n) <= NIX_BPW)
  175.      { // Simple case
  176.        if (Lth() == NIX_BPW)
  177.          w = (long)m_pNV;
  178.        else
  179.          w = m_pNV[word];
  180.        m >>= (n-1); // n bit mask
  181.        Nix_t u = (Nix_t)m;
  182.        u >>= bit;   // position mask
  183.        w &= u;      // extract the bits
  184.        w >>= (NIX_BPW - bit - n);
  185.      }
  186.    else
  187.      { // spans a word
  188.        if (Lth() == NIX_BPW)
  189.          w = (long)m_pNV;
  190.        else
  191.          w = m_pNV[word];
  192.        Nixl_t t = NIX_BPW - bit; // Number bits in first word
  193.        m >>= (t-1); // n bit mask
  194.        Nix_t u = (Nix_t)m;
  195.        u >>= bit;   // position mask
  196.        w &= u;
  197.        t = n - t;   // number bits in second word
  198.        w <<= t;
  199.        m = 0x80000000; // n bit mask
  200.        m >>= (t-1);
  201.        w |= (m_pNV[word+1] >> (NIX_BPW - t));
  202.      }
  203.    used += n;
  204.    *pUsed = used; // Return advanced
  205.    return(w);
  206. }
  207. void NixVec::DBDump()
  208. {
  209.   printf("Lth %3ld ActualLth %3ld Used %3ld ", Lth(), ALth(), m_used);
  210.   if (Lth() == NIX_BPW)
  211.     { // print the lone value
  212.       printf("val[0] %08lxn", (unsigned long)m_pNV);
  213.     }
  214.   else
  215.     {
  216.       printf("val[0] %08lxn", m_pNV[0]);
  217.       for (unsigned long i = 1; i < Lth() / NIX_BPW; i++)
  218.         printf("                 val[%ld] %08lxn", i, m_pNV[i]);
  219.     }
  220. }
  221. void NixVec::Reset()
  222. {
  223.   m_used = 0; // Reset to beginning
  224. }
  225. // Static functions
  226. Nixl_t NixVec::GetBitl( Nixl_t l)
  227. { // Find out how many bits needed
  228.   int h = 31; // highest bit number set
  229.   // Find a good starting point
  230.   if ((l & 0xFFFF0000) == 0)
  231.     {
  232.       if (l & 0xFFFFFF00 == 0)
  233.         {
  234.           h = 7;
  235.         }
  236.       else
  237.         {
  238.           h = 15;
  239.         }
  240.     }
  241.   while(h > 0)
  242.     {
  243.       Nixl_t m = 0x1L << h;
  244.       if (m & l)
  245.         { // Found highest bit
  246.           return(h+1);
  247.         }
  248.       h--;
  249.     }
  250.   return(1);
  251. }
  252. Nixl_t NixVec::Lth()
  253. { // Compute the length in bits of maximum allocated size
  254.   if (m_alth == 0) return (NIX_BPW); // Empty vector, can use up to 32
  255.   return((((m_alth - 1) / NIX_BPW) + 1) * NIX_BPW);
  256. }
  257. #endif
  258. #ifdef TEST_NIXVEC
  259. int main()
  260. {
  261.   NixVec n;
  262.   NixVec n1;
  263.   NixVec n2;
  264.   int    i;
  265.   // test the nixvector generator
  266.   for (i = 0; i < NIX_BPW-1; i++)
  267.     {
  268.       n.Add(NixPair_t(1, 1));
  269.     } 
  270.   n.Add(NixPair_t(2, 2));
  271.   n.Add(NixPair_t(1, 1));
  272.   n.DBDump();
  273.   //  exit(1);
  274.   n.Reset();
  275.   for (i = 0; i < NIX_BPW; i++)
  276.     {
  277.       n.Add(NixPair_t(1, 1));
  278.       n.Add(NixPair_t(0, 1));
  279.       n.DBDump();
  280.     } 
  281.   n.Reset();
  282.   for (i = 0; i < NIX_BPW*2; i++)
  283.     {
  284.       Nix_t v = n.Extract(1);
  285.       printf("V0 = %lxn", v);
  286.     }
  287.   for (i = 0; i < 16; i++)
  288.     {
  289.       n1.Add(NixPair_t(i, 4));
  290.       n1.DBDump();
  291.     }
  292.   n1.Reset();
  293.   for (i = 0; i < 16; i++)
  294.     {
  295.       Nix_t v = n1.Extract(4);
  296.       printf("V1 = %lxn", v);
  297.     }
  298.   for (i = 0; i < 8; i++)
  299.     {
  300.       n2.Add(NixPair_t(0xfe0 + i, 12));
  301.       n2.DBDump();
  302.     }
  303.   n2.Reset();
  304.   while(1)
  305.     {
  306.       Nix_t v = n2.Extract(12);
  307.       if (v == NIX_NONE) break;
  308.       printf("V2 = %lxn", v);
  309.     }
  310. }
  311. #endif
  312. #endif /* STL */