userlibandfileserver/fileserver/sfat32/sl_cache.cpp
branchRCL_3
changeset 19 4a8fed1c0ef6
parent 6 0173bcd7697c
child 42 a179b74831c9
equal deleted inserted replaced
15:2d65c2f76d7b 19:4a8fed1c0ef6
    26     @return a pointer to the created object.
    26     @return a pointer to the created object.
    27 */
    27 */
    28 CWTCachePage* CWTCachePage::NewL(TUint32 aPageSizeLog2)
    28 CWTCachePage* CWTCachePage::NewL(TUint32 aPageSizeLog2)
    29     {
    29     {
    30     CWTCachePage* pSelf = new (ELeave)CWTCachePage;
    30     CWTCachePage* pSelf = new (ELeave)CWTCachePage;
    31     pSelf->ConstructL(aPageSizeLog2);
    31     
       
    32     pSelf->iData.CreateMaxL(1 << aPageSizeLog2);
    32 
    33 
    33     return pSelf;
    34     return pSelf;
    34     }
    35     }
    35 
    36 
    36 /**
       
    37     2nd stage constructor.
       
    38     @param  aPageSizeLog2 Log2(cache page size in bytes)
       
    39 */
       
    40 void CWTCachePage::ConstructL(TUint32 aPageSizeLog2)
       
    41     {
       
    42     iData.CreateMaxL(1 << aPageSizeLog2);
       
    43     }
       
    44 
    37 
    45 CWTCachePage::CWTCachePage()
    38 CWTCachePage::CWTCachePage()
    46     {
    39     {
    47     iStartPos = 0xDeadDeadul;
    40     iStartPos = 0xDeadDeadul;
    48     iValid  = 0;
    41     iValid  = 0;
    80 /**
    73 /**
    81     Directory cache factory function.
    74     Directory cache factory function.
    82 
    75 
    83     @param  aDrive  reference to the driver for media access.
    76     @param  aDrive  reference to the driver for media access.
    84     @param  aNumPages     number of cache pages to be created
    77     @param  aNumPages     number of cache pages to be created
    85     @param  aPageSizeLog2 Log2 of the page size in bytes
    78     @param  aPageSizeLog2       Log2 of the page size in bytes, this is the cache read granularity
       
    79     @param  aWrGranularityLog2  Log2(cache write granularity)
    86     
    80     
    87     @return a pointer to the created object.
    81     @return a pointer to the created object.
    88 */
    82 */
    89 CMediaWTCache* CMediaWTCache::NewL(TDriveInterface& aDrive, TUint32 aNumPages, TUint32 aPageSizeLog2)
    83 CMediaWTCache* CMediaWTCache::NewL(TDriveInterface& aDrive, TUint32 aNumPages, TUint32 aPageSizeLog2, TUint32 aWrGranularityLog2)
    90     {
    84     {
    91 #ifndef ENABLE_DEDICATED_DIR_CACHE    
       
    92     //-- dedicated directory cache isn't enabled
       
    93     (void)aDrive; //-- supress compiler's warning
       
    94     (void)aClusterSizeLog2;
       
    95     return NULL;
       
    96 #else    
       
    97 
       
    98     //-- dedicated directory cache is enabled, create it
       
    99     ASSERT(aPageSizeLog2);
       
   100     ASSERT(aNumPages);
       
   101 
    85 
   102     CMediaWTCache* pSelf = new (ELeave) CMediaWTCache(aDrive);
    86     CMediaWTCache* pSelf = new (ELeave) CMediaWTCache(aDrive);
   103     
    87     
   104     CleanupStack::PushL(pSelf);
    88     CleanupStack::PushL(pSelf);
   105     pSelf->ConstructL(aNumPages, aPageSizeLog2);
    89     pSelf->InitialiseL(aNumPages, aPageSizeLog2, aWrGranularityLog2);
   106     CleanupStack::Pop();
    90     CleanupStack::Pop();
   107 
    91 
   108     return pSelf;
    92     return pSelf;
   109 
       
   110 #endif
       
   111     }
    93     }
   112 
    94 
   113 /**
    95 /**
   114     2nd stage constructor.
    96     2nd stage constructor.
   115     @param  aNumPages number of pages in the directory cache.
    97     @param  aNumPages number of pages in the directory cache.
   116     @param  aPageSizeLog2 Log2(single cache page size in bytes)
    98     @param  aPageSizeLog2       Log2 of the page size in bytes, this is the cache read granularity
   117 */
    99     @param  aWrGranularityLog2  Log2(cache write granularity)
   118 void CMediaWTCache::ConstructL(TUint32 aNumPages, TUint32 aPageSizeLog2)
   100 */
       
   101 void CMediaWTCache::InitialiseL(TUint32 aNumPages, TUint32 aPageSizeLog2, TUint32 aWrGranularityLog2)
   119     {
   102     {
   120     ASSERT(aNumPages && aPageSizeLog2);
   103     ASSERT(aNumPages && aPageSizeLog2);
   121     
   104     
   122     __PRINT2(_L("#CMediaWTCache::CreateL() Pages=%d, PageSize=%d"), aNumPages, 1<<aPageSizeLog2);
   105     __PRINT3(_L("#CMediaWTCache::InitialiseL() Pages=%d, PageSzLog2=%d, WrGrLog2:%d"), aNumPages, aPageSizeLog2, aWrGranularityLog2);
       
   106 
       
   107     ASSERT(aNumPages);
       
   108     ASSERT(aPageSizeLog2);
       
   109     
       
   110     if(aWrGranularityLog2)
       
   111         {
       
   112         ASSERT(aWrGranularityLog2 >= KDefSectorSzLog2 && aWrGranularityLog2 <= aPageSizeLog2);
       
   113         }
   123     
   114     
   124     iPageSizeLog2 = aPageSizeLog2; 
   115     iPageSizeLog2 = aPageSizeLog2; 
       
   116     iWrGranularityLog2 = aWrGranularityLog2;
   125 
   117 
   126     //-- create cache pages
   118     //-- create cache pages
   127     for(TUint cnt=0; cnt<aNumPages; ++cnt)
   119     for(TUint cnt=0; cnt<aNumPages; ++cnt)
   128         {
   120         {
   129         CWTCachePage* pPage = CWTCachePage::NewL(aPageSizeLog2);
   121         CWTCachePage* pPage = CWTCachePage::NewL(aPageSizeLog2);
   367     @param  aPosToSearch    linear media position to lookup in the cache
   359     @param  aPosToSearch    linear media position to lookup in the cache
   368     @param  aCachedPosStart if "aPosToSearch" is cached, here will be media position of this page start
   360     @param  aCachedPosStart if "aPosToSearch" is cached, here will be media position of this page start
   369     
   361     
   370     @return 0 if aPosToSearch isn't cached, otherwise  cache page size in bytes (see also aCachedPosStart).
   362     @return 0 if aPosToSearch isn't cached, otherwise  cache page size in bytes (see also aCachedPosStart).
   371 */
   363 */
   372 TUint32 CMediaWTCache::PosCached(const TInt64& aPosToSearch, TInt64& aCachedPosStart)
   364 TUint32 CMediaWTCache::PosCached(TInt64 aPosToSearch)
   373     {
   365     {
   374     TInt nPage = FindPageByPos(aPosToSearch);
   366     TInt nPage = FindPageByPos(aPosToSearch);
   375     if(nPage <0 )
   367     if(nPage <0 )
   376         return 0; //-- cache page containing aPos not found
   368         return 0; //-- cache page containing aPos not found
   377 
   369 
   378     aCachedPosStart = iPages[nPage]->iStartPos;
       
   379     
       
   380     return PageSize();
   370     return PageSize();
   381     }
   371     }
   382 
   372 
   383 /**
   373 /**
   384     Read data from the media through the directory cache.
   374     Read data from the media through the directory cache.
   481     const TUint32 bytesToPageEnd = (TUint32)(pPage->iStartPos+PageSize() - aPos); //-- number of bytes from aPos to the end of the page
   471     const TUint32 bytesToPageEnd = (TUint32)(pPage->iStartPos+PageSize() - aPos); //-- number of bytes from aPos to the end of the page
   482 //    __PRINT5(_L("CMediaWTCache::WriteL: aPos=%lx, aLength=%x, page:%lx, pageSz:%x, bytesToPageEnd=%x"), aPos, dataLen, pPage->iStartPos, PageSz, bytesToPageEnd);
   472 //    __PRINT5(_L("CMediaWTCache::WriteL: aPos=%lx, aLength=%x, page:%lx, pageSz:%x, bytesToPageEnd=%x"), aPos, dataLen, pPage->iStartPos, PageSz, bytesToPageEnd);
   483     if(dataLen <= bytesToPageEnd)
   473     if(dataLen <= bytesToPageEnd)
   484         {//-- data section completely fits to the cache page
   474         {//-- data section completely fits to the cache page
   485         Mem::Copy(pPage->PtrInCachePage(aPos), pData, dataLen);   //-- update cache
   475         Mem::Copy(pPage->PtrInCachePage(aPos), pData, dataLen);   //-- update cache
       
   476 
       
   477         //-- make small write a multiple of a write granularity size (if it is used at all)
       
   478         //-- this is not the best way to use write granularity, but we would need to refactor cache pages code to make it normal
       
   479         TPtrC8 desBlock(aDes);
       
   480         
       
   481         if(iWrGranularityLog2)
       
   482             {//-- write granularity is used
       
   483             const TInt64  newPos = (aPos >> iWrGranularityLog2) << iWrGranularityLog2; //-- round position down to the write granularity size
       
   484             TUint32 newLen = (TUint32)(aPos - newPos)+dataLen;  //-- round block size up to the write granularity size
       
   485             newLen = RoundUp(newLen, iWrGranularityLog2);
       
   486        
       
   487             const TUint8* pd = pPage->PtrInCachePage(newPos);
       
   488             desBlock.Set(pd, newLen);
       
   489             aPos = newPos;
       
   490             }
       
   491 
       
   492 
       
   493         //-- write data to the media
       
   494         const TInt nErr = iDrive.WriteCritical(aPos, desBlock); 
       
   495         if(nErr != KErrNone)
       
   496             {//-- some serious problem occured during writing, invalidate cache.
       
   497             InvalidateCache();
       
   498             User::Leave(nErr);
       
   499             }
       
   500 
   486         }
   501         }
   487     else
   502     else
   488         {//-- Data to be written cross cache page boundary or probably we have more than 1 page to write
   503         {//-- Data to be written cross cache page boundary or probably we have more than 1 page to write
       
   504          //-- this is a very rare case.   
   489 
   505 
   490         TInt64  currMediaPos(aPos); //-- current media position
   506         TInt64  currMediaPos(aPos); //-- current media position
   491 
   507 
   492         //-- 1. update the current page
   508         //-- 1. update the current page
   493         Mem::Copy(pPage->PtrInCachePage(currMediaPos), pData, bytesToPageEnd);
   509         Mem::Copy(pPage->PtrInCachePage(currMediaPos), pData, bytesToPageEnd);
   521             pPage = iPages[nPage];
   537             pPage = iPages[nPage];
   522 
   538 
   523             Mem::Copy(pPage->PtrInCachePage(currMediaPos), pData, dataLen);
   539             Mem::Copy(pPage->PtrInCachePage(currMediaPos), pData, dataLen);
   524             }
   540             }
   525 
   541 
   526         }// else(dataLen <= bytesToPageEnd)
       
   527 
       
   528     
       
   529     //-- write data to the media
   542     //-- write data to the media
   530     const TInt nErr = iDrive.WriteCritical(aPos,aDes); 
   543     const TInt nErr = iDrive.WriteCritical(aPos,aDes); 
   531     if(nErr != KErrNone)
   544     if(nErr != KErrNone)
   532         {//-- some serious problem occured during writing, invalidate cache.
   545         {//-- some serious problem occured during writing, invalidate cache.
   533         InvalidateCache();
   546         InvalidateCache();
   534         User::Leave(nErr);
   547         User::Leave(nErr);
   535         }
   548         }
   536 
   549 
       
   550         }// else(dataLen <= bytesToPageEnd)
       
   551 
       
   552     
       
   553 
   537     MakePageLRU(nPage); //-- push the page to the top of the priority list
   554     MakePageLRU(nPage); //-- push the page to the top of the priority list
   538     }
   555     }
   539 
   556 
   540 
   557 
   541 
   558