BitMap Class Reference

#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

Detailed Description

Definition at line 29 of file BitMap.h.


Constructor & Destructor Documentation

BitMap::BitMap (  ) 

Definition at line 50 of file BitMap.cpp.

00051 {
00052     m_FileName       = NULL;
00053     m_nBits          = 0;
00054     m_nFree          = 0;
00055     m_nFreeConfirmed = 0;
00056     m_nBytes         = 0;
00057     m_BitMap         = NULL;
00058     m_handle         = -1;
00059     m_log            = NULL;
00060     m_changed        = false;
00061 }

BitMap::~BitMap (  ) 

Definition at line 63 of file BitMap.cpp.

00064 {
00065     iclose();
00066     ifreestg();
00067 }


Member Function Documentation

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.

00424 {
00425     unsigned int count = 0;
00426     int mask = 0x80;
00427     for( int i = 0; i < 8; i++ )
00428     {
00429         if( ( mask & byte ) == 0 )
00430             count++;
00431         mask = mask >> 1;
00432     }
00433     return count;
00434 }

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]

Definition at line 64 of file BitMap.h.

00064 { return m_nFree; };

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 }


Field Documentation

unsigned char* BitMap::m_BitMap [private]

Definition at line 37 of file BitMap.h.

bool BitMap::m_changed [private]

Definition at line 41 of file BitMap.h.

char* BitMap::m_FileName [private]

Definition at line 32 of file BitMap.h.

int BitMap::m_handle [private]

Definition at line 39 of file BitMap.h.

ostream* BitMap::m_log [private]

Definition at line 40 of file BitMap.h.

unsigned int BitMap::m_nBits [private]

Definition at line 33 of file BitMap.h.

unsigned int BitMap::m_nBytes [private]

Definition at line 36 of file BitMap.h.

unsigned int BitMap::m_nFree [private]

Definition at line 34 of file BitMap.h.

unsigned int BitMap::m_nFreeConfirmed [private]

Definition at line 35 of file BitMap.h.


The documentation for this class was generated from the following files:
Generated on Wed Jul 4 16:03:31 2012 for RIO by  doxygen 1.6.3