#include "packedintarray.h" #include #define bitsizeof( x ) ((sizeof(x))*8) #define StoreBits ((bitsizeof(PackedIntArray::Store))) #define StoreCount( x ) ((((x)*iBitWidth)/StoreBits)+((((x)*iBitWidth)%StoreBits)?1:0)) PackedIntArray::PackedIntArray( PackedIntArray::Unit iBitWidth ) : iBitWidth( iBitWidth ), aData( NULL ), iCapacity( 0 ), iCount( 0 ), uMask( 0 ) { aData = new Store[4]; iCapacity = (StoreBits*4)/iBitWidth; if( iBitWidth < StoreBits ) { if( (StoreBits%iBitWidth) == 0 ) iMaxSpan = 1; else { iMaxSpan = (iBitWidth/StoreBits)+1; } } for( int j = 0; j < iBitWidth; j++ ) uMask |= (1< 0 ) iCount--; } PackedIntArray::Unit PackedIntArray::get( int idx ) const { int iStore = idx*iBitWidth/StoreBits; int iBit = (idx*iBitWidth)%StoreBits; // Bu::println("idx = %1, iStore = %2, iBit = %3"). // arg( idx ).arg( iStore ).arg( iBit ); Unit ret = (aData[iStore]>>iBit)&uMask; for( iBit = StoreBits-iBit; iBit < iBitWidth; ) { iStore++; // Bu::println(" ==> iStore = %2, iBit = %3"). // arg( idx ).arg( iStore ).arg( iBit ); ret |= (aData[iStore]&((Store)uMask)>>iBit)< iStore = %2, iBit = %3"). // arg( idx ).arg( iStore ).arg( iBit ); aData[iStore] = (aData[iStore]& ~(((Store)uMask)>>iBit)) | ((Store)i)>>iBit; iBit += StoreBits; } } void PackedIntArray::insert( int idx, Unit i ) { iCount++; checkCapacity(); for( int j = iCount-1; j > idx; j-- ) { set( j, get( j-1 ) ); } set( idx, i ); } void PackedIntArray::set( const PackedIntArray &rSrc, int iStart, int iSize ) { iCount = iSize; checkCapacity(); for( int j = 0; j < iSize; j++ ) { set( j, rSrc.get( iStart+j ) ); } } void PackedIntArray::set( const PackedIntArray &rSrc ) { delete[] aData; iBitWidth = rSrc.iBitWidth; iCapacity = rSrc.iCapacity; iCount = rSrc.iCount; uMask = rSrc.uMask; int iSize = StoreCount(iCapacity); aData = new Store[iSize]; memcpy( aData, rSrc.aData, iSize*sizeof(Store) ); } void PackedIntArray::copy( int iDest, const PackedIntArray &rSrc, int iStart, int iSize ) { iCount = iSize; checkCapacity(); for( int j = 0; j < iSize; j++ ) { set( j+iDest, rSrc.get( iStart+j ) ); } } void PackedIntArray::trim() { while( iCount > 0 && get( iCount-1 ) == 0 ) iCount--; } Bu::String PackedIntArray::toBitString() const { Bu::String sRet; for( int j = iCount*iBitWidth-1; j >= 0; j-- ) { sRet += (aData[j/StoreBits] & (1<<(j%StoreBits))) ? "1" : "0"; if( j > 0 && j%iBitWidth == 0 ) sRet += " "; } return sRet; } Bu::String PackedIntArray::toString() const { Bu::String sRet; for( int j = iCount-1; j >= 0; j-- ) { sRet += (char)(get(j))+'0'; } return sRet; } void PackedIntArray::checkCapacity() { if( iCount > iCapacity ) { // Bu::println("!!! Resizing !!!"); Store *aOldData = aData; int iSize = StoreCount(iCapacity); int iNewSize = (iCapacity==0)?(bitsizeof(Store)/iBitWidth):(iCapacity=StoreCount(iCapacity*2)); int iCountSize = StoreCount(iCount); while( iNewSize < iCountSize ) iNewSize *= 2; // Bu::println(" %1 => %2 (%3 bit words)").arg( iSize ).arg( iNewSize ) // .arg( StoreBits ); aData = new Store[iNewSize]; memset( aData, 0, iNewSize*sizeof(Store) ); memcpy( aData, aOldData, iSize*sizeof(Store) ); iCapacity = (iNewSize*bitsizeof(Store))/iBitWidth; delete[] aOldData; } }