From 286dc953c1e0e4a75589e4068e29a317a03f23dd Mon Sep 17 00:00:00 2001 From: Mike Buland Date: Tue, 25 May 2010 05:42:26 +0000 Subject: More myriad tests and features, passes perfectly so far. --- src/array.h | 12 ++++++++++ src/myriad.cpp | 53 ++++++++++++++++++++++++++++++++++++++++--- src/myriad.h | 1 + src/myriadstream.cpp | 6 ++--- src/unit/myriad.unit | 64 ++++++++++++++++++++++++++++++++++++++++++++++++---- 5 files changed, 126 insertions(+), 10 deletions(-) (limited to 'src') diff --git a/src/array.h b/src/array.h index 604f8a6..39efb9e 100644 --- a/src/array.h +++ b/src/array.h @@ -488,6 +488,18 @@ namespace Bu core->erase( i.iPos ); } + void eraseLast() + { + _hardCopy(); + core->erase( core->iSize-1 ); + } + + void eraseFirst() + { + _hardCopy(); + core->erase( 0 ); + } + /** * In order to make swapErase faster, what it does is swap the given * item in the array with the last item, then make the array shorter diff --git a/src/myriad.cpp b/src/myriad.cpp index 044e35e..9e128d1 100644 --- a/src/myriad.cpp +++ b/src/myriad.cpp @@ -352,8 +352,22 @@ int Bu::Myriad::findEmptyBlock() return iBlocks++; } -void Bu::Myriad::deleteStream( int /*iID*/ ) +void Bu::Myriad::deleteStream( int iId ) { + for( StreamArray::iterator i = aStreams.begin(); i; i++ ) + { + if( (*i)->iId == iId ) + { + Stream *pStream = *i; + for( BlockArray::iterator j = pStream->aBlocks.begin(); j; j++ ) + { + bsBlockUsed.setBit( *j, false ); + } + aStreams.erase( i ); + bHeaderChanged = true; + return; + } + } } Bu::MyriadStream Bu::Myriad::openStream( int iId ) @@ -426,9 +440,42 @@ void Bu::Myriad::syncBlock( Block *pBlock ) } } +int Bu::Myriad::streamAddBlock( Stream *pStream ) +{ + int iBlock = findEmptyBlock(); + pStream->aBlocks.append( iBlock ); + bsBlockUsed.setBit( iBlock ); + return iBlock; +} + void Bu::Myriad::setStreamSize( Stream *pStream, long iSize ) { - sio << "Oh man, you have to implement Bu::Myriad::setStreamSize!!! (line " - << __LINE__ << ")" << sio.nl; + if( pStream->iSize == iSize ) + { + return; + } + else if( pStream->iSize > iSize ) + { + // Shrink + for( int iNewSize = pStream->aBlocks.getSize()*iBlockSize; + iNewSize-64 > iSize; iNewSize -= iBlockSize ) + { + bsBlockUsed.setBit( pStream->aBlocks.last(), false ); + pStream->aBlocks.eraseLast(); + } + pStream->iSize = iSize; + bHeaderChanged = true; + } + else + { + // Grow + for( int iNewSize = pStream->aBlocks.getSize()*iBlockSize; + iNewSize < iSize; iNewSize += iBlockSize ) + { + streamAddBlock( pStream ); + } + pStream->iSize = iSize; + bHeaderChanged = true; + } } diff --git a/src/myriad.h b/src/myriad.h index 8e7cfb1..900037b 100644 --- a/src/myriad.h +++ b/src/myriad.h @@ -150,6 +150,7 @@ namespace Bu void releaseBlock( Block *pBlock ); void syncBlock( Block *pBlock ); + int streamAddBlock( Stream *pStream ); void setStreamSize( Stream *pStream, long iSize ); private: diff --git a/src/myriadstream.cpp b/src/myriadstream.cpp index 41c5b53..b0b1d05 100644 --- a/src/myriadstream.cpp +++ b/src/myriadstream.cpp @@ -139,9 +139,7 @@ size_t Bu::MyriadStream::write( const void *pBuf, size_t nBytes ) } else { - iCurBlock = rMyriad.findEmptyBlock(); - pStream->aBlocks.append( iCurBlock ); - rMyriad.bsBlockUsed.setBit( iCurBlock ); + iCurBlock = rMyriad.streamAddBlock( pStream ); #ifdef MYRIAD_STREAM_DEBUG sio << "MyriadStream: write: " << __LINE__ << ": New block allocated and appended: " << iCurBlock << "." << sio.nl; @@ -283,6 +281,8 @@ void Bu::MyriadStream::setBlocking( bool /*bBlocking*/ ) void Bu::MyriadStream::setSize( long iSize ) { + if( iSize < 0 ) + iSize = 0; rMyriad.setStreamSize( pStream, iSize ); if( iPos > iSize ) iPos = iSize; diff --git a/src/unit/myriad.unit b/src/unit/myriad.unit index ed121cc..d27c0dc 100644 --- a/src/unit/myriad.unit +++ b/src/unit/myriad.unit @@ -20,9 +20,33 @@ using namespace Bu; suite Myriad { - void addBlock( Stream &s ) + test setSize { - s.setPosEnd( 0 ); + FString sFileName("myriad-XXXXXXX"); + + File fMyriad = tempFile( sFileName ); + Myriad m( fMyriad ); + m.initialize( 64 ); + + MyriadStream ms = m.openStream( m.createStream() ); + ms.setSize( 150 ); + ms.setPos( 145 ); + char stuff[10]; + unitTest( ms.read( stuff, 10 ) == 5 ); + + ms.setSize( 12 ); + unitTest( ms.read( stuff, 10 ) == 0 ); + unitTest( ms.write( "hello", 5 ) == 5 ); + unitTest( ms.tell() == 17 ); + + ms.setSize( 500 ); + unitTest( ms.tell() == 17 ); + } + + void addBlock( Stream &s, bool bAppend=true ) + { + if( bAppend ) + s.setPosEnd( 0 ); int iSize = (random()%1016)+8; s.write( &iSize, 4 ); char *buf = new char[iSize-8]; @@ -72,7 +96,7 @@ suite Myriad verifyBlock( s ); } - test grow1 + test stressGrow { FString sFileName("myriad-XXXXXXX"); @@ -90,7 +114,6 @@ suite Myriad for( int j = 0; j < 2500; j++ ) { - switch( random()%5 ) { case 0: @@ -134,5 +157,38 @@ suite Myriad verifyStream( ms ); } } + + test stressTruncate + { + FString sFileName("myriad-XXXXXXX"); + + File fMyriad = tempFile( sFileName ); + Myriad m( fMyriad ); + m.initialize( 64 ); + + Array aStream; + + for( int j = 0; j < 5; j++ ) + { + aStream.append( m.createStream() ); + } + + srandom( 1024 ); + + char b; + for( int iter = 0; iter < 2500; iter++ ) + { + for( Array::iterator i = aStream.begin(); i; i++ ) + { + MyriadStream ms = m.openStream( *i ); + addBlock( ms, false ); + ms.setSize( ms.tell() ); + unitTest( ms.read( &b, 1 ) == 0 ); + ms.setPos( 0 ); + verifyBlock( ms ); + unitTest( ms.read( &b, 1 ) == 0 ); + } + } + } } -- cgit v1.2.3