diff options
| author | Mike Buland <eichlan@xagasoft.com> | 2010-04-12 17:50:37 +0000 |
|---|---|---|
| committer | Mike Buland <eichlan@xagasoft.com> | 2010-04-12 17:50:37 +0000 |
| commit | fc2943ed980306244749d8d13796eaff690917b6 (patch) | |
| tree | 78e2c058295b76299f9e1c9560d150e0f124f640 | |
| parent | 41c9581b48f055f6559335ffc0316f27ed1b3657 (diff) | |
| download | libbu++-fc2943ed980306244749d8d13796eaff690917b6.tar.gz libbu++-fc2943ed980306244749d8d13796eaff690917b6.tar.bz2 libbu++-fc2943ed980306244749d8d13796eaff690917b6.tar.xz libbu++-fc2943ed980306244749d8d13796eaff690917b6.zip | |
Wow Myriad!!
Myriad seems to work. I have to run it through a few more paces, and there are
some known corner cases that I may just disallow, such as too-small block sizes.
Beyond a little more testing, it's ready for production. I may switch some of
my cache tests to using it now.
| -rw-r--r-- | src/myriad.cpp | 121 | ||||
| -rw-r--r-- | src/myriadstream.cpp | 191 | ||||
| -rw-r--r-- | src/server.cpp | 12 | ||||
| -rw-r--r-- | src/tools/myriad.cpp | 49 |
4 files changed, 269 insertions, 104 deletions
diff --git a/src/myriad.cpp b/src/myriad.cpp index a1a5c38..58270c5 100644 --- a/src/myriad.cpp +++ b/src/myriad.cpp | |||
| @@ -78,10 +78,6 @@ void Bu::Myriad::initialize() | |||
| 78 | sio << "Myriad: iSize=" << iSize << ", iBlockSize=" << iBlockSize | 78 | sio << "Myriad: iSize=" << iSize << ", iBlockSize=" << iBlockSize |
| 79 | << ", iBlocks=" << iBlocks << ", iStreams=" << iStreams << sio.nl; | 79 | << ", iBlocks=" << iBlocks << ", iStreams=" << iStreams << sio.nl; |
| 80 | 80 | ||
| 81 | // Don't do this, just read the damn header. | ||
| 82 | sio << "Myriad: Don't do this, just read the damn header (line 82)" | ||
| 83 | << sio.nl; | ||
| 84 | |||
| 85 | int iHeaderSize = 14 + 8 + 4; | 81 | int iHeaderSize = 14 + 8 + 4; |
| 86 | int iHeaderBlocks = 0; //blkDiv( iHeaderSize+4, iBlockSize ); | 82 | int iHeaderBlocks = 0; //blkDiv( iHeaderSize+4, iBlockSize ); |
| 87 | 83 | ||
| @@ -93,30 +89,38 @@ void Bu::Myriad::initialize() | |||
| 93 | 89 | ||
| 94 | sio << "Myriad: iHeaderSize=" << iHeaderSize | 90 | sio << "Myriad: iHeaderSize=" << iHeaderSize |
| 95 | << ", iHeaderBlocks=" << iHeaderBlocks << sio.nl; | 91 | << ", iHeaderBlocks=" << iHeaderBlocks << sio.nl; |
| 92 | |||
| 93 | Stream *pFakeHdr = new Stream; | ||
| 94 | pFakeHdr->iId = 0; | ||
| 95 | pFakeHdr->iSize = iHeaderSize; | ||
| 96 | for( int j = 0; j < iHeaderBlocks; j++ ) | ||
| 97 | { | ||
| 98 | pFakeHdr->aBlocks.append( j ); | ||
| 99 | } | ||
| 96 | 100 | ||
| 97 | bsBlockUsed.setSize( iBlocks, true ); | 101 | bsBlockUsed.setSize( iBlocks, true ); |
| 98 | 102 | ||
| 99 | bool bCanSkip = false; // Can skip around, post initial header stream i/o | 103 | bool bCanSkip = false; // Can skip around, post initial header stream i/o |
| 104 | MyriadStream *pIn = new MyriadStream( *this, pFakeHdr ); | ||
| 105 | pIn->setPos( sStore.tell() ); | ||
| 100 | for( int j = 0; j < iStreams; j++ ) | 106 | for( int j = 0; j < iStreams; j++ ) |
| 101 | { | 107 | { |
| 102 | int iHdrBlock = 0; | ||
| 103 | int iCurBlock = 0; | ||
| 104 | aStreams.append( new Stream() ); | 108 | aStreams.append( new Stream() ); |
| 105 | Stream &s = *aStreams[j]; | 109 | Stream &s = *aStreams[j]; |
| 106 | sStore.read( &s.iId, 4 ); | 110 | pIn->read( &s.iId, 4 ); |
| 107 | sStore.read( &s.iSize, 4 ); | 111 | pIn->read( &s.iSize, 4 ); |
| 108 | int iSBlocks = blkDiv(s.iSize, iBlockSize); | 112 | int iSBlocks = blkDiv(s.iSize, iBlockSize); |
| 109 | sio << "Myriad: - Stream::iId=" << s.iId | 113 | sio << "Myriad: - Stream::iId=" << s.iId |
| 110 | << ", Stream::iSize=" << s.iSize | 114 | << ", Stream::iSize=" << s.iSize |
| 111 | << ", Stream::aBlocks=" << iSBlocks | 115 | << ", Stream::aBlocks=" << iSBlocks |
| 112 | << ", sStore.tell()=" << sStore.tell() << sio.nl; | 116 | << ", pIn->tell()=" << pIn->tell() << sio.nl; |
| 113 | for( int k = 0; k < iSBlocks; k++ ) | 117 | for( int k = 0; k < iSBlocks; k++ ) |
| 114 | { | 118 | { |
| 115 | int iBId; | 119 | int iBId; |
| 116 | sStore.read( &iBId, 4 ); | 120 | pIn->read( &iBId, 4 ); |
| 117 | sio << "Myriad: - iBId=" << iBId | 121 | sio << "Myriad: - iBId=" << iBId |
| 118 | << ", iStartPos=" << iBId*iBlockSize | 122 | << ", iStartPos=" << iBId*iBlockSize |
| 119 | << ", sStore.tell()=" << sStore.tell() << sio.nl; | 123 | << ", pIn->tell()=" << pIn->tell() << sio.nl; |
| 120 | s.aBlocks.append( iBId ); | 124 | s.aBlocks.append( iBId ); |
| 121 | bsBlockUsed.setBit( iBId ); | 125 | bsBlockUsed.setBit( iBId ); |
| 122 | if( (j == 0 && k == iHeaderBlocks-1) ) | 126 | if( (j == 0 && k == iHeaderBlocks-1) ) |
| @@ -124,25 +128,18 @@ void Bu::Myriad::initialize() | |||
| 124 | sio << "Myriad: - End of prepartition, unlocking skipping." | 128 | sio << "Myriad: - End of prepartition, unlocking skipping." |
| 125 | << sio.nl; | 129 | << sio.nl; |
| 126 | bCanSkip = true; | 130 | bCanSkip = true; |
| 127 | iCurBlock = blkDiv( (int)sStore.tell(), iBlockSize ); | 131 | MyriadStream *pTmp = new MyriadStream( *this, aStreams[0] ); |
| 128 | } | 132 | sio << "Myriad - Position = " << pIn->tell() << sio.nl; |
| 129 | if( bCanSkip && sStore.tell() >= iCurBlock*iBlockSize+iBlockSize ) | 133 | pTmp->setPos( pIn->tell() ); |
| 130 | { | 134 | delete pIn; |
| 131 | iHdrBlock++; | 135 | delete pFakeHdr; |
| 132 | iCurBlock = aStreams[0]->aBlocks[iHdrBlock]; | 136 | pIn = pTmp; |
| 133 | sio << "Myriad: Ran out of data in block, finding next header " | ||
| 134 | "block: " << iHdrBlock << " = " << iCurBlock << " (" | ||
| 135 | << iCurBlock*iBlockSize << "b)" << sio.nl; | ||
| 136 | sStore.setPos( iCurBlock*iBlockSize ); | ||
| 137 | } | 137 | } |
| 138 | } | 138 | } |
| 139 | } | 139 | } |
| 140 | delete pIn; | ||
| 140 | 141 | ||
| 141 | sio << "Myriad: Blocks used: " << bsBlockUsed.toString() << sio.nl; | 142 | sio << "Myriad: Blocks used: " << bsBlockUsed.toString() << sio.nl; |
| 142 | |||
| 143 | //printf("%d blocks, %db each, %db block offset\n", | ||
| 144 | // iBlocks, iBlockSize, iBlockStart ); | ||
| 145 | |||
| 146 | } | 143 | } |
| 147 | 144 | ||
| 148 | void Bu::Myriad::initialize( int iBlockSize, int iPreAllocate ) | 145 | void Bu::Myriad::initialize( int iBlockSize, int iPreAllocate ) |
| @@ -211,6 +208,14 @@ void Bu::Myriad::initialize( int iBlockSize, int iPreAllocate ) | |||
| 211 | pStr->iSize = sStore.tell(); | 208 | pStr->iSize = sStore.tell(); |
| 212 | sio << "Myriad: Actual end of header stream = " << pStr->iSize << sio.nl; | 209 | sio << "Myriad: Actual end of header stream = " << pStr->iSize << sio.nl; |
| 213 | 210 | ||
| 211 | pStr->iSize = iHeaderSize; | ||
| 212 | for( int j = 0; j < iHeaderBlocks; j++ ) | ||
| 213 | { | ||
| 214 | pStr->aBlocks.append( j ); | ||
| 215 | } | ||
| 216 | |||
| 217 | aStreams.append( pStr ); | ||
| 218 | |||
| 214 | //hStreams.insert( 0, BlockArray( 0 ) ); | 219 | //hStreams.insert( 0, BlockArray( 0 ) ); |
| 215 | } | 220 | } |
| 216 | 221 | ||
| @@ -219,9 +224,64 @@ void Bu::Myriad::updateHeader() | |||
| 219 | if( !sStore.canWrite() ) | 224 | if( !sStore.canWrite() ) |
| 220 | return; | 225 | return; |
| 221 | 226 | ||
| 222 | 227 | char cBuf; | |
| 228 | int iBuf; | ||
| 223 | 229 | ||
| 224 | // TODO: Use the stream class to access this really smoothly, I hope :) | 230 | // Compute the new size of the header. |
| 231 | int iHeaderSize = 14 + 8*aStreams.getSize(); | ||
| 232 | sio << "Myriad: updateHeader: aStreams.getSize() = " << aStreams.getSize() | ||
| 233 | << sio.nl; | ||
| 234 | for( StreamArray::iterator i = aStreams.begin(); i; i++ ) | ||
| 235 | { | ||
| 236 | iHeaderSize += 4*(*i)->aBlocks.getSize(); | ||
| 237 | sio << "Myriad: updateHeader: (*i)->aBlocks.getSize() = " | ||
| 238 | << (*i)->aBlocks.getSize() << sio.nl; | ||
| 239 | } | ||
| 240 | int iNewBlocks = blkDiv( iHeaderSize, iBlockSize ); | ||
| 241 | while( iNewBlocks > aStreams[0]->aBlocks.getSize() ) | ||
| 242 | { | ||
| 243 | int iBlock = findEmptyBlock(); | ||
| 244 | sio << "Myriad: updateHeader: Appending block " << iBlock | ||
| 245 | << " to header." << sio.nl; | ||
| 246 | aStreams[0]->aBlocks.append( iBlock ); | ||
| 247 | bsBlockUsed.setBit( iBlock ); | ||
| 248 | iHeaderSize += 4; | ||
| 249 | iNewBlocks = blkDiv( iHeaderSize, iBlockSize ); | ||
| 250 | } | ||
| 251 | aStreams[0]->iSize = iHeaderSize; | ||
| 252 | sio << "Myriad: updateHeader: iHeaderSize=" << iHeaderSize | ||
| 253 | << ", iNewBlocks=" << iNewBlocks << ", curBlocks=" | ||
| 254 | << aStreams[0]->aBlocks.getSize() << sio.nl; | ||
| 255 | |||
| 256 | MyriadStream sHdr( *this, aStreams[0] ); | ||
| 257 | sHdr.write( Myriad_MAGIC_CODE, 4 ); | ||
| 258 | |||
| 259 | // Version (1) | ||
| 260 | cBuf = 1; | ||
| 261 | sHdr.write( &cBuf, 1 ); | ||
| 262 | |||
| 263 | // Bits per int | ||
| 264 | cBuf = 32; | ||
| 265 | sHdr.write( &cBuf, 1 ); | ||
| 266 | |||
| 267 | // The size of each block | ||
| 268 | sHdr.write( &iBlockSize, 4 ); | ||
| 269 | |||
| 270 | iBuf = aStreams.getSize(); | ||
| 271 | // The number of streams | ||
| 272 | sHdr.write( &iBuf, 4 ); | ||
| 273 | |||
| 274 | for( StreamArray::iterator i = aStreams.begin(); i; i++ ) | ||
| 275 | { | ||
| 276 | sHdr.write( &(*i)->iId, 4 ); | ||
| 277 | sHdr.write( &(*i)->iSize, 4 ); | ||
| 278 | int iUsedBlocks = blkDiv( (*i)->iSize, iBlockSize ); | ||
| 279 | // for( BlockArray::iterator j = (*i)->aBlocks.begin(); j; j++ ) | ||
| 280 | for( int j = 0; j < iUsedBlocks; j++ ) | ||
| 281 | { | ||
| 282 | sHdr.write( &(*i)->aBlocks[j], 4 ); | ||
| 283 | } | ||
| 284 | } | ||
| 225 | } | 285 | } |
| 226 | 286 | ||
| 227 | int Bu::Myriad::createStream( int iPreAllocate ) | 287 | int Bu::Myriad::createStream( int iPreAllocate ) |
| @@ -231,6 +291,7 @@ int Bu::Myriad::createStream( int iPreAllocate ) | |||
| 231 | sio << "Myriad: New stream id=" << pStr->iId << ", iPreAllocate=" | 291 | sio << "Myriad: New stream id=" << pStr->iId << ", iPreAllocate=" |
| 232 | << iPreAllocate << sio.nl; | 292 | << iPreAllocate << sio.nl; |
| 233 | pStr->iSize = 0; | 293 | pStr->iSize = 0; |
| 294 | aStreams.append( pStr ); | ||
| 234 | 295 | ||
| 235 | for( int j = 0; j < iPreAllocate; j++ ) | 296 | for( int j = 0; j < iPreAllocate; j++ ) |
| 236 | { | 297 | { |
| @@ -240,7 +301,7 @@ int Bu::Myriad::createStream( int iPreAllocate ) | |||
| 240 | bsBlockUsed.setBit( iFreeBlock ); | 301 | bsBlockUsed.setBit( iFreeBlock ); |
| 241 | } | 302 | } |
| 242 | 303 | ||
| 243 | return 0; | 304 | return pStr->iId; |
| 244 | } | 305 | } |
| 245 | 306 | ||
| 246 | int Bu::Myriad::findEmptyBlock() | 307 | int Bu::Myriad::findEmptyBlock() |
| @@ -260,7 +321,7 @@ int Bu::Myriad::findEmptyBlock() | |||
| 260 | sStore.write( pBlock, iBlockSize ); | 321 | sStore.write( pBlock, iBlockSize ); |
| 261 | delete pBlock; | 322 | delete pBlock; |
| 262 | 323 | ||
| 263 | return iBlockSize++; | 324 | return iBlocks++; |
| 264 | } | 325 | } |
| 265 | 326 | ||
| 266 | void Bu::Myriad::deleteStream( int /*iID*/ ) | 327 | void Bu::Myriad::deleteStream( int /*iID*/ ) |
| @@ -314,6 +375,8 @@ Bu::Myriad::Block *Bu::Myriad::getBlock( int iBlock ) | |||
| 314 | 375 | ||
| 315 | void Bu::Myriad::releaseBlock( Bu::Myriad::Block *pBlock ) | 376 | void Bu::Myriad::releaseBlock( Bu::Myriad::Block *pBlock ) |
| 316 | { | 377 | { |
| 378 | if( pBlock == NULL ) | ||
| 379 | return; | ||
| 317 | sio << "Myriad: Releasing block " << pBlock->iBlockIndex << sio.nl; | 380 | sio << "Myriad: Releasing block " << pBlock->iBlockIndex << sio.nl; |
| 318 | if( pBlock->bChanged ) | 381 | if( pBlock->bChanged ) |
| 319 | { | 382 | { |
diff --git a/src/myriadstream.cpp b/src/myriadstream.cpp index 0e6fc89..d714c23 100644 --- a/src/myriadstream.cpp +++ b/src/myriadstream.cpp | |||
| @@ -13,6 +13,8 @@ using Bu::Fmt; | |||
| 13 | 13 | ||
| 14 | #include <string.h> | 14 | #include <string.h> |
| 15 | 15 | ||
| 16 | // #define MYRIAD_STREAM_DEBUG 1 | ||
| 17 | |||
| 16 | Bu::MyriadStream::MyriadStream( Bu::Myriad &rMyriad, | 18 | Bu::MyriadStream::MyriadStream( Bu::Myriad &rMyriad, |
| 17 | Bu::Myriad::Stream *pStream ) : | 19 | Bu::Myriad::Stream *pStream ) : |
| 18 | rMyriad( rMyriad ), | 20 | rMyriad( rMyriad ), |
| @@ -20,8 +22,10 @@ Bu::MyriadStream::MyriadStream( Bu::Myriad &rMyriad, | |||
| 20 | pCurBlock( NULL ), | 22 | pCurBlock( NULL ), |
| 21 | iPos( 0 ) | 23 | iPos( 0 ) |
| 22 | { | 24 | { |
| 25 | #ifdef MYRIAD_STREAM_DEBUG | ||
| 23 | sio << "MyriadStream: Created, iId=" << pStream->iId << ", iSize=" | 26 | sio << "MyriadStream: Created, iId=" << pStream->iId << ", iSize=" |
| 24 | << pStream->iSize << sio.nl; | 27 | << pStream->iSize << sio.nl; |
| 28 | #endif | ||
| 25 | //pCurBlock = rMyriad.newBlock(); | 29 | //pCurBlock = rMyriad.newBlock(); |
| 26 | //rMyriad.getBlock( uStream, pCurBlock ); | 30 | //rMyriad.getBlock( uStream, pCurBlock ); |
| 27 | //uSize = pCurBlock->uBytesUsed; | 31 | //uSize = pCurBlock->uBytesUsed; |
| @@ -41,19 +45,25 @@ void Bu::MyriadStream::close() | |||
| 41 | 45 | ||
| 42 | size_t Bu::MyriadStream::read( void *pBuf, size_t nBytes ) | 46 | size_t Bu::MyriadStream::read( void *pBuf, size_t nBytes ) |
| 43 | { | 47 | { |
| 44 | sio << "MyriadStream: Read: Started, asked to read " << nBytes << "b." | 48 | #ifdef MYRIAD_STREAM_DEBUG |
| 49 | sio << "MyriadStream: read: Started, asked to read " << nBytes << "b." | ||
| 45 | << sio.nl; | 50 | << sio.nl; |
| 46 | if( nBytes <= 0 ) | 51 | #endif |
| 47 | return 0; | ||
| 48 | if( nBytes > pStream->iSize-iPos ) | 52 | if( nBytes > pStream->iSize-iPos ) |
| 49 | nBytes = pStream->iSize-iPos; | 53 | nBytes = pStream->iSize-iPos; |
| 54 | if( nBytes <= 0 ) | ||
| 55 | return 0; | ||
| 50 | int iLeft = nBytes; | 56 | int iLeft = nBytes; |
| 51 | sio << "MyriadStream: Read: Started, going to read " << nBytes << "b." | 57 | #ifdef MYRIAD_STREAM_DEBUG |
| 58 | sio << "MyriadStream: read: Started, going to read " << nBytes << "b." | ||
| 52 | << sio.nl; | 59 | << sio.nl; |
| 60 | #endif | ||
| 53 | if( pCurBlock == NULL ) | 61 | if( pCurBlock == NULL ) |
| 54 | { | 62 | { |
| 55 | sio << "MyriadStream: Read: No block loaded, loading initial block." | 63 | #ifdef MYRIAD_STREAM_DEBUG |
| 64 | sio << "MyriadStream: read: No block loaded, loading initial block." | ||
| 56 | << sio.nl; | 65 | << sio.nl; |
| 66 | #endif | ||
| 57 | pCurBlock = rMyriad.getBlock( | 67 | pCurBlock = rMyriad.getBlock( |
| 58 | pStream->aBlocks[iPos/rMyriad.iBlockSize] | 68 | pStream->aBlocks[iPos/rMyriad.iBlockSize] |
| 59 | ); | 69 | ); |
| @@ -63,25 +73,30 @@ size_t Bu::MyriadStream::read( void *pBuf, size_t nBytes ) | |||
| 63 | int iCurBlock = pStream->aBlocks[iPos/rMyriad.iBlockSize]; | 73 | int iCurBlock = pStream->aBlocks[iPos/rMyriad.iBlockSize]; |
| 64 | if( pCurBlock->iBlockIndex != iCurBlock ) | 74 | if( pCurBlock->iBlockIndex != iCurBlock ) |
| 65 | { | 75 | { |
| 66 | sio << "MyriadStream: Read: Loading new block " << iCurBlock << "." | 76 | #ifdef MYRIAD_STREAM_DEBUG |
| 77 | sio << "MyriadStream: read: Loading new block " << iCurBlock << "." | ||
| 67 | << sio.nl; | 78 | << sio.nl; |
| 79 | #endif | ||
| 68 | rMyriad.releaseBlock( pCurBlock ); | 80 | rMyriad.releaseBlock( pCurBlock ); |
| 69 | pCurBlock = rMyriad.getBlock( iCurBlock ); | 81 | pCurBlock = rMyriad.getBlock( iCurBlock ); |
| 70 | } | 82 | } |
| 71 | 83 | ||
| 72 | int iAmnt = Bu::min( | 84 | int iAmnt = Bu::min( |
| 73 | rMyriad.iBlockSize - iPos%rMyriad.iBlockSize, | 85 | Bu::min( |
| 74 | iLeft | 86 | rMyriad.iBlockSize - iPos%rMyriad.iBlockSize, |
| 87 | iLeft | ||
| 88 | ), | ||
| 89 | pStream->iSize-iPos | ||
| 75 | ); | 90 | ); |
| 76 | // if( iLeft > iAmnt ) | 91 | #ifdef MYRIAD_STREAM_DEBUG |
| 77 | // iAmnt = iLeft; | 92 | sio << "MyriadStream: read: Copying out bytes: " |
| 78 | sio << "MyriadStream: Read: Copying out bytes: " | 93 | << iPos << "(" << (iPos%rMyriad.iBlockSize) << ")+" |
| 79 | << (iPos%rMyriad.iBlockSize) << " - " | ||
| 80 | << iAmnt | 94 | << iAmnt |
| 81 | << ", " << iLeft << "b left." << sio.nl; | 95 | << ", " << iLeft << "b left." << sio.nl; |
| 96 | #endif | ||
| 82 | memcpy( | 97 | memcpy( |
| 83 | pBuf, | 98 | pBuf, |
| 84 | pCurBlock->pData+iPos%rMyriad.iBlockSize, | 99 | pCurBlock->pData+(iPos%rMyriad.iBlockSize), |
| 85 | iAmnt | 100 | iAmnt |
| 86 | ); | 101 | ); |
| 87 | iPos += iAmnt; | 102 | iPos += iAmnt; |
| @@ -93,65 +108,109 @@ size_t Bu::MyriadStream::read( void *pBuf, size_t nBytes ) | |||
| 93 | 108 | ||
| 94 | size_t Bu::MyriadStream::write( const void *pBuf, size_t nBytes ) | 109 | size_t Bu::MyriadStream::write( const void *pBuf, size_t nBytes ) |
| 95 | { | 110 | { |
| 96 | if( nBytes == 0 ) | 111 | if( nBytes <= 0 ) |
| 97 | return 0; | 112 | return 0; |
| 98 | /* if( pCurBlock->uBytesUsed >= uBlockSize ) | 113 | |
| 99 | { | 114 | #ifdef MYRIAD_STREAM_DEBUG |
| 100 | // We're at the end of our current block, allocate another before we do | 115 | sio << "MyriadStream: write: Started, asked to write " << nBytes << "b." |
| 101 | // anything. | 116 | << sio.nl; |
| 102 | uCurBlock = rMyriad.getNextBlock( uCurBlock, pCurBlock ); | 117 | #endif |
| 103 | } */ | 118 | if( nBytes <= 0 ) |
| 119 | return 0; | ||
| 120 | int iLeft = nBytes; | ||
| 104 | /* | 121 | /* |
| 105 | if( (iPos%uBlockSize)+nBytes < uBlockSize ) | 122 | if( pCurBlock == NULL ) |
| 106 | { | 123 | { |
| 107 | //printf("wa: %u:%u:%u:%u -> ", iPos, iPos%uBlockSize, uSize, pCurBlock->uBytesUsed ); | 124 | #ifdef MYRIAD_STREAM_DEBUG |
| 108 | memcpy( pCurBlock->pData+(iPos%uBlockSize), pBuf, nBytes ); | 125 | sio << "MyriadStream: write: No block loaded, loading initial block." |
| 109 | //printf("write buffill: %ub, %u-%u/%u -> %d-%d/%d (a:%u:%u)\n", | 126 | << sio.nl; |
| 110 | // nBytes, 0, nBytes-1, nBytes, | 127 | #endif |
| 111 | // iPos, iPos+nBytes-1, uSize, uCurBlock, | 128 | pCurBlock = rMyriad.getBlock( |
| 112 | // pCurBlock->uBytesUsed ); | 129 | pStream->aBlocks[iPos/rMyriad.iBlockSize] |
| 113 | if( (iPos%uBlockSize)+nBytes > pCurBlock->uBytesUsed ) | 130 | ); |
| 114 | pCurBlock->uBytesUsed = (iPos%uBlockSize)+nBytes; | 131 | }*/ |
| 115 | rMyriad.setBlock( uCurBlock, pCurBlock ); | 132 | |
| 116 | iPos += nBytes; | 133 | while( iLeft > 0 ) |
| 117 | if( iPos > uSize ) | ||
| 118 | uSize = iPos; | ||
| 119 | //printf("block %u = %ub (%ub total) %d:%u\n", | ||
| 120 | // uCurBlock, pCurBlock->uBytesUsed, uSize, nBytes, iPos ); | ||
| 121 | return nBytes; | ||
| 122 | } | ||
| 123 | else | ||
| 124 | { | 134 | { |
| 125 | size_t nTotal = 0; | 135 | int iCurBlock; |
| 126 | for(;;) | 136 | if( iPos/rMyriad.iBlockSize < pStream->aBlocks.getSize() ) |
| 127 | { | 137 | { |
| 128 | uint32_t uNow = uBlockSize-(iPos%uBlockSize); | 138 | iCurBlock = pStream->aBlocks[iPos/rMyriad.iBlockSize]; |
| 129 | //printf("uNow: %u (%u-(%u%%%u)) %d req\n", uNow, uBlockSize, iPos, uBlockSize, nBytes ); | ||
| 130 | if( nBytes < uNow ) | ||
| 131 | uNow = nBytes; | ||
| 132 | memcpy( pCurBlock->pData+(iPos%uBlockSize), | ||
| 133 | &((char *)pBuf)[nTotal], uNow ); | ||
| 134 | //printf("write buffill: %ub, %u-%u/%u -> %d-%d/%d (b:%u:%u)\n", | ||
| 135 | // uNow, nTotal, nTotal+uNow-1, nBytes, | ||
| 136 | // iPos, iPos+uNow-1, uSize, uCurBlock, pCurBlock->uBytesUsed ); | ||
| 137 | if( (iPos%uBlockSize)+uNow > pCurBlock->uBytesUsed ) | ||
| 138 | pCurBlock->uBytesUsed = (iPos%uBlockSize)+uNow; | ||
| 139 | rMyriad.setBlock( uCurBlock, pCurBlock ); | ||
| 140 | iPos += uNow; | ||
| 141 | if( iPos > uSize ) | ||
| 142 | uSize = iPos; | ||
| 143 | nTotal += uNow; | ||
| 144 | nBytes -= uNow; | ||
| 145 | //printf("wb: block %u = %ub (%ub total)\n", | ||
| 146 | // uCurBlock, pCurBlock->uBytesUsed, uSize ); | ||
| 147 | //if( pCurBlock->uBytesUsed == uBlockSize ) | ||
| 148 | if( iPos%uBlockSize == 0 ) | ||
| 149 | uCurBlock = rMyriad.getNextBlock( uCurBlock, pCurBlock ); | ||
| 150 | if( nBytes == 0 ) | ||
| 151 | return nTotal; | ||
| 152 | } | 139 | } |
| 153 | }*/ | 140 | else |
| 154 | return 0; | 141 | { |
| 142 | iCurBlock = rMyriad.findEmptyBlock(); | ||
| 143 | pStream->aBlocks.append( iCurBlock ); | ||
| 144 | rMyriad.bsBlockUsed.setBit( iCurBlock ); | ||
| 145 | #ifdef MYRIAD_STREAM_DEBUG | ||
| 146 | sio << "MyriadStream: write: New block allocated and appended: " | ||
| 147 | << iCurBlock << "." << sio.nl; | ||
| 148 | |||
| 149 | #endif | ||
| 150 | } | ||
| 151 | if( !pCurBlock || pCurBlock->iBlockIndex != iCurBlock ) | ||
| 152 | { | ||
| 153 | #ifdef MYRIAD_STREAM_DEBUG | ||
| 154 | sio << "MyriadStream: write: Loading new block " << iCurBlock << "." | ||
| 155 | << sio.nl; | ||
| 156 | #endif | ||
| 157 | rMyriad.releaseBlock( pCurBlock ); | ||
| 158 | pCurBlock = rMyriad.getBlock( iCurBlock ); | ||
| 159 | } | ||
| 160 | pCurBlock->bChanged = true; | ||
| 161 | |||
| 162 | // There are two main writing modes when it comes down to it. | ||
| 163 | // Overwrite mode and append mode. Append is what pretty much always | ||
| 164 | // happens when creating a new stream. | ||
| 165 | if( iPos < pStream->iSize ) | ||
| 166 | { | ||
| 167 | int iAmnt = Bu::min( | ||
| 168 | Bu::min( | ||
| 169 | rMyriad.iBlockSize - iPos%rMyriad.iBlockSize, | ||
| 170 | iLeft | ||
| 171 | ), | ||
| 172 | pStream->iSize-iPos | ||
| 173 | ); | ||
| 174 | #ifdef MYRIAD_STREAM_DEBUG | ||
| 175 | sio << "MyriadStream: write (ovr): Copying in bytes: " | ||
| 176 | << (iPos%rMyriad.iBlockSize) << "+" | ||
| 177 | << iAmnt | ||
| 178 | << ", " << iLeft << "b left." << sio.nl; | ||
| 179 | #endif | ||
| 180 | memcpy( | ||
| 181 | pCurBlock->pData+(iPos%rMyriad.iBlockSize), | ||
| 182 | pBuf, | ||
| 183 | iAmnt | ||
| 184 | ); | ||
| 185 | iPos += iAmnt; | ||
| 186 | pBuf = &((char *)pBuf)[iAmnt]; | ||
| 187 | iLeft -= iAmnt; | ||
| 188 | } | ||
| 189 | else | ||
| 190 | { | ||
| 191 | int iAmnt = Bu::min( | ||
| 192 | rMyriad.iBlockSize - iPos%rMyriad.iBlockSize, | ||
| 193 | iLeft | ||
| 194 | ); | ||
| 195 | #ifdef MYRIAD_STREAM_DEBUG | ||
| 196 | sio << "MyriadStream: write (app): Copying in bytes: " | ||
| 197 | << (iPos%rMyriad.iBlockSize) << "+" | ||
| 198 | << iAmnt | ||
| 199 | << ", " << iLeft << "b left." << sio.nl; | ||
| 200 | #endif | ||
| 201 | memcpy( | ||
| 202 | pCurBlock->pData+(iPos%rMyriad.iBlockSize), | ||
| 203 | pBuf, | ||
| 204 | iAmnt | ||
| 205 | ); | ||
| 206 | iPos += iAmnt; | ||
| 207 | pStream->iSize += iAmnt; | ||
| 208 | pBuf = &((char *)pBuf)[iAmnt]; | ||
| 209 | iLeft -= iAmnt; | ||
| 210 | } | ||
| 211 | } | ||
| 212 | |||
| 213 | return nBytes; | ||
| 155 | } | 214 | } |
| 156 | 215 | ||
| 157 | long Bu::MyriadStream::tell() | 216 | long Bu::MyriadStream::tell() |
diff --git a/src/server.cpp b/src/server.cpp index 80ed509..36d9d6c 100644 --- a/src/server.cpp +++ b/src/server.cpp | |||
| @@ -93,8 +93,16 @@ void Bu::Server::scan() | |||
| 93 | } | 93 | } |
| 94 | if( FD_ISSET( j, &fdWrite ) ) | 94 | if( FD_ISSET( j, &fdWrite ) ) |
| 95 | { | 95 | { |
| 96 | Client *pClient = hClients.get( j ); | 96 | try |
| 97 | pClient->processOutput(); | 97 | { |
| 98 | Client *pClient = hClients.get( j ); | ||
| 99 | pClient->processOutput(); | ||
| 100 | } | ||
| 101 | catch( Bu::HashException &e ) | ||
| 102 | { | ||
| 103 | // Do nothing, I guess, the client is already dead... | ||
| 104 | // TODO: Someday, we may want to handle this more graceully. | ||
| 105 | } | ||
| 98 | } | 106 | } |
| 99 | } | 107 | } |
| 100 | 108 | ||
diff --git a/src/tools/myriad.cpp b/src/tools/myriad.cpp index 95b4503..605aac9 100644 --- a/src/tools/myriad.cpp +++ b/src/tools/myriad.cpp | |||
| @@ -20,7 +20,8 @@ enum Mode | |||
| 20 | modeCreate, | 20 | modeCreate, |
| 21 | modeInfo, | 21 | modeInfo, |
| 22 | modeStreamNew, | 22 | modeStreamNew, |
| 23 | modeStreamRead, | 23 | modeStreamDump, |
| 24 | modeStreamPut, | ||
| 24 | 25 | ||
| 25 | modeNone | 26 | modeNone |
| 26 | }; | 27 | }; |
| @@ -41,8 +42,10 @@ public: | |||
| 41 | "Display some info about a Myriad file." ); | 42 | "Display some info about a Myriad file." ); |
| 42 | addOption( eMode, 'n', "new", | 43 | addOption( eMode, 'n', "new", |
| 43 | "Create a new sub-stream in a Myriad file."); | 44 | "Create a new sub-stream in a Myriad file."); |
| 44 | addOption( eMode, 'r', "read", | 45 | addOption( eMode, 'd', "dump", |
| 45 | "Read a stream from a Myriad file."); | 46 | "Read a stream from a Myriad file."); |
| 47 | addOption( eMode, "put", | ||
| 48 | "Put a file into a Myriad stream."); | ||
| 46 | addHelpOption(); | 49 | addHelpOption(); |
| 47 | 50 | ||
| 48 | addHelpBanner("\nGeneral options:"); | 51 | addHelpBanner("\nGeneral options:"); |
| @@ -56,7 +59,8 @@ public: | |||
| 56 | setOverride( "create", "create" ); | 59 | setOverride( "create", "create" ); |
| 57 | setOverride( "info", "info" ); | 60 | setOverride( "info", "info" ); |
| 58 | setOverride( "new", "new" ); | 61 | setOverride( "new", "new" ); |
| 59 | setOverride( "read", "read" ); | 62 | setOverride( "dump", "dump" ); |
| 63 | setOverride( "put", "put" ); | ||
| 60 | 64 | ||
| 61 | parse( argc, argv ); | 65 | parse( argc, argv ); |
| 62 | } | 66 | } |
| @@ -78,8 +82,10 @@ Bu::Formatter &operator>>( Bu::Formatter &f, Mode &m ) | |||
| 78 | m = modeInfo; | 82 | m = modeInfo; |
| 79 | else if( sTok == "new" ) | 83 | else if( sTok == "new" ) |
| 80 | m = modeStreamNew; | 84 | m = modeStreamNew; |
| 81 | else if( sTok == "read" ) | 85 | else if( sTok == "dump" ) |
| 82 | m = modeStreamRead; | 86 | m = modeStreamDump; |
| 87 | else if( sTok == "put" ) | ||
| 88 | m = modeStreamPut; | ||
| 83 | else | 89 | else |
| 84 | m = modeNone; | 90 | m = modeNone; |
| 85 | return f; | 91 | return f; |
| @@ -99,7 +105,7 @@ int main( int argc, char *argv[] ) | |||
| 99 | } | 105 | } |
| 100 | else | 106 | else |
| 101 | { | 107 | { |
| 102 | File fOut( opts.sFile, File::WriteNew ); | 108 | File fOut( opts.sFile, File::WriteNew|File::Read ); |
| 103 | Myriad m( fOut ); | 109 | Myriad m( fOut ); |
| 104 | m.initialize( opts.iBlockSize, opts.iPreallocate ); | 110 | m.initialize( opts.iBlockSize, opts.iPreallocate ); |
| 105 | } | 111 | } |
| @@ -134,7 +140,7 @@ int main( int argc, char *argv[] ) | |||
| 134 | } | 140 | } |
| 135 | break; | 141 | break; |
| 136 | 142 | ||
| 137 | case modeStreamRead: | 143 | case modeStreamDump: |
| 138 | if( !opts.sFile.isSet() ) | 144 | if( !opts.sFile.isSet() ) |
| 139 | { | 145 | { |
| 140 | sio << "Please specify a file manipulate." << sio.nl; | 146 | sio << "Please specify a file manipulate." << sio.nl; |
| @@ -173,6 +179,35 @@ int main( int argc, char *argv[] ) | |||
| 173 | } | 179 | } |
| 174 | sio << sio.nl; | 180 | sio << sio.nl; |
| 175 | } | 181 | } |
| 182 | sio << "Position: " << s.tell() << ", isEos()=" << s.isEos() | ||
| 183 | << sio.nl; | ||
| 184 | } | ||
| 185 | break; | ||
| 186 | |||
| 187 | case modeStreamPut: | ||
| 188 | if( !opts.sFile.isSet() ) | ||
| 189 | { | ||
| 190 | sio << "Please specify a file manipulate." << sio.nl; | ||
| 191 | return 0; | ||
| 192 | } | ||
| 193 | else if( !opts.sSrc.isSet() ) | ||
| 194 | { | ||
| 195 | sio << "Please specify a source file to read." << sio.nl; | ||
| 196 | } | ||
| 197 | else | ||
| 198 | { | ||
| 199 | File fOut( opts.sFile, File::Write|File::Read ); | ||
| 200 | Myriad m( fOut ); | ||
| 201 | m.initialize(); | ||
| 202 | MyriadStream sOut = m.openStream( | ||
| 203 | m.createStream( opts.iPreallocate ) | ||
| 204 | ); | ||
| 205 | File fIn( opts.sSrc, File::Read ); | ||
| 206 | char buf[1024]; | ||
| 207 | while( !fIn.isEos() ) | ||
| 208 | { | ||
| 209 | sOut.write( buf, fIn.read( buf, 1024 ) ); | ||
| 210 | } | ||
| 176 | } | 211 | } |
| 177 | break; | 212 | break; |
| 178 | 213 | ||
