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

通讯编程

开发平台:

Visual C++

  1. /*
  2.  * rbitmap.cc
  3.  * Copyright (C) 2000 by the University of Southern California
  4.  * $Id: rbitmap.cc,v 1.5 2005/08/25 18:58:11 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.  * Define a bitmap object
  47.  * contributed to ns
  48.  * George Riley, Georgia Tech, Winter 2000
  49.  */
  50. #include "config.h"
  51. #ifdef HAVE_STL
  52. // Creates a bitmap object.  The 'entries' can be more than one bit,
  53. // but default to one bit.  Bits per entry can't be more than 32.
  54. // Entries DO NOT span words, for ease of coding
  55. #include <stdio.h>
  56. #include <assert.h>
  57. #include "routealgo/rbitmap.h"
  58. #ifndef TEST_BM
  59. BitMap::BitMap() :  m_Size(0), m_BPE(0), m_Words(0), m_EPW(0), m_pM(0)
  60. { // Default constructor ...used only to input from log file
  61. }
  62. BitMap::BitMap( u_long Size, u_long BitsPerEntry)
  63.   : m_Size(Size), m_BPE(BitsPerEntry)
  64. {
  65.   m_EPW = BITS_ULONG / BitsPerEntry; // Entries per word
  66.   m_Words = (Size + m_EPW - 1) / m_EPW;
  67.   if(0)printf("Hello from bitmap constructor size %ld bpe %ld epw %d m_Words %ldn",
  68.          Size, BitsPerEntry, m_EPW, m_Words);
  69.   if (m_Words > 1)
  70.     {
  71.       m_pM = new u_long[m_Words];
  72.       for (u_long i = 0; i < m_Words; i++) m_pM[i] = 0;
  73.     }
  74.   else
  75.     {
  76.       m_pM = (u_long*)(0);
  77.     }
  78.   if(0)printf("Exiting bitmap constructorn");
  79. }
  80. /*BitMap::~BitMap()
  81. {
  82.   if (m_Words > 1) delete [] m_pM;
  83. }*/
  84. void BitMap::Set(u_long Which, u_long Value)
  85. {
  86. u_long* pW;
  87. u_long  Mask;
  88. short   Shift;
  89.   pW    = GetWordAddress(Which);
  90.   Mask  = GetBitMask(Which);
  91.   Shift = GetShiftCount(Which);
  92.   *pW  &= (~Mask); // Clear existing bits
  93.   *pW  |= (Value << Shift);
  94. }
  95. void BitMap::Clear(u_long Which)
  96. {
  97. u_long* pW;
  98. u_long  Mask;
  99.   pW    = GetWordAddress(Which);
  100.   Mask  = GetBitMask(Which);
  101.   *pW  &= (~Mask); // Clear existing bits
  102. }
  103. u_long BitMap::Get(u_long Which)
  104. {
  105. u_long* pW;
  106. u_long  Mask;
  107. short   Shift;
  108. u_long  r;
  109.   pW    = GetWordAddress(Which);
  110.   Mask  = GetBitMask(Which);
  111.   Shift = GetShiftCount(Which);
  112.   if(0)printf("Get which %ld Mask %08lx Shift %dn", Which, Mask, Shift);
  113.   r = *pW;
  114.   r  &= (Mask); // get existing bits
  115.   return (r >> Shift);
  116. }
  117. // Private subroutines
  118. u_long* BitMap::GetWordAddress(
  119.     u_long Which) // Get a pointer to the word needed
  120. {
  121. u_long ind;
  122.  Validate(Which);
  123.  ind = Which / m_EPW; 
  124.  if (m_Words == 1)
  125.    { // not indirected
  126.      return((u_long*)&m_pM);
  127.    }
  128.  return(&m_pM[ind]);
  129. }
  130. u_long BitMap::GetBitMask( // Get a bit mask to the needed bits
  131.     u_long Which)
  132. {
  133. long  m;
  134. short c;
  135. u_long um;
  136.   m = 0x80000000;
  137.   m >>= (m_BPE - 1);
  138.   c = GetShiftCount(Which);
  139.   um = m;
  140.   um = um >> (32 - (c + m_BPE));
  141.   if(0)printf("Get Bit Mask m %08lx shifted m %08lxn", m, um);
  142.   return(um);
  143. }
  144. short BitMap::GetShiftCount( // Get a shift count for position
  145.     u_long Which)  
  146. {
  147. u_long ind;
  148. short  left;
  149.  Validate(Which);
  150.  ind = Which / m_EPW; 
  151.  left = Which - (ind * m_EPW);  // Entry number in the actual word
  152.  return(left * m_BPE);
  153. }
  154. void    BitMap::Validate(u_long Which)// Validate which not too large
  155. {
  156.   assert (Which < m_Size);
  157. }
  158. size_t BitMap::Size( void )
  159. {
  160.   size_t r;
  161.   r = sizeof(u_long*) + // m_pM
  162.       sizeof(u_long) + // m_Size
  163.       sizeof(u_long) + // m_BPE
  164.       sizeof(u_long) + // m_Words
  165.       sizeof(short); // m_EPW
  166.   if (m_Size * m_BPE > BITS_ULONG)
  167.     r += ((m_Size * m_BPE) + BITS_ULONG - 1 / BITS_ULONG) * 
  168.          sizeof(u_long) ; // Account for the actual map
  169.   return(r);
  170. }
  171. void BitMap::DBPrint()
  172. {
  173.   printf("Size %ld BPE %ld Words %ld EPW %dn", m_Size, m_BPE, m_Words, m_EPW);
  174.   if (m_Words == 1)
  175.     {
  176.       printf("Word 0 %08lxn", (u_long)m_pM);
  177.     }
  178.   else
  179.     {
  180.       for (u_long i = 0; i < m_Words; i++)
  181.         printf("Word %ld %08lxn", i, m_pM[i]);
  182.     }
  183. }
  184. u_long BitMap::FindBPE( u_long m ) // Find how many bits/entry we need
  185. {
  186.   u_long bpe = 32;
  187.   u_long k = 0x80000000;
  188.   while(k)
  189.     {
  190.       if (m & k) return(bpe);
  191.       bpe--;
  192.       k >>= 1;
  193.     }
  194.   return(0);
  195. }
  196. size_t BitMap::EstimateSize( u_long Size, u_long BitsPerEntry)
  197. {
  198.   size_t r;
  199.   r = sizeof(u_long*) + // m_pM
  200.       sizeof(u_long) + // m_Size
  201.       sizeof(u_long) + // m_BPE
  202.       sizeof(u_long) + // m_Words
  203.       sizeof(short); // m_EPW
  204.   if (Size * BitsPerEntry > BITS_ULONG)
  205.     r += ((Size * BitsPerEntry) + BITS_ULONG - 1 / BITS_ULONG) * 
  206.          sizeof(u_long) ; // Account for the actual map
  207.   return (r);
  208. }
  209. void BitMap::Log( ostream& os)
  210. {
  211.   os << " " << m_Size;
  212.   os << " " << m_BPE;
  213.   os << " " << m_Words;
  214.   os << " " << m_EPW;
  215.   if (m_Words == 1)
  216.     { // Not a pointer, but the actual map
  217.       os << " " << hex << (unsigned long)m_pM << dec;
  218.     }
  219.   else
  220.     {
  221.       for (unsigned int i = 0; i < m_Words; i++)
  222.         os << " " << hex << m_pM[i] << dec;
  223.     }
  224. }
  225. #endif
  226. #ifdef TEST_BM
  227. int main()
  228. {
  229. BitMap B(64);
  230. BitMap B2(64, 2);
  231. BitMap B3(64, 3);
  232.   B.DBPrint();
  233.   B.Set(0);
  234.   B.DBPrint();
  235.   printf("Entry 0 is %ldn", B.Get(0));
  236.   B.Set(31);
  237.   B.DBPrint();
  238.   B.Set(32);
  239.   B.DBPrint();
  240.   B.Set(63);
  241.   B.DBPrint();
  242.   B2.DBPrint();
  243.   B2.Set(0, 1);
  244.   B2.DBPrint();
  245.   B2.Set(31, 2);
  246.   B2.DBPrint();
  247.   B2.Set(32, 2);
  248.   B2.DBPrint();
  249.   B2.Set(63, 3);
  250.   B2.DBPrint();
  251.   B3.DBPrint();
  252.   B3.Set(0, 1);
  253.   B3.DBPrint();
  254.   B3.Set(31, 2);
  255.   B3.DBPrint();
  256.   B3.Set(32, 2);
  257.   B3.DBPrint();
  258.   B3.Set(63, 7);
  259.   B3.DBPrint();
  260. }
  261. #endif
  262. #endif /* STL */