userlibandfileserver/fileserver/sfat32/sl_dir_cache.cpp
branchCompilerCompatibility
changeset 77 c4d65d91ad0c
parent 62 4a8fed1c0ef6
child 80 597aaf25e343
equal deleted inserted replaced
74:741dcdf88ba9 77:c4d65d91ad0c
    37 @param	aOwnerCache	pointer of the cache that owns this page
    37 @param	aOwnerCache	pointer of the cache that owns this page
    38 @param	aStartMedPos	the start address on the media that this page caches
    38 @param	aStartMedPos	the start address on the media that this page caches
    39 @param	aStartRamAddr	the start address in the ram that this page content lives
    39 @param	aStartRamAddr	the start address in the ram that this page content lives
    40 */
    40 */
    41 TDynamicDirCachePage::TDynamicDirCachePage(CDynamicDirCache* aOwnerCache, TInt64 aStartMedPos, TUint8* aStartRamAddr)
    41 TDynamicDirCachePage::TDynamicDirCachePage(CDynamicDirCache* aOwnerCache, TInt64 aStartMedPos, TUint8* aStartRamAddr)
    42 :iStartMedPos(aStartMedPos),
    42                      :iStartMedPos(aStartMedPos),
    43 iStartRamAddr(aStartRamAddr),
    43                       iStartRamAddr(aStartRamAddr),
    44 iOwnerCache(aOwnerCache),
    44                       iOwnerCache(aOwnerCache),
    45 iValid(EFalse),
    45                       iValid(EFalse),
    46 iLocked(EFalse)
    46                       iLocked(EFalse)
    47 	{
    47 	{
    48 	//__PRINT3(_L("TDynamicDirCachePage::TDynamicDirCachePage(aStartMedPos=%lx, aStartRamAddr=0x%X, aPageSize=%u)"), aStartMedPos, aStartRamAddr, PageSizeInBytes());
    48 	//__PRINT3(_L("TDynamicDirCachePage::TDynamicDirCachePage(aStartMedPos=%lx, aStartRamAddr=0x%X, aPageSize=%u)"), aStartMedPos, aStartRamAddr, PageSizeInBytes());
    49 	iType = EUnknown;
    49 	iType = EUnknown;
    50 	}
    50 	}
    51 
    51 
   102 /**
   102 /**
   103 Constructor of CDynamicDirCache.
   103 Constructor of CDynamicDirCache.
   104 @param	aDrive	local drive interface to read/write media
   104 @param	aDrive	local drive interface to read/write media
   105 @param	aMinPageNum	the minimum page number for the cache, includes iActive page and locked pages.
   105 @param	aMinPageNum	the minimum page number for the cache, includes iActive page and locked pages.
   106 @param	aMaxPageNum	the maximum page number for the cache, includes iActive page, locked pages and unlocked pages.
   106 @param	aMaxPageNum	the maximum page number for the cache, includes iActive page, locked pages and unlocked pages.
   107 @param	aPageSizeInBytesLog2	the log2 value of page size in bytes, assumes page size is always a power of two
   107     @param	aPageSizeInBytesLog2	Log2 of the page size in bytes, this is the cache read granularity
   108 */
   108     @param  aWrGranularityLog2      Log2(cache write granularity)
   109 CDynamicDirCache::CDynamicDirCache(TDriveInterface& aDrive, TUint32 aMinPageNum, TUint32 aMaxPageNum, TUint32 aPageSizeInBytesLog2)
   109 */
   110 :iPageSizeLog2(aPageSizeInBytesLog2),
   110 CDynamicDirCache::CDynamicDirCache(TDriveInterface& aDrive, TUint32 aMinPageNum, TUint32 aMaxPageNum, TUint32 aPageSizeInBytesLog2, TUint32 aWrGranularityLog2)
   111 iMinSizeInPages(aMinPageNum),
   111                  :iPageSizeLog2(aPageSizeInBytesLog2),
   112 iMaxSizeInPages(aMaxPageNum),
   112                   iWrGranularityLog2(aWrGranularityLog2),
   113 iDrive(aDrive),
   113                   iMinSizeInPages(aMinPageNum),
   114 iLockedQ(_FOFF(TDynamicDirCachePage, iLink)),
   114                   iMaxSizeInPages(aMaxPageNum),
   115 iUnlockedQ(_FOFF(TDynamicDirCachePage, iLink)),
   115                   iDrive(aDrive),
   116 iLockedQCount(0),
   116                   iLockedQ(_FOFF(TDynamicDirCachePage, iLink)),
   117 iUnlockedQCount(0),
   117                   iUnlockedQ(_FOFF(TDynamicDirCachePage, iLink)),
   118 iHashFunction(HashFunction),
   118                   iLockedQCount(0),
   119 iIdentityFunction(IdentityFunction),
   119                   iUnlockedQCount(0),
   120 iLookupTable(iHashFunction, iIdentityFunction)
   120                   iHashFunction(HashFunction),
       
   121                   iIdentityFunction(IdentityFunction),
       
   122                   iLookupTable(iHashFunction, iIdentityFunction)
   121 	{
   123 	{
   122 	iPageSizeInBytes = 1 << aPageSizeInBytesLog2;
   124 	iPageSizeInBytes = 1 << aPageSizeInBytesLog2;
   123 	iCacheDisabled = EFalse;
   125 	iCacheDisabled = EFalse;
   124     iMinCacheSizeInBytes = aMinPageNum << aPageSizeInBytesLog2;
   126     iMinCacheSizeInBytes = aMinPageNum << aPageSizeInBytesLog2;
   125     iMaxCacheSizeInBytes = aMaxPageNum << aPageSizeInBytesLog2;
   127     iMaxCacheSizeInBytes = aMaxPageNum << aPageSizeInBytesLog2;
   172 	}
   174 	}
   173 
   175 
   174 /**
   176 /**
   175 Static factory function of CDynamicDirCache
   177 Static factory function of CDynamicDirCache
   176 */
   178 */
   177 CDynamicDirCache* CDynamicDirCache::NewL(TDriveInterface& aDrive, TUint32 aMinPageNum, TUint32 aMaxPageNum, TUint32 aPageSizeLog2, const TDesC& aClientName)
   179 CDynamicDirCache* CDynamicDirCache::NewL(TDriveInterface& aDrive, TUint32 aMinPageNum, TUint32 aMaxPageNum, TUint32 aPageSizeLog2, TUint32 aWrGranularityLog2, const TDesC& aClientName)
   178     {
   180     {
   179     __PRINT3(_L("CDynamicDirCache::NewL(MinPageNum=%u, MaxPageNum=%u, page=%u)"), aMinPageNum, aMaxPageNum, 1<<aPageSizeLog2);
   181     __PRINT3(_L("CDynamicDirCache::NewL(MinPageNum=%u, MaxPageNum=%u, page=%u)"), aMinPageNum, aMaxPageNum, 1<<aPageSizeLog2);
   180     CDynamicDirCache* pSelf = new (ELeave) CDynamicDirCache(aDrive, aMinPageNum, aMaxPageNum, aPageSizeLog2);
   182     CDynamicDirCache* pSelf = new (ELeave) CDynamicDirCache(aDrive, aMinPageNum, aMaxPageNum, aPageSizeLog2, aWrGranularityLog2);
   181     CleanupStack::PushL(pSelf);
   183     CleanupStack::PushL(pSelf);
   182     pSelf->ConstructL(aClientName);
   184     pSelf->ConstructL(aClientName);
   183     CleanupStack::Pop();
   185     CleanupStack::Pop();
   184     return pSelf;
   186     return pSelf;
   185     }
   187     }
   336 @param	aPos	the starting position of the media address to be write.
   338 @param	aPos	the starting position of the media address to be write.
   337 @param	aData	the starting address that the writing content lives in the ram.
   339 @param	aData	the starting address that the writing content lives in the ram.
   338 @param	aDataLen	the length of the content to be written.
   340 @param	aDataLen	the length of the content to be written.
   339 @pre	aDataLen	should be no more than page size.
   341 @pre	aDataLen	should be no more than page size.
   340 */
   342 */
   341 void CDynamicDirCache::WriteDataOntoSinglePageL(TInt64 aPos, const TUint8* aData, TUint32 aDataLen)
   343 TDynamicDirCachePage* CDynamicDirCache::WriteDataOntoSinglePageL(TInt64 aPos, const TUint8* aData, TUint32 aDataLen)
   342 	{
   344 	{
   343 	ASSERT(aDataLen <= iPageSizeInBytes);
   345 	ASSERT(aDataLen <= iPageSizeInBytes);
   344     //-- the data section is in the cache page entirely, take data directly from the cache
   346     //-- the data section is in the cache page entirely, take data directly from the cache
   345 	TDynamicDirCachePage* pPage = FindPageByPos(aPos);
   347 	TDynamicDirCachePage* pPage = FindPageByPos(aPos);
   346     if (pPage)
   348     if (pPage)
   376 		UnlockPage(pPage);
   378 		UnlockPage(pPage);
   377 		}
   379 		}
   378 
   380 
   379 	// always make writting events MRU
   381 	// always make writting events MRU
   380 	DoMakePageMRU(aPos);
   382 	DoMakePageMRU(aPos);
   381     return;
   383     
       
   384     return pPage;
   382 	}
   385 	}
   383 
   386 
   384 /**
   387 /**
   385 Implementation of pure virtual function.
   388 Implementation of pure virtual function.
   386 @see	MWTCacheInterface::WriteL()
   389 @see	MWTCacheInterface::WriteL()
   405     TUint32 bytesToPageEnd = (TUint32)(pageStartMedPos + PageSz - aPos);
   408     TUint32 bytesToPageEnd = (TUint32)(pageStartMedPos + PageSz - aPos);
   406 
   409 
   407 //    __PRINT5(_L("CDynamicDirCache::WriteL: aPos=%lx, aLength=%x, page:%lx, pageSz:%x, bytesToPageEnd=%x"), aPos, dataLen, pageStartMedPos, PageSz, bytesToPageEnd);
   410 //    __PRINT5(_L("CDynamicDirCache::WriteL: aPos=%lx, aLength=%x, page:%lx, pageSz:%x, bytesToPageEnd=%x"), aPos, dataLen, pageStartMedPos, PageSz, bytesToPageEnd);
   408 
   411 
   409     if(dataLen <= bytesToPageEnd)
   412     if(dataLen <= bytesToPageEnd)
   410         {
   413         {//-- make small write a multiple of a write granularity size (if it is used at all)
   411         WriteDataOntoSinglePageL(aPos, pData, dataLen);
   414          //-- this is not the best way to use write granularity, but we would need to refactor cache pages code to make it normal
       
   415         
       
   416         TDynamicDirCachePage* pPage = WriteDataOntoSinglePageL(aPos, pData, dataLen);
       
   417         TPtrC8 desBlock(aDes);
       
   418 
       
   419         if(iWrGranularityLog2)
       
   420             {//-- write granularity is used
       
   421             const TInt64  newPos = (aPos >> iWrGranularityLog2)  << iWrGranularityLog2; //-- round position down to the granularity unit size
       
   422             TUint32 newLen = (TUint32)(aPos - newPos)+dataLen;
       
   423             newLen = RoundUp(newLen, iWrGranularityLog2);
       
   424 
       
   425             const TUint8* pd = pPage->PtrInPage(newPos);
       
   426             desBlock.Set(pd, newLen);
       
   427             aPos = newPos;
       
   428             
       
   429             }
       
   430 
       
   431         //-- write data to the media
       
   432         const TInt nErr = iDrive.WriteCritical(aPos, desBlock);
       
   433         if(nErr != KErrNone)
       
   434             {//-- some serious problem occured during writing, invalidate cache.
       
   435             InvalidateCache();
       
   436             User::Leave(nErr);
       
   437             }
       
   438 
       
   439 
   412         }
   440         }
   413     else
   441     else
   414         {
   442         {//-- Data to be written cross cache page boundary or probably we have more than 1 page to write
       
   443          //-- this is a very rare case.   
   415         __PRINT(_L("CDynamicDirCache::WriteL() CROSS PAGE!"));
   444         __PRINT(_L("CDynamicDirCache::WriteL() CROSS PAGE!"));
   416 
   445 
   417         //-- Data to be written cross cache page boundary or probably we have more than 1 page to write
   446         //-- Data to be written cross cache page boundary or probably we have more than 1 page to write
   418         TInt64  currMediaPos(aPos);
   447         TInt64  currMediaPos(aPos);
   419 
   448 
   437         //-- 3. write the rest of the data
   466         //-- 3. write the rest of the data
   438         if(dataLen > 0)
   467         if(dataLen > 0)
   439             {
   468             {
   440             WriteDataOntoSinglePageL(currMediaPos, pData, dataLen);
   469             WriteDataOntoSinglePageL(currMediaPos, pData, dataLen);
   441             }
   470             }
   442         }// else(dataLen <= bytesToPageEnd)
       
   443 
       
   444 
   471 
   445     //-- write data to the media
   472     //-- write data to the media
   446     const TInt nErr = iDrive.WriteCritical(aPos,aDes);
   473     const TInt nErr = iDrive.WriteCritical(aPos,aDes);
   447     if(nErr != KErrNone)
   474     if(nErr != KErrNone)
   448         {//-- some serious problem occured during writing, invalidate cache.
   475         {//-- some serious problem occured during writing, invalidate cache.
   449         InvalidateCache();
   476         InvalidateCache();
   450         User::Leave(nErr);
   477         User::Leave(nErr);
   451         }
   478         }
       
   479 
       
   480 
       
   481         }// else(dataLen <= bytesToPageEnd)
       
   482 
       
   483 
   452 	}
   484 	}
   453 
   485 
   454 /**
   486 /**
   455     Invalidate the cache
   487     Invalidate the cache
   456     @see	MWTCacheInterface::InvalidateCache()
   488     @see	MWTCacheInterface::InvalidateCache()
   516 
   548 
   517 /**
   549 /**
   518 Implementation of pure virtual function.
   550 Implementation of pure virtual function.
   519 @see	MWTCacheInterface::PosCached()
   551 @see	MWTCacheInterface::PosCached()
   520 */
   552 */
   521 TUint32 CDynamicDirCache::PosCached(const TInt64& aPos, TInt64& aCachedPosStart)
   553 TUint32 CDynamicDirCache::PosCached(TInt64 aPos)
   522 	{
   554 	{
   523 	const TInt64 pageStartMedPos = CalcPageStartPos(aPos);
   555 	const TInt64 pageStartMedPos = CalcPageStartPos(aPos);
   524 
   556 
   525 	// only search the page in lookup table
   557 	// only search the page in lookup table
   526 	// NOTE: we don't count the active page into acount here,
   558 	// NOTE: we don't count the active page into acount here,
   533 		if (LockPage(pPage) != NULL)
   565 		if (LockPage(pPage) != NULL)
   534 			{
   566 			{
   535 //			__PRINT1(_L("CDynamicDirCache::PosCached: page(0x%lx) found on Unlocked Queue!"), aPos);
   567 //			__PRINT1(_L("CDynamicDirCache::PosCached: page(0x%lx) found on Unlocked Queue!"), aPos);
   536 			// have to unlock it before returning, otherwise there will be memory leak
   568 			// have to unlock it before returning, otherwise there will be memory leak
   537 			UnlockPage(pPage);
   569 			UnlockPage(pPage);
   538     	    aCachedPosStart = pPage->StartPos();
       
   539 			return pPage->PageSizeInBytes();
   570 			return pPage->PageSizeInBytes();
   540 			}
   571 			}
   541 		else	// if the unlocked page is not valid anymore, remove it
   572 		else	// if the unlocked page is not valid anymore, remove it
   542 			{
   573 			{
   543     		DeQueue(pPage);
   574     		DeQueue(pPage);
   549 		}
   580 		}
   550 	// otherwise if page is already locked or valid active page
   581 	// otherwise if page is already locked or valid active page
   551 	else if (pPage)
   582 	else if (pPage)
   552 		{
   583 		{
   553 		__PRINT1(_L("CDynamicDirCache::PosCached: page(0x%lx) on Locked Queue!"), aPos);
   584 		__PRINT1(_L("CDynamicDirCache::PosCached: page(0x%lx) on Locked Queue!"), aPos);
   554 	    aCachedPosStart = pPage->StartPos();
       
   555 		return pPage->PageSizeInBytes();
   585 		return pPage->PageSizeInBytes();
   556 		}
   586 		}
   557 
   587 
   558 	// page is not found or not valid anymore
   588 	// page is not found or not valid anymore
   559 	return 0;
   589 	return 0;