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 /src/myriad.cpp | |
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.
Diffstat (limited to 'src/myriad.cpp')
-rw-r--r-- | src/myriad.cpp | 121 |
1 files changed, 92 insertions, 29 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 | { |