aboutsummaryrefslogtreecommitdiff
path: root/src/stable/myriad.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/stable/myriad.cpp')
-rw-r--r--src/stable/myriad.cpp143
1 files changed, 136 insertions, 7 deletions
diff --git a/src/stable/myriad.cpp b/src/stable/myriad.cpp
index 5278ac5..f3ff09a 100644
--- a/src/stable/myriad.cpp
+++ b/src/stable/myriad.cpp
@@ -81,6 +81,14 @@ bool Bu::Myriad::setSize( Bu::Myriad::StreamId /*iStream*/,
81 return false; 81 return false;
82} 82}
83 83
84Bu::String Bu::Myriad::getLocation() const
85{
86 Bu::MutexLocker l( mAccess );
87 Bu::MutexLocker l2( mBacking );
88 return Bu::String("myriad(%1,%2):%3")
89 .arg( 1 ).arg( iBlockSize ).arg( rBacking.getLocation() );
90}
91
84bool Bu::Myriad::loadMyriad() 92bool Bu::Myriad::loadMyriad()
85{ 93{
86 Bu::println("Load myriad!"); 94 Bu::println("Load myriad!");
@@ -264,6 +272,32 @@ int32_t Bu::Myriad::allocateBlock()
264 } 272 }
265} 273}
266 274
275void Bu::Myriad::releaseBlock( int32_t iBlockId, bool bBlank )
276{
277 Bu::MutexLocker l( mAccess );
278 lFreeBlocks.append( iBlockId );
279 if( bBlank )
280 {
281 blankBlock( iBlockId );
282 }
283}
284
285void Bu::Myriad::blankBlock( int32_t iBlockId )
286{
287 Bu::MutexLocker l( mBacking );
288 rBacking.setPos( iBlockId*iBlockSize );
289 int32_t iChunk = std::min( iBlockSize, 4096 );
290 uint8_t *pChunk = new uint8_t[iChunk];
291 memset( pChunk, 0, iChunk );
292 int iLeft = iBlockSize;
293 while( iLeft > 0 )
294 {
295 int32_t iWrite = rBacking.write( pChunk, std::min( iChunk, iLeft ) );
296 iLeft -= iWrite;
297 }
298 delete[] pChunk;
299}
300
267void Bu::Myriad::openStream( StreamId id ) 301void Bu::Myriad::openStream( StreamId id )
268{ 302{
269 Bu::MutexLocker l( mAccess ); 303 Bu::MutexLocker l( mAccess );
@@ -276,20 +310,36 @@ void Bu::Myriad::closeStream( StreamId id )
276 hStream.get( id )->close(); 310 hStream.get( id )->close();
277} 311}
278 312
279int32_t Bu::Myriad::blockRead( int32_t iStart, void *pTarget, int32_t iSize ) 313int32_t Bu::Myriad::blockRead( int32_t iBlock, int32_t iStart,
314 void *pTarget, int32_t iSize )
280{ 315{
281 int32_t iUpperSize = iBlockSize - (iStart%iBlockSize); 316 int32_t iUpperSize = iBlockSize - (iStart%iBlockSize);
282 Bu::println("Max size within block: %1 vs %2 (start=%3, blocksize=%4)") 317 Bu::println("Max read within block: %1 vs %2 (start=%3, blocksize=%4)")
283 .arg( iUpperSize ).arg( iSize ) 318 .arg( iUpperSize ).arg( iSize )
284 .arg( iStart ).arg( iBlockSize ); 319 .arg( iStart ).arg( iBlockSize );
285 320
286 int32_t iAmnt = std::min( iSize, iUpperSize ); 321 int32_t iAmnt = std::min( iSize, iUpperSize );
287 Bu::MutexLocker l( mBacking ); 322 Bu::MutexLocker l( mBacking );
288 rBacking.setPos( iStart ); 323 rBacking.setPos( iBlockSize*iBlock + iStart );
289 324
290 return rBacking.read( pTarget, iAmnt ); 325 return rBacking.read( pTarget, iAmnt );
291} 326}
292 327
328int32_t Bu::Myriad::blockWrite( int32_t iBlock, int32_t iStart,
329 const void *pTarget, int32_t iSize )
330{
331 int32_t iUpperSize = iBlockSize - (iStart%iBlockSize);
332 Bu::println("Max write within block: %1 vs %2 (start=%3, blocksize=%4)")
333 .arg( iUpperSize ).arg( iSize )
334 .arg( iStart ).arg( iBlockSize );
335
336 int32_t iAmnt = std::min( iSize, iUpperSize );
337 Bu::MutexLocker l( mBacking );
338 rBacking.setPos( iBlock*iBlockSize + iStart );
339
340 return rBacking.write( pTarget, iAmnt );
341}
342
293///////// 343/////////
294// Bu::Myriad::Stream 344// Bu::Myriad::Stream
295// 345//
@@ -308,22 +358,71 @@ Bu::Myriad::Stream::~Stream()
308{ 358{
309} 359}
310 360
361int32_t Bu::Myriad::Stream::getSize() const
362{
363 Bu::MutexLocker l( mAccess );
364 return iSize;
365}
366
367int32_t Bu::Myriad::Stream::getBlockSize() const
368{
369 Bu::MutexLocker l( mAccess );
370 return rParent.iBlockSize;
371}
372
373Bu::Myriad::StreamId Bu::Myriad::Stream::getStreamId() const
374{
375 return iStream;
376}
377
378int32_t Bu::Myriad::Stream::getOpenCount() const
379{
380 Bu::MutexLocker l( mAccess );
381 return iOpenCount;
382}
383
384void Bu::Myriad::Stream::setSize( int32_t iNewSize )
385{
386 // Two possible modes, shrink or grow.
387 Bu::MutexLocker l( mAccess );
388 if( iNewSize < iSize )
389 {
390 // Shrink it
391 int iNewBlocks = Bu::blkDiv( iNewSize, rParent.iBlockSize );
392 while( aBlocks.getSize() > iNewBlocks )
393 {
394 rParent.releaseBlock( aBlocks.last(), false );
395 aBlocks.eraseLast();
396 }
397 iSize = iNewSize;
398 }
399 else if( iNewSize > iSize )
400 {
401 // Grow it
402 int iNewBlocks = Bu::blkDiv( iNewSize, rParent.iBlockSize );
403 while( aBlocks.getSize() < iNewBlocks )
404 {
405 aBlocks.append( rParent.allocateBlock() );
406 }
407 iSize = iNewSize;
408 }
409}
410
311int32_t Bu::Myriad::Stream::read( int32_t iStart, void *pTarget, 411int32_t Bu::Myriad::Stream::read( int32_t iStart, void *pTarget,
312 int32_t iSize ) 412 int32_t iSize )
313{ 413{
314 int32_t iPos = iStart;
315 int32_t iRead = 0; 414 int32_t iRead = 0;
316 Bu::MutexLocker l( mAccess ); 415 Bu::MutexLocker l( mAccess );
317 while( iStart > 0 ) 416 while( iSize > 0 )
318 { 417 {
319 int32_t iBlock = aBlocks[iStart/rParent.iBlockSize]; 418 int32_t iBlock = aBlocks[iStart/rParent.iBlockSize];
320 int32_t iOffset = iPos % rParent.iBlockSize;
321 int32_t iChunkRead = rParent.blockRead( 419 int32_t iChunkRead = rParent.blockRead(
322 iBlock*rParent.iBlockSize+iOffset, pTarget, iSize 420 iBlock, iStart%rParent.iBlockSize, pTarget, iSize
323 ); 421 );
324 if( iChunkRead == 0 ) 422 if( iChunkRead == 0 )
325 break; 423 break;
326 iRead += iChunkRead; 424 iRead += iChunkRead;
425 iStart += iChunkRead;
327 reinterpret_cast<ptrdiff_t &>(pTarget) += iChunkRead; 426 reinterpret_cast<ptrdiff_t &>(pTarget) += iChunkRead;
328 iSize -= iChunkRead; 427 iSize -= iChunkRead;
329 } 428 }
@@ -331,6 +430,36 @@ int32_t Bu::Myriad::Stream::read( int32_t iStart, void *pTarget,
331 return iRead; 430 return iRead;
332} 431}
333 432
433int32_t Bu::Myriad::Stream::write( int32_t iStart, const void *pTarget,
434 int32_t iSize )
435{
436 int32_t iWrite = 0;
437 Bu::MutexLocker l( mAccess );
438 while( iSize > 0 )
439 {
440 int32_t iBlockIdx = iStart/rParent.iBlockSize;
441 int32_t iBlock = aBlocks[iBlockIdx];
442 int32_t iChunkWrite = rParent.blockWrite(
443 iBlock, iStart%rParent.iBlockSize, pTarget, iSize
444 );
445 if( iChunkWrite == 0 )
446 break;
447 iWrite += iChunkWrite;
448 iStart += iChunkWrite;
449 reinterpret_cast<ptrdiff_t &>(pTarget) += iChunkWrite;
450 iSize -= iChunkWrite;
451 }
452
453 return iWrite;
454}
455
456Bu::String Bu::Myriad::Stream::getLocation() const
457{
458 Bu::MutexLocker l( mAccess );
459 return Bu::String("%1:stream %2")\
460 .arg( rParent.getLocation() ).arg( iStream );
461}
462
334void Bu::Myriad::Stream::open() 463void Bu::Myriad::Stream::open()
335{ 464{
336 Bu::MutexLocker l( mAccess ); 465 Bu::MutexLocker l( mAccess );