00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052 #include "config.h"
00053 #ifdef HAVE_STL
00054
00055
00056
00057
00058
00059 #include <stdio.h>
00060 #include <assert.h>
00061
00062 #include "routealgo/rbitmap.h"
00063
00064 #ifndef TEST_BM
00065 BitMap::BitMap() : m_Size(0), m_BPE(0), m_Words(0), m_EPW(0), m_pM(0)
00066 {
00067 }
00068
00069 BitMap::BitMap( u_long Size, u_long BitsPerEntry)
00070 : m_Size(Size), m_BPE(BitsPerEntry)
00071 {
00072 m_EPW = BITS_ULONG / BitsPerEntry;
00073 m_Words = (Size + m_EPW - 1) / m_EPW;
00074 if(0)printf("Hello from bitmap constructor size %ld bpe %ld epw %d m_Words %ld\n",
00075 Size, BitsPerEntry, m_EPW, m_Words);
00076 if (m_Words > 1)
00077 {
00078 m_pM = new u_long[m_Words];
00079 for (u_long i = 0; i < m_Words; i++) m_pM[i] = 0;
00080 }
00081 else
00082 {
00083 m_pM = (u_long*)(0);
00084 }
00085 if(0)printf("Exiting bitmap constructor\n");
00086 }
00087
00088
00089
00090
00091
00092
00093 void BitMap::Set(u_long Which, u_long Value)
00094 {
00095 u_long* pW;
00096 u_long Mask;
00097 short Shift;
00098
00099 pW = GetWordAddress(Which);
00100 Mask = GetBitMask(Which);
00101 Shift = GetShiftCount(Which);
00102 *pW &= (~Mask);
00103 *pW |= (Value << Shift);
00104 }
00105
00106 void BitMap::Clear(u_long Which)
00107 {
00108 u_long* pW;
00109 u_long Mask;
00110
00111 pW = GetWordAddress(Which);
00112 Mask = GetBitMask(Which);
00113 *pW &= (~Mask);
00114 }
00115
00116 u_long BitMap::Get(u_long Which)
00117 {
00118 u_long* pW;
00119 u_long Mask;
00120 short Shift;
00121 u_long r;
00122
00123 pW = GetWordAddress(Which);
00124 Mask = GetBitMask(Which);
00125 Shift = GetShiftCount(Which);
00126 if(0)printf("Get which %ld Mask %08lx Shift %d\n", Which, Mask, Shift);
00127 r = *pW;
00128
00129 r &= (Mask);
00130 return (r >> Shift);
00131 }
00132
00133
00134
00135
00136 u_long* BitMap::GetWordAddress(
00137 u_long Which)
00138 {
00139 u_long ind;
00140
00141 Validate(Which);
00142 ind = Which / m_EPW;
00143 if (m_Words == 1)
00144 {
00145 return((u_long*)&m_pM);
00146 }
00147 return(&m_pM[ind]);
00148 }
00149
00150 u_long BitMap::GetBitMask(
00151 u_long Which)
00152 {
00153 long m;
00154 short c;
00155 u_long um;
00156
00157 m = 0x80000000;
00158 m >>= (m_BPE - 1);
00159 c = GetShiftCount(Which);
00160 um = m;
00161 um = um >> (32 - (c + m_BPE));
00162 if(0)printf("Get Bit Mask m %08lx shifted m %08lx\n", m, um);
00163 return(um);
00164 }
00165
00166
00167 short BitMap::GetShiftCount(
00168 u_long Which)
00169 {
00170 u_long ind;
00171 short left;
00172
00173 Validate(Which);
00174 ind = Which / m_EPW;
00175 left = Which - (ind * m_EPW);
00176 return(left * m_BPE);
00177 }
00178
00179 void BitMap::Validate(u_long Which)
00180 {
00181 assert (Which < m_Size);
00182 }
00183
00184
00185 size_t BitMap::Size( void )
00186 {
00187 size_t r;
00188
00189 r = sizeof(u_long*) +
00190 sizeof(u_long) +
00191 sizeof(u_long) +
00192 sizeof(u_long) +
00193 sizeof(short);
00194 if (m_Size * m_BPE > BITS_ULONG)
00195 r += ((m_Size * m_BPE) + BITS_ULONG - 1 / BITS_ULONG) *
00196 sizeof(u_long) ;
00197 return(r);
00198 }
00199
00200 void BitMap::DBPrint()
00201 {
00202 printf("Size %ld BPE %ld Words %ld EPW %d\n", m_Size, m_BPE, m_Words, m_EPW);
00203 if (m_Words == 1)
00204 {
00205 printf("Word 0 %08lx\n", (u_long)m_pM);
00206 }
00207 else
00208 {
00209 for (u_long i = 0; i < m_Words; i++)
00210 printf("Word %ld %08lx\n", i, m_pM[i]);
00211 }
00212 }
00213
00214 u_long BitMap::FindBPE( u_long m )
00215 {
00216 u_long bpe = 32;
00217 u_long k = 0x80000000;
00218
00219 while(k)
00220 {
00221 if (m & k) return(bpe);
00222 bpe--;
00223 k >>= 1;
00224 }
00225 return(0);
00226 }
00227
00228 size_t BitMap::EstimateSize( u_long Size, u_long BitsPerEntry)
00229 {
00230 size_t r;
00231
00232 r = sizeof(u_long*) +
00233 sizeof(u_long) +
00234 sizeof(u_long) +
00235 sizeof(u_long) +
00236 sizeof(short);
00237 if (Size * BitsPerEntry > BITS_ULONG)
00238 r += ((Size * BitsPerEntry) + BITS_ULONG - 1 / BITS_ULONG) *
00239 sizeof(u_long) ;
00240 return (r);
00241 }
00242
00243 void BitMap::Log( ostream& os)
00244 {
00245 os << " " << m_Size;
00246 os << " " << m_BPE;
00247 os << " " << m_Words;
00248 os << " " << m_EPW;
00249 if (m_Words == 1)
00250 {
00251 os << " " << hex << (unsigned long)m_pM << dec;
00252 }
00253 else
00254 {
00255 for (unsigned int i = 0; i < m_Words; i++)
00256 os << " " << hex << m_pM[i] << dec;
00257 }
00258 }
00259
00260 #endif
00261
00262 #ifdef TEST_BM
00263 int main()
00264 {
00265 BitMap B(64);
00266 BitMap B2(64, 2);
00267 BitMap B3(64, 3);
00268
00269 B.DBPrint();
00270 B.Set(0);
00271 B.DBPrint();
00272 printf("Entry 0 is %ld\n", B.Get(0));
00273 B.Set(31);
00274 B.DBPrint();
00275 B.Set(32);
00276 B.DBPrint();
00277 B.Set(63);
00278 B.DBPrint();
00279
00280 B2.DBPrint();
00281 B2.Set(0, 1);
00282 B2.DBPrint();
00283 B2.Set(31, 2);
00284 B2.DBPrint();
00285 B2.Set(32, 2);
00286 B2.DBPrint();
00287 B2.Set(63, 3);
00288 B2.DBPrint();
00289
00290 B3.DBPrint();
00291 B3.Set(0, 1);
00292 B3.DBPrint();
00293 B3.Set(31, 2);
00294 B3.DBPrint();
00295 B3.Set(32, 2);
00296 B3.DBPrint();
00297 B3.Set(63, 7);
00298 B3.DBPrint();
00299
00300 }
00301 #endif
00302
00303 #endif