diff -r 2d65c2f76d7b -r 4a8fed1c0ef6 userlibandfileserver/fileserver/sfat32/sl_dir_cache.cpp --- a/userlibandfileserver/fileserver/sfat32/sl_dir_cache.cpp Tue Feb 02 01:24:03 2010 +0200 +++ b/userlibandfileserver/fileserver/sfat32/sl_dir_cache.cpp Sat Feb 20 00:10:51 2010 +0200 @@ -39,11 +39,11 @@ @param aStartRamAddr the start address in the ram that this page content lives */ TDynamicDirCachePage::TDynamicDirCachePage(CDynamicDirCache* aOwnerCache, TInt64 aStartMedPos, TUint8* aStartRamAddr) -:iStartMedPos(aStartMedPos), -iStartRamAddr(aStartRamAddr), -iOwnerCache(aOwnerCache), -iValid(EFalse), -iLocked(EFalse) + :iStartMedPos(aStartMedPos), + iStartRamAddr(aStartRamAddr), + iOwnerCache(aOwnerCache), + iValid(EFalse), + iLocked(EFalse) { //__PRINT3(_L("TDynamicDirCachePage::TDynamicDirCachePage(aStartMedPos=%lx, aStartRamAddr=0x%X, aPageSize=%u)"), aStartMedPos, aStartRamAddr, PageSizeInBytes()); iType = EUnknown; @@ -104,20 +104,22 @@ @param aDrive local drive interface to read/write media @param aMinPageNum the minimum page number for the cache, includes iActive page and locked pages. @param aMaxPageNum the maximum page number for the cache, includes iActive page, locked pages and unlocked pages. -@param aPageSizeInBytesLog2 the log2 value of page size in bytes, assumes page size is always a power of two + @param aPageSizeInBytesLog2 Log2 of the page size in bytes, this is the cache read granularity + @param aWrGranularityLog2 Log2(cache write granularity) */ -CDynamicDirCache::CDynamicDirCache(TDriveInterface& aDrive, TUint32 aMinPageNum, TUint32 aMaxPageNum, TUint32 aPageSizeInBytesLog2) -:iPageSizeLog2(aPageSizeInBytesLog2), -iMinSizeInPages(aMinPageNum), -iMaxSizeInPages(aMaxPageNum), -iDrive(aDrive), -iLockedQ(_FOFF(TDynamicDirCachePage, iLink)), -iUnlockedQ(_FOFF(TDynamicDirCachePage, iLink)), -iLockedQCount(0), -iUnlockedQCount(0), -iHashFunction(HashFunction), -iIdentityFunction(IdentityFunction), -iLookupTable(iHashFunction, iIdentityFunction) +CDynamicDirCache::CDynamicDirCache(TDriveInterface& aDrive, TUint32 aMinPageNum, TUint32 aMaxPageNum, TUint32 aPageSizeInBytesLog2, TUint32 aWrGranularityLog2) + :iPageSizeLog2(aPageSizeInBytesLog2), + iWrGranularityLog2(aWrGranularityLog2), + iMinSizeInPages(aMinPageNum), + iMaxSizeInPages(aMaxPageNum), + iDrive(aDrive), + iLockedQ(_FOFF(TDynamicDirCachePage, iLink)), + iUnlockedQ(_FOFF(TDynamicDirCachePage, iLink)), + iLockedQCount(0), + iUnlockedQCount(0), + iHashFunction(HashFunction), + iIdentityFunction(IdentityFunction), + iLookupTable(iHashFunction, iIdentityFunction) { iPageSizeInBytes = 1 << aPageSizeInBytesLog2; iCacheDisabled = EFalse; @@ -174,10 +176,10 @@ /** Static factory function of CDynamicDirCache */ -CDynamicDirCache* CDynamicDirCache::NewL(TDriveInterface& aDrive, TUint32 aMinPageNum, TUint32 aMaxPageNum, TUint32 aPageSizeLog2, const TDesC& aClientName) +CDynamicDirCache* CDynamicDirCache::NewL(TDriveInterface& aDrive, TUint32 aMinPageNum, TUint32 aMaxPageNum, TUint32 aPageSizeLog2, TUint32 aWrGranularityLog2, const TDesC& aClientName) { __PRINT3(_L("CDynamicDirCache::NewL(MinPageNum=%u, MaxPageNum=%u, page=%u)"), aMinPageNum, aMaxPageNum, 1<ConstructL(aClientName); CleanupStack::Pop(); @@ -338,7 +340,7 @@ @param aDataLen the length of the content to be written. @pre aDataLen should be no more than page size. */ -void CDynamicDirCache::WriteDataOntoSinglePageL(TInt64 aPos, const TUint8* aData, TUint32 aDataLen) +TDynamicDirCachePage* CDynamicDirCache::WriteDataOntoSinglePageL(TInt64 aPos, const TUint8* aData, TUint32 aDataLen) { ASSERT(aDataLen <= iPageSizeInBytes); //-- the data section is in the cache page entirely, take data directly from the cache @@ -378,7 +380,8 @@ // always make writting events MRU DoMakePageMRU(aPos); - return; + + return pPage; } /** @@ -407,11 +410,37 @@ // __PRINT5(_L("CDynamicDirCache::WriteL: aPos=%lx, aLength=%x, page:%lx, pageSz:%x, bytesToPageEnd=%x"), aPos, dataLen, pageStartMedPos, PageSz, bytesToPageEnd); if(dataLen <= bytesToPageEnd) - { - WriteDataOntoSinglePageL(aPos, pData, dataLen); + {//-- 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 + + TDynamicDirCachePage* pPage = WriteDataOntoSinglePageL(aPos, pData, dataLen); + TPtrC8 desBlock(aDes); + + if(iWrGranularityLog2) + {//-- write granularity is used + const TInt64 newPos = (aPos >> iWrGranularityLog2) << iWrGranularityLog2; //-- round position down to the granularity unit size + TUint32 newLen = (TUint32)(aPos - newPos)+dataLen; + newLen = RoundUp(newLen, iWrGranularityLog2); + + const TUint8* pd = pPage->PtrInPage(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. __PRINT(_L("CDynamicDirCache::WriteL() CROSS PAGE!")); //-- Data to be written cross cache page boundary or probably we have more than 1 page to write @@ -439,8 +468,6 @@ { WriteDataOntoSinglePageL(currMediaPos, pData, dataLen); } - }// else(dataLen <= bytesToPageEnd) - //-- write data to the media const TInt nErr = iDrive.WriteCritical(aPos,aDes); @@ -449,6 +476,11 @@ InvalidateCache(); User::Leave(nErr); } + + + }// else(dataLen <= bytesToPageEnd) + + } /** @@ -518,7 +550,7 @@ Implementation of pure virtual function. @see MWTCacheInterface::PosCached() */ -TUint32 CDynamicDirCache::PosCached(const TInt64& aPos, TInt64& aCachedPosStart) +TUint32 CDynamicDirCache::PosCached(TInt64 aPos) { const TInt64 pageStartMedPos = CalcPageStartPos(aPos); @@ -535,7 +567,6 @@ // __PRINT1(_L("CDynamicDirCache::PosCached: page(0x%lx) found on Unlocked Queue!"), aPos); // have to unlock it before returning, otherwise there will be memory leak UnlockPage(pPage); - aCachedPosStart = pPage->StartPos(); return pPage->PageSizeInBytes(); } else // if the unlocked page is not valid anymore, remove it @@ -551,7 +582,6 @@ else if (pPage) { __PRINT1(_L("CDynamicDirCache::PosCached: page(0x%lx) on Locked Queue!"), aPos); - aCachedPosStart = pPage->StartPos(); return pPage->PageSizeInBytes(); }