userlibandfileserver/fileserver/sfat32/sl_cache.cpp
branchRCL_3
changeset 62 4a8fed1c0ef6
parent 33 0173bcd7697c
child 245 647ab20fee2e
--- a/userlibandfileserver/fileserver/sfat32/sl_cache.cpp	Tue Feb 02 01:24:03 2010 +0200
+++ b/userlibandfileserver/fileserver/sfat32/sl_cache.cpp	Sat Feb 20 00:10:51 2010 +0200
@@ -28,19 +28,12 @@
 CWTCachePage* CWTCachePage::NewL(TUint32 aPageSizeLog2)
     {
     CWTCachePage* pSelf = new (ELeave)CWTCachePage;
-    pSelf->ConstructL(aPageSizeLog2);
+    
+    pSelf->iData.CreateMaxL(1 << aPageSizeLog2);
 
     return pSelf;
     }
 
-/**
-    2nd stage constructor.
-    @param  aPageSizeLog2 Log2(cache page size in bytes)
-*/
-void CWTCachePage::ConstructL(TUint32 aPageSizeLog2)
-    {
-    iData.CreateMaxL(1 << aPageSizeLog2);
-    }
 
 CWTCachePage::CWTCachePage()
     {
@@ -82,46 +75,45 @@
 
     @param  aDrive  reference to the driver for media access.
     @param  aNumPages     number of cache pages to be created
-    @param  aPageSizeLog2 Log2 of the page size in bytes
+    @param  aPageSizeLog2       Log2 of the page size in bytes, this is the cache read granularity
+    @param  aWrGranularityLog2  Log2(cache write granularity)
     
     @return a pointer to the created object.
 */
-CMediaWTCache* CMediaWTCache::NewL(TDriveInterface& aDrive, TUint32 aNumPages, TUint32 aPageSizeLog2)
+CMediaWTCache* CMediaWTCache::NewL(TDriveInterface& aDrive, TUint32 aNumPages, TUint32 aPageSizeLog2, TUint32 aWrGranularityLog2)
     {
-#ifndef ENABLE_DEDICATED_DIR_CACHE    
-    //-- dedicated directory cache isn't enabled
-    (void)aDrive; //-- supress compiler's warning
-    (void)aClusterSizeLog2;
-    return NULL;
-#else    
-
-    //-- dedicated directory cache is enabled, create it
-    ASSERT(aPageSizeLog2);
-    ASSERT(aNumPages);
 
     CMediaWTCache* pSelf = new (ELeave) CMediaWTCache(aDrive);
     
     CleanupStack::PushL(pSelf);
-    pSelf->ConstructL(aNumPages, aPageSizeLog2);
+    pSelf->InitialiseL(aNumPages, aPageSizeLog2, aWrGranularityLog2);
     CleanupStack::Pop();
 
     return pSelf;
-
-#endif
     }
 
 /**
     2nd stage constructor.
     @param  aNumPages number of pages in the directory cache.
-    @param  aPageSizeLog2 Log2(single cache page size in bytes)
+    @param  aPageSizeLog2       Log2 of the page size in bytes, this is the cache read granularity
+    @param  aWrGranularityLog2  Log2(cache write granularity)
 */
-void CMediaWTCache::ConstructL(TUint32 aNumPages, TUint32 aPageSizeLog2)
+void CMediaWTCache::InitialiseL(TUint32 aNumPages, TUint32 aPageSizeLog2, TUint32 aWrGranularityLog2)
     {
     ASSERT(aNumPages && aPageSizeLog2);
     
-    __PRINT2(_L("#CMediaWTCache::CreateL() Pages=%d, PageSize=%d"), aNumPages, 1<<aPageSizeLog2);
+    __PRINT3(_L("#CMediaWTCache::InitialiseL() Pages=%d, PageSzLog2=%d, WrGrLog2:%d"), aNumPages, aPageSizeLog2, aWrGranularityLog2);
+
+    ASSERT(aNumPages);
+    ASSERT(aPageSizeLog2);
+    
+    if(aWrGranularityLog2)
+        {
+        ASSERT(aWrGranularityLog2 >= KDefSectorSzLog2 && aWrGranularityLog2 <= aPageSizeLog2);
+        }
     
     iPageSizeLog2 = aPageSizeLog2; 
+    iWrGranularityLog2 = aWrGranularityLog2;
 
     //-- create cache pages
     for(TUint cnt=0; cnt<aNumPages; ++cnt)
@@ -369,14 +361,12 @@
     
     @return 0 if aPosToSearch isn't cached, otherwise  cache page size in bytes (see also aCachedPosStart).
 */
-TUint32 CMediaWTCache::PosCached(const TInt64& aPosToSearch, TInt64& aCachedPosStart)
+TUint32 CMediaWTCache::PosCached(TInt64 aPosToSearch)
     {
     TInt nPage = FindPageByPos(aPosToSearch);
     if(nPage <0 )
         return 0; //-- cache page containing aPos not found
 
-    aCachedPosStart = iPages[nPage]->iStartPos;
-    
     return PageSize();
     }
 
@@ -483,9 +473,35 @@
     if(dataLen <= bytesToPageEnd)
         {//-- data section completely fits to the cache page
         Mem::Copy(pPage->PtrInCachePage(aPos), pData, dataLen);   //-- update cache
+
+        //-- make small write a multiple of a write granularity size (if it is used at all)
+        //-- this is not the best way to use write granularity, but we would need to refactor cache pages code to make it normal
+        TPtrC8 desBlock(aDes);
+        
+        if(iWrGranularityLog2)
+            {//-- write granularity is used
+            const TInt64  newPos = (aPos >> iWrGranularityLog2) << iWrGranularityLog2; //-- round position down to the write granularity size
+            TUint32 newLen = (TUint32)(aPos - newPos)+dataLen;  //-- round block size up to the write granularity size
+            newLen = RoundUp(newLen, iWrGranularityLog2);
+       
+            const TUint8* pd = pPage->PtrInCachePage(newPos);
+            desBlock.Set(pd, newLen);
+            aPos = newPos;
+            }
+
+
+        //-- write data to the media
+        const TInt nErr = iDrive.WriteCritical(aPos, desBlock); 
+        if(nErr != KErrNone)
+            {//-- some serious problem occured during writing, invalidate cache.
+            InvalidateCache();
+            User::Leave(nErr);
+            }
+
         }
     else
         {//-- Data to be written cross cache page boundary or probably we have more than 1 page to write
+         //-- this is a very rare case.   
 
         TInt64  currMediaPos(aPos); //-- current media position
 
@@ -523,9 +539,6 @@
             Mem::Copy(pPage->PtrInCachePage(currMediaPos), pData, dataLen);
             }
 
-        }// else(dataLen <= bytesToPageEnd)
-
-    
     //-- write data to the media
     const TInt nErr = iDrive.WriteCritical(aPos,aDes); 
     if(nErr != KErrNone)
@@ -534,6 +547,10 @@
         User::Leave(nErr);
         }
 
+        }// else(dataLen <= bytesToPageEnd)
+
+    
+
     MakePageLRU(nPage); //-- push the page to the top of the priority list
     }