summaryrefslogtreecommitdiff
path: root/src/myriad.cpp
diff options
context:
space:
mode:
authorMike Buland <eichlan@xagasoft.com>2010-04-12 17:50:37 +0000
committerMike Buland <eichlan@xagasoft.com>2010-04-12 17:50:37 +0000
commitfc2943ed980306244749d8d13796eaff690917b6 (patch)
tree78e2c058295b76299f9e1c9560d150e0f124f640 /src/myriad.cpp
parent41c9581b48f055f6559335ffc0316f27ed1b3657 (diff)
downloadlibbu++-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.cpp121
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
148void Bu::Myriad::initialize( int iBlockSize, int iPreAllocate ) 145void 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
227int Bu::Myriad::createStream( int iPreAllocate ) 287int 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
246int Bu::Myriad::findEmptyBlock() 307int 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
266void Bu::Myriad::deleteStream( int /*iID*/ ) 327void Bu::Myriad::deleteStream( int /*iID*/ )
@@ -314,6 +375,8 @@ Bu::Myriad::Block *Bu::Myriad::getBlock( int iBlock )
314 375
315void Bu::Myriad::releaseBlock( Bu::Myriad::Block *pBlock ) 376void 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 {