#include <BitMap.h>
Public Member Functions | |
BitMap () | |
~BitMap () | |
int | Initialize (char *BitMapFileName, unsigned int nBits, ostream *LogStream) |
int | Format () |
int | Load () |
int | Reset () |
int | Confirm () |
int | Close () |
int | AllocSeq (unsigned int Startbit, unsigned int *Bit) |
void | Free (unsigned int Bit) |
unsigned int | nFree () |
Private Member Functions | |
void | ifreestg () |
int | iclose () |
unsigned int | CountnFree () |
bool | TestBit (const unsigned int Bit) |
void | SetBit (const unsigned int Bit) |
void | ClearBit (const unsigned int Bit) |
unsigned int | CountFreeBits (const int Byte) |
Private Attributes | |
char * | m_FileName |
unsigned int | m_nBits |
unsigned int | m_nFree |
unsigned int | m_nFreeConfirmed |
unsigned int | m_nBytes |
unsigned char * | m_BitMap |
int | m_handle |
ostream * | m_log |
bool | m_changed |
Definition at line 29 of file BitMap.h.
BitMap::BitMap | ( | ) |
Definition at line 50 of file BitMap.cpp.
BitMap::~BitMap | ( | ) |
Definition at line 63 of file BitMap.cpp.
int BitMap::AllocSeq | ( | unsigned int | Startbit, | |
unsigned int * | Bit | |||
) |
Definition at line 311 of file BitMap.cpp.
00312 { 00313 if( m_nFree <= 0 ) 00314 { 00315 return ERROR_BITMAP + 1; 00316 } 00317 00318 if( Startbit >= m_nBits ) 00319 { 00320 abort(); // caller logic error, Startbit out of range 00321 } 00322 00323 unsigned int x = Startbit; 00324 int off; 00325 unsigned int BitCount = 0; 00326 00327 while( 1 ) 00328 { 00329 // Check if been all the way around (Give 8 extra bits 00330 // to account for possible unused bits at end of BitMap) 00331 if( BitCount > ( m_nBits + 8 ) ) 00332 break; 00333 if( x >= m_nBits ) // wrap bit table 00334 x = 0; 00335 off = x >> 3; 00336 00337 // optimization: skip to next byte if all bits are used 00338 // in current byte 00339 if( m_BitMap[off] == 0xff ) 00340 { 00341 x = ( off + 1 ) << 3; 00342 BitCount += 8; 00343 } 00344 else 00345 { 00346 if( !TestBit( x ) ) 00347 { 00348 SetBit( x ); 00349 *Bit = x; 00350 m_changed = true; 00351 m_nFree--; 00352 return 0; 00353 } 00354 x++; 00355 BitCount++; 00356 } 00357 } 00358 00359 // no free bits found 00360 // This should not happen, as m_nFree above claimed some were 00361 // available 00362 *m_log << "BitMap::AllocSeq(): no free bits found for " 00363 << m_FileName << " (UNEXPECTED ERROR)" << endl; 00364 return ERROR_BITMAP + 2; 00365 }
void BitMap::ClearBit | ( | const unsigned int | Bit | ) | [private] |
Definition at line 415 of file BitMap.cpp.
00416 { 00417 int mask = 0x80 >> ( Bit & 7 ); 00418 int off = Bit >> 3; 00419 m_BitMap[off] &= ~mask; 00420 }
int BitMap::Close | ( | ) |
int BitMap::Confirm | ( | ) |
Definition at line 284 of file BitMap.cpp.
00285 { 00286 // If there was any change in bit map, update file 00287 if( m_changed ) 00288 { 00289 // Start writing from file begining 00290 lseek( m_handle, 0, SEEK_SET ); 00291 unsigned int nBytes; 00292 // Write bit map to file 00293 nBytes = write( m_handle, m_BitMap, m_nBytes ); 00294 if( ( nBytes != ( unsigned int ) m_nBytes ) ) 00295 { 00296 (*m_log) << "BitMap::Flush(): Error writing bitmap file " 00297 << m_FileName << "\n SYSTEM ERROR: " << strerror(errno) 00298 << endl; 00299 return ERROR_OBJECTMANAGER + ERROR_UNEXPECTED; 00300 } 00301 // Flush OS file buffers to disk 00302 fsync( m_handle ); 00303 m_nFreeConfirmed = m_nFree; 00304 m_changed = false; 00305 } 00306 return 0; 00307 }
unsigned int BitMap::CountFreeBits | ( | const int | Byte | ) | [private] |
Definition at line 423 of file BitMap.cpp.
unsigned int BitMap::CountnFree | ( | ) | [private] |
Definition at line 386 of file BitMap.cpp.
00387 { 00388 // Count number of free bits in bitmap 00389 unsigned int count = 0; 00390 for( unsigned int i = 0;i < m_nBytes; i++ ) 00391 { 00392 count += CountFreeBits( m_BitMap[i] ); 00393 } 00394 00395 return count; 00396 }
int BitMap::Format | ( | ) |
Definition at line 146 of file BitMap.cpp.
00147 { 00148 // set all bits to not allocated (zero) 00149 memset( m_BitMap, 0, m_nBytes ); 00150 00151 // set extra bits at end of bitmap so they won't be allocated 00152 unsigned int x; 00153 for( x = m_nBits; x < ( m_nBytes << 3 ); x++ ) 00154 { 00155 SetBit( x ); 00156 } 00157 00158 // create file to store bitmap 00159 m_handle = open( m_FileName, O_RDWR | O_TRUNC | O_CREAT, 0700 ); 00160 if( m_handle == -1 ) 00161 { 00162 (*m_log) << "BitMap::Format(): " 00163 << " open create for " << m_FileName << " failed " 00164 << strerror(errno) << endl; 00165 return ERROR_OBJECTMANAGER + ERROR_SYSTEM_CONFIGURATION; 00166 } 00167 00168 // init free bit count 00169 m_nFree = CountnFree(); 00170 00171 // force write of metadata to disk 00172 m_changed = true; 00173 return Confirm(); 00174 }
void BitMap::Free | ( | unsigned int | Bit | ) |
Definition at line 368 of file BitMap.cpp.
00369 { 00370 if( TestBit( Bit ) ) 00371 { 00372 ClearBit(Bit); 00373 m_changed = true; 00374 m_nFree++; 00375 return; 00376 } 00377 00378 // terrible error -- freeing bit already free 00379 *m_log << "BitMap::Free(): Attempt to free bit already free for " 00380 << m_FileName << " bit " << Bit << endl; 00381 RioErr << "BitMap::Free(): Attempt to free bit already free for " 00382 << m_FileName << " bit " << Bit << endl; 00383 }
int BitMap::iclose | ( | ) | [private] |
Definition at line 89 of file BitMap.cpp.
00090 { 00091 if( m_handle != -1 ) 00092 { 00093 if( close( m_handle ) == -1 ) 00094 { 00095 *m_log << "BitMap::Close(): Error closing bitmap file " 00096 << m_FileName << "\n SYSTEM ERROR: " << strerror( errno ) 00097 << endl; 00098 return ERROR_OBJECTMANAGER + ERROR_UNEXPECTED; 00099 } 00100 m_handle = -1; 00101 } 00102 return 0; 00103 }
void BitMap::ifreestg | ( | ) | [private] |
Definition at line 71 of file BitMap.cpp.
00072 { 00073 if( m_BitMap != 0 ) 00074 { 00075 delete[] m_BitMap; 00076 m_BitMap = 0; 00077 } 00078 00079 if( m_FileName != 0 ) 00080 { 00081 delete[] m_FileName; 00082 m_FileName = 0; 00083 } 00084 m_nBits = m_nBytes = 0; 00085 }
int BitMap::Initialize | ( | char * | BitMapFileName, | |
unsigned int | nBits, | |||
ostream * | LogStream | |||
) |
Definition at line 106 of file BitMap.cpp.
00108 { 00109 m_log = Logstream; 00110 00111 if( nBits < 1 ) 00112 { 00113 (*m_log) << "BitMap::Initialize(): Unexpected error. " 00114 << " Number of Bits specified is less than one" 00115 << endl; 00116 return ERROR_OBJECTMANAGER + ERROR_UNEXPECTED; 00117 } 00118 00119 ifreestg(); 00120 00121 m_nBits = nBits; 00122 m_nBytes = ( m_nBits + 7 ) >> 3; 00123 m_BitMap = new unsigned char[m_nBytes]; 00124 if( m_BitMap == NULL ) 00125 { 00126 ifreestg(); 00127 return ERROR_OBJECTMANAGER + ERROR_MEMORY; 00128 } 00129 00130 // Allocate file name string 00131 m_FileName = new char [strlen( BitMapFileName ) + 1]; 00132 // Check if memory was allocated successfully 00133 if( m_FileName == NULL ) 00134 { 00135 ifreestg(); 00136 return ERROR_OBJECTMANAGER + ERROR_MEMORY; 00137 } 00138 // Update name of file with bit map 00139 strcpy( m_FileName, BitMapFileName ); 00140 00141 return 0; 00142 }
int BitMap::Load | ( | ) |
Definition at line 177 of file BitMap.cpp.
00178 { 00179 // Load bitmap from file 00180 m_handle = open( m_FileName, O_RDWR, 0 ); 00181 if( m_handle == -1 ) 00182 { 00183 RioErr << "BitMap::Load(): Could not open bitmap file " 00184 << m_FileName << " with RDWR permissions, trying to open with " 00185 << "RDONLY permission" << endl; 00186 00187 m_handle = open( m_FileName, O_RDONLY, 0 ); 00188 if( m_handle == -1 ) 00189 { 00190 // to insert new devices without 00191 // removing everything and copying it again. 00192 char answer[128] = ""; 00193 00194 do { 00195 //cout << "Would you like to insert this new device" 00196 // << " and format it? [y/n]\n"; 00197 //fgets( answer, 128, stdin ); 00198 //if( ( answer[0] == 'n' ) || ( answer[0] == 'N' ) ) 00199 RioErr << "BitMap::Load() You have to format the new disk " 00200 << " before start server. Exiting..." << endl; 00201 return ERROR_OBJECTMANAGER + ERROR_UNEXPECTED; 00202 }while(( answer[0] != 'Y' ) && ( answer[0] != 'y' )); 00203 00204 //Format the new device 00205 RioErr << " Trying to format ... " << endl; 00206 int rc2 = Format(); 00207 // preallocate block 0, 1 00208 unsigned int junk; 00209 if( !rc2 ) 00210 { 00211 rc2 = AllocSeq( 0, &junk ); 00212 } 00213 if( !rc2 ) 00214 { 00215 rc2 = AllocSeq( 1, &junk ); 00216 } 00217 if( rc2 ) 00218 { 00219 RioErr << " Error! " << endl; 00220 return ERROR_OBJECTMANAGER + ERROR_UNEXPECTED; 00221 } 00222 RioErr << " New device formatted. " << endl; 00223 Confirm(); 00224 close( m_handle ); 00225 RioErr << " Trying to open the new device." << endl; 00226 m_handle = open( m_FileName, O_RDWR, 0 ); 00227 if( m_handle == -1 ) 00228 { 00229 RioErr << "BitMap::Load(): Could not open bitmap file " 00230 << m_FileName << endl 00231 << " SYSTEM ERROR: " << strerror(errno) << endl; 00232 return ERROR_OBJECTMANAGER + ERROR_UNEXPECTED; 00233 } 00234 RioErr << " OK. " << endl; 00235 // -------------------------------------------------------------------- 00236 } 00237 } 00238 00239 unsigned int nBytes; 00240 nBytes = read( m_handle, m_BitMap, m_nBytes ); 00241 if( ( nBytes != ( unsigned int )m_nBytes ) ) 00242 { 00243 RioErr << "BitMap::Load(): Error reading bitmap file " 00244 << m_FileName << endl 00245 << " SYSTEM ERROR: " << strerror(errno) << endl; 00246 close( m_handle ); 00247 return ERROR_OBJECTMANAGER + ERROR_UNEXPECTED; 00248 } 00249 00250 // init free bit count 00251 m_nFree = CountnFree(); 00252 m_nFreeConfirmed = m_nFree; 00253 00254 m_changed = false; 00255 return 0; 00256 }
unsigned int BitMap::nFree | ( | ) | [inline] |
int BitMap::Reset | ( | void | ) |
Definition at line 260 of file BitMap.cpp.
00261 { 00262 unsigned int nBytes; 00263 // Reload bitmap from file (erasing previous updates not flushed to disk) 00264 lseek( m_handle, 0, SEEK_SET ); 00265 nBytes = read( m_handle, m_BitMap, m_nBytes ); 00266 if( ( nBytes != ( unsigned int ) m_nBytes ) ) 00267 { 00268 (*m_log) << "BitMap::Reset(): Error reading bitmap file " 00269 << m_FileName << " - " << strerror(errno) << endl; 00270 //### I'm not really sure what to do at this point 00271 //### the bitmap is probably lost... 00272 iclose(); 00273 return ERROR_OBJECTMANAGER + ERROR_UNEXPECTED; 00274 } 00275 00276 m_nFree = m_nFreeConfirmed; 00277 m_changed = false; 00278 return 0; 00279 }
void BitMap::SetBit | ( | const unsigned int | Bit | ) | [private] |
Definition at line 407 of file BitMap.cpp.
00408 { 00409 int mask = 0x80 >> ( Bit & 7 ); 00410 int off = Bit >> 3; 00411 m_BitMap[off] |= mask; 00412 }
bool BitMap::TestBit | ( | const unsigned int | Bit | ) | [private] |
Definition at line 399 of file BitMap.cpp.
00400 { 00401 int mask = 0x80 >> ( Bit & 7 ); 00402 int off = Bit >> 3; 00403 return (( m_BitMap[off] & mask ) != 0); 00404 }
unsigned char* BitMap::m_BitMap [private] |
bool BitMap::m_changed [private] |
char* BitMap::m_FileName [private] |
int BitMap::m_handle [private] |
ostream* BitMap::m_log [private] |
unsigned int BitMap::m_nBits [private] |
unsigned int BitMap::m_nBytes [private] |
unsigned int BitMap::m_nFree [private] |
unsigned int BitMap::m_nFreeConfirmed [private] |