diff -r a41df078684a -r 4122176ea935 userlibandfileserver/fileserver/sfat/sl_dir_cache.cpp --- a/userlibandfileserver/fileserver/sfat/sl_dir_cache.cpp Mon Oct 19 15:55:17 2009 +0100 +++ b/userlibandfileserver/fileserver/sfat/sl_dir_cache.cpp Mon Dec 21 16:14:42 2009 +0000 @@ -15,28 +15,37 @@ // // +//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! +//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! +//!! +//!! WARNING!! DO NOT edit this file !! '\sfat' component is obsolete and is not being used. '\sfat32'replaces it +//!! +//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! +//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + + #include "sl_std.h" #include "sl_dir_cache.h" //====================================================================== TDynamicDirCachePage::~TDynamicDirCachePage() - { - } + { + } /** The static cache page creation function. Cache page objects are not supposed to be created on the stack, so this factory function is required. */ TDynamicDirCachePage* TDynamicDirCachePage::NewL(CDynamicDirCache* aOwnerCache, TInt64 aStartMedPos, TUint8* aStartRamAddr) - { - return new(ELeave) TDynamicDirCachePage(aOwnerCache, aStartMedPos, aStartRamAddr); - } + { + return new(ELeave) TDynamicDirCachePage(aOwnerCache, aStartMedPos, aStartRamAddr); + } /** Cache page constructor. -@param aOwnerCache pointer of the cache that owns this page -@param aStartMedPos the start address on the media that this page caches -@param aStartRamAddr the start address in the ram that this page content lives +@param aOwnerCache pointer of the cache that owns this page +@param aStartMedPos the start address on the media that this page caches +@param aStartRamAddr the start address in the ram that this page content lives */ TDynamicDirCachePage::TDynamicDirCachePage(CDynamicDirCache* aOwnerCache, TInt64 aStartMedPos, TUint8* aStartRamAddr) :iStartMedPos(aStartMedPos), @@ -44,69 +53,69 @@ iOwnerCache(aOwnerCache), iValid(EFalse), iLocked(EFalse) - { -// __PRINT3(_L("TDynamicDirCachePage::TDynamicDirCachePage(aStartMedPos=%lx, aStartRamAddr=0x%X, aPageSize=%u)"), aStartMedPos, aStartRamAddr, PageSizeInBytes()); - iType = EUnknown; - } + { +// __PRINT3(_L("TDynamicDirCachePage::TDynamicDirCachePage(aStartMedPos=%lx, aStartRamAddr=0x%X, aPageSize=%u)"), aStartMedPos, aStartRamAddr, PageSizeInBytes()); + iType = EUnknown; + } /////////////////////////////// class CDynamicDirCache::TLookupEntry /////////////////////////// /** Required by RHashSet to identify individual hash set entries. -@see RHashSet +@see RHashSet */ TBool IdentityFunction(const TLookupEntry& aEntry1, const TLookupEntry& aEntry2) - { - // only check starting med pos for hash searching - return aEntry1.iPos == aEntry2.iPos; - } + { + // only check starting med pos for hash searching + return aEntry1.iPos == aEntry2.iPos; + } /** Required by RHashSet to generate hash value. -@see RHashSet +@see RHashSet */ TUint32 HashFunction(const TLookupEntry& aEntry) - { - return (DefaultHash::Integer(I64HIGH(aEntry.iPos)) + DefaultHash::Integer(I64LOW(aEntry.iPos))); - } + { + return (DefaultHash::Integer(I64HIGH(aEntry.iPos)) + DefaultHash::Integer(I64LOW(aEntry.iPos))); + } /////////////////////////////// class CDynamicDirCache /////////////////////////// CDynamicDirCache::~CDynamicDirCache() - { -// __PRINT(_L("CDynamicDirCache::~CDynamicDirCache()")); + { +// __PRINT(_L("CDynamicDirCache::~CDynamicDirCache()")); - // we should never decommit locked pages + // we should never decommit locked pages while (!iLockedQ.IsEmpty()) - { - TDynamicDirCachePage* page = iLockedQ.Last(); - DeQueue(page); // remove from queue - LookupTblRemove(page->StartPos()); // remove from lookuptable - delete page; - } - ASSERT(iLockedQCount == 0); + { + TDynamicDirCachePage* page = iLockedQ.Last(); + DeQueue(page); // remove from queue + LookupTblRemove(page->StartPos()); // remove from lookuptable + delete page; + } + ASSERT(iLockedQCount == 0); - while (!iUnlockedQ.IsEmpty()) - { - TDynamicDirCachePage* page = iUnlockedQ.Last(); - DeQueue(page); // remove from queue - LookupTblRemove(page->StartPos()); // remove from lookuptable - DecommitPage(page); // inform cache client to decommit page memory - delete page; - } - ASSERT(iUnlockedQCount == 0); + while (!iUnlockedQ.IsEmpty()) + { + TDynamicDirCachePage* page = iUnlockedQ.Last(); + DeQueue(page); // remove from queue + LookupTblRemove(page->StartPos()); // remove from lookuptable + DecommitPage(page); // inform cache client to decommit page memory + delete page; + } + ASSERT(iUnlockedQCount == 0); - delete iActivePage; + delete iActivePage; - ASSERT(iLookupTable.Count() == 0); - iLookupTable.Close(); + ASSERT(iLookupTable.Count() == 0); + iLookupTable.Close(); if (iCacheMemoryClient) - iCacheMemoryClient->Reset(); - } + iCacheMemoryClient->Reset(); + } /** Constructor of CDynamicDirCache. -@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 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 */ CDynamicDirCache::CDynamicDirCache(TFatDriveInterface& aDrive, TUint32 aMinPageNum, TUint32 aMaxPageNum, TUint32 aPageSizeInBytesLog2) :iPageSizeLog2(aPageSizeInBytesLog2), @@ -120,50 +129,50 @@ iHashFunction(HashFunction), iIdentityFunction(IdentityFunction), iLookupTable(iHashFunction, iIdentityFunction) - { - iPageSizeInBytes = 1 << aPageSizeInBytesLog2; - iCacheDisabled = EFalse; + { + iPageSizeInBytes = 1 << aPageSizeInBytesLog2; + iCacheDisabled = EFalse; iMinCacheSizeInBytes = aMinPageNum << aPageSizeInBytesLog2; iMaxCacheSizeInBytes = aMaxPageNum << aPageSizeInBytesLog2; ASSERT(iPageSizeInBytes && iPageSizeInBytes <= iMinCacheSizeInBytes && iMinCacheSizeInBytes <= iMaxCacheSizeInBytes); - // initial value, will be reset from outside - iCacheBasePos = 0; - } + // initial value, will be reset from outside + iCacheBasePos = 0; + } /** Second phase constructor of CDynamicDirCache. -@param aClientName the identification of cache memeory client this cache connects +@param aClientName the identification of cache memeory client this cache connects */ void CDynamicDirCache::ConstructL(const TDesC& aClientName) - { + { // __PRINT3(_L("CDynamicDirCache::ConstructL(Min=%u, Max=%u, page=%u)"), iMinCacheSizeInBytes, iMaxCacheSizeInBytes, iPageSizeInBytes); - CCacheMemoryManager* manager = CCacheMemoryManagerFactory::CacheMemoryManager(); - if (manager) - { - // client will register itself onto cache memory manager when created - // note this operation may leave under OOM condition - iCacheMemoryClient = manager->ConnectClientL(aClientName, iMinSizeInPages * PageSizeInSegs(), iMaxSizeInPages * PageSizeInSegs()); - } - else - { - User::Leave(KErrNotSupported); - } + CCacheMemoryManager* manager = CCacheMemoryManagerFactory::CacheMemoryManager(); + if (manager) + { + // client will register itself onto cache memory manager when created + // note this operation may leave under OOM condition + iCacheMemoryClient = manager->ConnectClientL(aClientName, iMinSizeInPages * PageSizeInSegs(), iMaxSizeInPages * PageSizeInSegs()); + } + else + { + User::Leave(KErrNotSupported); + } - ASSERT(iCacheMemoryClient); - if (!iCacheMemoryClient) - { - User::Leave(KErrNoMemory); - } + ASSERT(iCacheMemoryClient); + if (!iCacheMemoryClient) + { + User::Leave(KErrNoMemory); + } - // reserve active page - iActivePage = AllocateAndLockNewPageL(0); - ASSERT(iActivePage); - if (!iActivePage) - { - User::Leave(KErrNoMemory); - } - iActivePage->SetPageType(TDynamicDirCachePage::EActivePage); - } + // reserve active page + iActivePage = AllocateAndLockNewPageL(0); + ASSERT(iActivePage); + if (!iActivePage) + { + User::Leave(KErrNoMemory); + } + iActivePage->SetPageType(TDynamicDirCachePage::EActivePage); + } /** Static factory function of CDynamicDirCache @@ -183,94 +192,94 @@ the unlocked queue. This function is used on last visited but 'unlocked' pages to avoid excessive lock/unlock calls to cache memory manager as contiguous entry reading/writing often happens on the same page. -@param aPage the page to be inserted. -@pre the page type of aPage should only be TDynamicDirCachePage::EUnknown +@param aPage the page to be inserted. +@pre the page type of aPage should only be TDynamicDirCachePage::EUnknown */ void CDynamicDirCache::MakePageLastLocked(TDynamicDirCachePage* aPage) - { - // this function should not be called on active pages - ASSERT(aPage->iType == TDynamicDirCachePage::EUnknown); + { + // this function should not be called on active pages + ASSERT(aPage->iType == TDynamicDirCachePage::EUnknown); - if (iLockedQ.IsEmpty()) - { - // if locked queue is empty, add it onto the locked queue directly - AddFirstOntoQueue(aPage, TDynamicDirCachePage::ELocked); - } - else - { - // otherwise, we squeeze for the last position on locked queue - while (iLockedQCount + 1 >= iMinSizeInPages) - { - TDynamicDirCachePage* last = iLockedQ.Last(); - DeQueue(last); - UnlockPage(last); - AddFirstOntoQueue(last, TDynamicDirCachePage::EUnlocked); - } + if (iLockedQ.IsEmpty()) + { + // if locked queue is empty, add it onto the locked queue directly + AddFirstOntoQueue(aPage, TDynamicDirCachePage::ELocked); + } + else + { + // otherwise, we squeeze for the last position on locked queue + while (iLockedQCount + 1 >= iMinSizeInPages) + { + TDynamicDirCachePage* last = iLockedQ.Last(); + DeQueue(last); + UnlockPage(last); + AddFirstOntoQueue(last, TDynamicDirCachePage::EUnlocked); + } - // iLockedQCount + 1 < iMinSizeInPages - iLockedQ.AddLast(*aPage); - aPage->SetPageType(TDynamicDirCachePage::ELocked); - iLockedQCount++; - } - } + // iLockedQCount + 1 < iMinSizeInPages + iLockedQ.AddLast(*aPage); + aPage->SetPageType(TDynamicDirCachePage::ELocked); + iLockedQCount++; + } + } /** Read data from a single page. If the page is not found or not valid anymore, read media onto iActive page first. -@param aPos the starting position of the media address to be read. -@param aLength the length of the content to be read. -@param aDes the descriptor to contain the content. -@pre aLength should be no more than page size. +@param aPos the starting position of the media address to be read. +@param aLength the length of the content to be read. +@param aDes the descriptor to contain the content. +@pre aLength should be no more than page size. */ void CDynamicDirCache::ReadDataFromSinglePageL(TInt64 aPos, TInt aLength, TDes8& aDes) - { + { //-- the data section is in the cache page entirely, take data directly from the cache - TDynamicDirCachePage* pPage = FindPageByPos(aPos); + TDynamicDirCachePage* pPage = FindPageByPos(aPos); if (pPage) - { - // lock page before reading, - if (LockPage(pPage) != NULL) - { - // read data + { + // lock page before reading, + if (LockPage(pPage) != NULL) + { + // read data aDes.Copy(pPage->PtrInPage(aPos), aLength); // if page is from unlocked queue, insert it onto the last page of the locked // queue. this is to avoid excessive locking and unlocking operations that is // highly likely to happen for following reads. if (pPage->PageType() == TDynamicDirCachePage::EUnlocked) - { - DeQueue(pPage); - MakePageLastLocked(pPage); - } - } - else // page locking failed - { - ASSERT(pPage->PageType() == TDynamicDirCachePage::EUnlocked); - DeQueue(pPage); - LookupTblRemove(pPage->StartPos()); - DecommitPage(pPage); - delete pPage; - pPage = NULL; - } - } + { + DeQueue(pPage); + MakePageLastLocked(pPage); + } + } + else // page locking failed + { + ASSERT(pPage->PageType() == TDynamicDirCachePage::EUnlocked); + DeQueue(pPage); + LookupTblRemove(pPage->StartPos()); + DecommitPage(pPage); + delete pPage; + pPage = NULL; + } + } - if (!pPage) - { + if (!pPage) + { // if page not found or page data not valid anymore, use active page to read data in pPage = UpdateActivePageL(aPos); // read data aDes.Copy(pPage->PtrInPage(aPos), aLength); - } + } - } + } //==================================================================== /** Implementation of pure virtual function. -@see MWTCacheInterface::ReadL() +@see MWTCacheInterface::ReadL() */ void CDynamicDirCache::ReadL(TInt64 aPos, TInt aLength, TDes8& aDes) - { + { #ifdef _DEBUG if(iCacheDisabled) { @@ -309,79 +318,79 @@ //-- 2. read whole pages of data while (dataLen >= PageSz) - { - //-- find out if currMediaPos is in cache. If not, find a spare page and read data there - ReadDataFromSinglePageL(currMediaPos, PageSz, dataNext); + { + //-- find out if currMediaPos is in cache. If not, find a spare page and read data there + ReadDataFromSinglePageL(currMediaPos, PageSz, dataNext); currMediaPos += PageSz; dataLen -= PageSz; dataNext = dataNext.MidTPtr(dataNext.Length()); - } + } //-- 3. read the rest of the data if(dataLen > 0) { - ReadDataFromSinglePageL(currMediaPos, dataLen, dataNext); + ReadDataFromSinglePageL(currMediaPos, dataLen, dataNext); } } //else((TUint32)aLength <= bytesToPageEnd) - } + } /** Write data through a single page. If the page is not found or not valid anymore, read media onto iActive page first, then write data through iActive page. -@param aPos the starting position of the media address to be write. -@param aData the starting address that the writing content lives in the ram. -@param aDataLen the length of the content to be written. -@pre aDataLen should be no more than page size. +@param aPos the starting position of the media address to be write. +@param aData the starting address that the writing content lives in the ram. +@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) - { - ASSERT(aDataLen <= iPageSizeInBytes); + { + ASSERT(aDataLen <= iPageSizeInBytes); //-- the data section is in the cache page entirely, take data directly from the cache - TDynamicDirCachePage* pPage = FindPageByPos(aPos); + TDynamicDirCachePage* pPage = FindPageByPos(aPos); if (pPage) - { - // lock page before writing, - if (LockPage(pPage) != NULL) - { - //-- update cache + { + // lock page before writing, + if (LockPage(pPage) != NULL) + { + //-- update cache Mem::Copy(pPage->PtrInPage(aPos), aData, aDataLen); - } - else - { - ASSERT(pPage->PageType() == TDynamicDirCachePage::EUnlocked); - DeQueue(pPage); - LookupTblRemove(pPage->StartPos()); - DecommitPage(pPage); - delete pPage; - pPage = NULL; - } - } + } + else + { + ASSERT(pPage->PageType() == TDynamicDirCachePage::EUnlocked); + DeQueue(pPage); + LookupTblRemove(pPage->StartPos()); + DecommitPage(pPage); + delete pPage; + pPage = NULL; + } + } // if page not found or page data not valid anymore, use active page to read data in if (!pPage) - { + { pPage = UpdateActivePageL(aPos); //-- update cache Mem::Copy(pPage->PtrInPage(aPos), aData, aDataLen); - } + } - // make sure the page is unlocked after use - if (pPage->PageType() == TDynamicDirCachePage::EUnlocked) - { - UnlockPage(pPage); - } + // make sure the page is unlocked after use + if (pPage->PageType() == TDynamicDirCachePage::EUnlocked) + { + UnlockPage(pPage); + } - // always make writting events MRU - MakePageMRU(aPos); + // always make writting events MRU + MakePageMRU(aPos); return; - } + } /** Implementation of pure virtual function. -@see MWTCacheInterface::WriteL() +@see MWTCacheInterface::WriteL() */ void CDynamicDirCache::WriteL(TInt64 aPos,const TDesC8& aDes) - { + { #ifdef _DEBUG if(iCacheDisabled) { @@ -421,13 +430,13 @@ //-- 2. write whole pages of data to the cache while (dataLen >= PageSz) - { + { WriteDataOntoSinglePageL(currMediaPos, pData, PageSz); pData += PageSz; currMediaPos += PageSz; dataLen -= PageSz; - } + } //-- 3. write the rest of the data if(dataLen > 0) @@ -444,56 +453,56 @@ InvalidateCache(); User::Leave(nErr); } - } + } /** Implementation of pure virtual function. -@see MWTCacheInterface::InvalidateCache() +@see MWTCacheInterface::InvalidateCache() */ void CDynamicDirCache::InvalidateCache(void) - { - __PRINT2(_L("CDynamicDirCache::InvalidateCache(locked=%d, unlocked=%d)"), iLockedQCount, iUnlockedQCount); - // we should never decommit locked pages as they needs to be reserved anyway - // the overhead of unnecessary page committing operations - while(!iLockedQ.IsEmpty()) - { - TDynamicDirCachePage* page = iLockedQ.Last(); - DeQueue(page); // remove from queue - LookupTblRemove(page->StartPos()); // remove from lookuptable - delete page; - } - ASSERT(iLockedQCount == 0); + { + __PRINT2(_L("CDynamicDirCache::InvalidateCache(locked=%d, unlocked=%d)"), iLockedQCount, iUnlockedQCount); + // we should never decommit locked pages as they needs to be reserved anyway + // the overhead of unnecessary page committing operations + while(!iLockedQ.IsEmpty()) + { + TDynamicDirCachePage* page = iLockedQ.Last(); + DeQueue(page); // remove from queue + LookupTblRemove(page->StartPos()); // remove from lookuptable + delete page; + } + ASSERT(iLockedQCount == 0); - // however we should decommit unlocked pages here - while (!iUnlockedQ.IsEmpty()) - { - TDynamicDirCachePage* page = iUnlockedQ.Last(); - DeQueue(page); // remove from queue - LookupTblRemove(page->StartPos()); // remove from lookuptable - DecommitPage(page); // inform cache client to decommit page memory - delete page; - } - ASSERT(iUnlockedQCount == 0); + // however we should decommit unlocked pages here + while (!iUnlockedQ.IsEmpty()) + { + TDynamicDirCachePage* page = iUnlockedQ.Last(); + DeQueue(page); // remove from queue + LookupTblRemove(page->StartPos()); // remove from lookuptable + DecommitPage(page); // inform cache client to decommit page memory + delete page; + } + ASSERT(iUnlockedQCount == 0); ASSERT(iLookupTable.Count() == 0); - iLookupTable.Close(); + iLookupTable.Close(); - ASSERT(iCacheMemoryClient); + ASSERT(iCacheMemoryClient); - // initialize cache state. - // Note that once the client is reset, all pages lose connection with the client - // including the active page. So we will need to reset and re-allocate active page - // properly. - if (iCacheMemoryClient) - iCacheMemoryClient->Reset(); + // initialize cache state. + // Note that once the client is reset, all pages lose connection with the client + // including the active page. So we will need to reset and re-allocate active page + // properly. + if (iCacheMemoryClient) + iCacheMemoryClient->Reset(); - // reset and re-allocate active page - ResetPagePos(iActivePage); // reset start media position (0), invalidate page content - TUint8* startRamAddr = iCacheMemoryClient->AllocateAndLockSegments(PageSizeInSegs()); - // this should always succeed as the client has just been reset and there are always reserved pages - ASSERT(startRamAddr); - iActivePage->SetStartPtr(startRamAddr); // set RAM address - } + // reset and re-allocate active page + ResetPagePos(iActivePage); // reset start media position (0), invalidate page content + TUint8* startRamAddr = iCacheMemoryClient->AllocateAndLockSegments(PageSizeInSegs()); + // this should always succeed as the client has just been reset and there are always reserved pages + ASSERT(startRamAddr); + iActivePage->SetStartPtr(startRamAddr); // set RAM address + } /** this method isn't implemented*/ @@ -505,64 +514,64 @@ /** Implementation of pure virtual function. -@see MWTCacheInterface::PosCached() +@see MWTCacheInterface::PosCached() */ TUint32 CDynamicDirCache::PosCached(const TInt64& aPos, TInt64& aCachedPosStart) - { - const TInt64 pageStartMedPos = CalcPageStartPos(aPos); + { + const TInt64 pageStartMedPos = CalcPageStartPos(aPos); - // only search the page in lookup table - // NOTE: we don't count the active page into acount here, - // this is to avoid pulling next pages recursively - TDynamicDirCachePage* pPage = LookupTblFind(pageStartMedPos); + // only search the page in lookup table + // NOTE: we don't count the active page into acount here, + // this is to avoid pulling next pages recursively + TDynamicDirCachePage* pPage = LookupTblFind(pageStartMedPos); - // then check if page is still valid if page is on Unlocked Page Queue - if (pPage && pPage->PageType() == TDynamicDirCachePage::EUnlocked) - { - if (LockPage(pPage) != NULL) - { -// __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 - { - DeQueue(pPage); - LookupTblRemove(pPage->StartPos()); - DecommitPage(pPage); - delete pPage; - pPage = NULL; - } - } - // otherwise if page is already locked or valid active page - else if (pPage) - { - __PRINT1(_L("CDynamicDirCache::PosCached: page(0x%lx) on Locked Queue!"), aPos); - aCachedPosStart = pPage->StartPos(); - return pPage->PageSizeInBytes(); - } + // then check if page is still valid if page is on Unlocked Page Queue + if (pPage && pPage->PageType() == TDynamicDirCachePage::EUnlocked) + { + if (LockPage(pPage) != NULL) + { +// __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 + { + DeQueue(pPage); + LookupTblRemove(pPage->StartPos()); + DecommitPage(pPage); + delete pPage; + pPage = NULL; + } + } + // otherwise if page is already locked or valid active page + else if (pPage) + { + __PRINT1(_L("CDynamicDirCache::PosCached: page(0x%lx) on Locked Queue!"), aPos); + aCachedPosStart = pPage->StartPos(); + return pPage->PageSizeInBytes(); + } - // page is not found or not valid anymore - return 0; - } + // page is not found or not valid anymore + return 0; + } /** Implementation of pure virtual function. -@see MWTCacheInterface::CacheSizeInBytes() +@see MWTCacheInterface::CacheSizeInBytes() */ TUint32 CDynamicDirCache::CacheSizeInBytes() const - { - return iMaxCacheSizeInBytes; - } + { + return iMaxCacheSizeInBytes; + } /** Implementation of pure virtual function. -@see MWTCacheInterface::Control() +@see MWTCacheInterface::Control() */ TInt CDynamicDirCache::Control(TUint32 aFunction, TUint32 aParam1, TAny* aParam2) - { + { TInt r = KErrNotSupported; #ifdef _DEBUG (void)aParam2; @@ -577,27 +586,27 @@ // dump cache, for debug case EDumpCache: - { - RFs fs; - fs.Connect(); - const TUint32 debugRegister = DebugRegister(); - fs.SetDebugRegister(debugRegister|KFSYS); - Dump(); - fs.SetDebugRegister(debugRegister); - fs.Close(); - break; - } + { + RFs fs; + fs.Connect(); + const TUint32 debugRegister = DebugRegister(); + fs.SetDebugRegister(debugRegister|KFSYS); + Dump(); + fs.SetDebugRegister(debugRegister); + fs.Close(); + break; + } case ECacheInfo: - { - RFs fs; - fs.Connect(); - const TUint32 debugRegister = DebugRegister(); - fs.SetDebugRegister(debugRegister|KFSYS); - Info(); - fs.SetDebugRegister(debugRegister); - fs.Close(); - break; - } + { + RFs fs; + fs.Connect(); + const TUint32 debugRegister = DebugRegister(); + fs.SetDebugRegister(debugRegister|KFSYS); + Info(); + fs.SetDebugRegister(debugRegister); + fs.Close(); + break; + } default: __PRINT1(_L("CDynamicDirCache::Control() invalid function: %d"), aFunction); @@ -613,237 +622,237 @@ #endif //_DEBUG return r; - } + } /** Implementation of pure virtual function. -@see MWTCacheInterface::SetCacheBasePos() +@see MWTCacheInterface::SetCacheBasePos() */ void CDynamicDirCache::SetCacheBasePos(TInt64 aBasePos) - { - iCacheBasePos = aBasePos; - } + { + iCacheBasePos = aBasePos; + } /** Implementation of pure virtual function. -@see MWTCacheInterface::SetCacheBasePos() +@see MWTCacheInterface::SetCacheBasePos() */ TUint32 CDynamicDirCache::PageSizeInBytesLog2() const - { - return iPageSizeLog2; - } + { + return iPageSizeLog2; + } /** Implementation of pure virtual function. -@see MWTCacheInterface::MakePageMRU() +@see MWTCacheInterface::MakePageMRU() */ void CDynamicDirCache::MakePageMRU(TInt64 aPos) - { - __PRINT1(_L("MakePageMRU (%lx)"), aPos); -// __PRINT4(_L("Current Cache State: iLockedQCount=%d, iUnlockedQCount=%d, iLookupTbl=%d, iMaxSizeInPages=%d"), iLockedQCount, iUnlockedQCount, iLookupTable.Count(), iMaxSizeInPages); - // check the MRU page first, if it is already the MRU page, we can return immediately - TInt64 pageStartMedPos = CalcPageStartPos(aPos); - if (!iLockedQ.IsEmpty()) - { - if (iLockedQ.First()->StartPos() == pageStartMedPos) - { - return; - } - } + { + __PRINT1(_L("MakePageMRU (%lx)"), aPos); +// __PRINT4(_L("Current Cache State: iLockedQCount=%d, iUnlockedQCount=%d, iLookupTbl=%d, iMaxSizeInPages=%d"), iLockedQCount, iUnlockedQCount, iLookupTable.Count(), iMaxSizeInPages); + // check the MRU page first, if it is already the MRU page, we can return immediately + TInt64 pageStartMedPos = CalcPageStartPos(aPos); + if (!iLockedQ.IsEmpty()) + { + if (iLockedQ.First()->StartPos() == pageStartMedPos) + { + return; + } + } - TDynamicDirCachePage* pPage = FindPageByPos(aPos); + TDynamicDirCachePage* pPage = FindPageByPos(aPos); if (pPage) - { - ASSERT(pPage->IsValid()); - // lock page before make it MRU - if (pPage->PageType() == TDynamicDirCachePage::EUnlocked) - { - ASSERT(!pPage->IsLocked()); - if (LockPage(pPage) == NULL) - { - DeQueue(pPage); - LookupTblRemove(pPage->StartPos()); - DecommitPage(pPage); - delete pPage; - pPage = NULL; - } - } - else - { - // error checking: page should either be locked or active - ASSERT(LockPage(pPage) != NULL); - } - } + { + ASSERT(pPage->IsValid()); + // lock page before make it MRU + if (pPage->PageType() == TDynamicDirCachePage::EUnlocked) + { + ASSERT(!pPage->IsLocked()); + if (LockPage(pPage) == NULL) + { + DeQueue(pPage); + LookupTblRemove(pPage->StartPos()); + DecommitPage(pPage); + delete pPage; + pPage = NULL; + } + } + else + { + // error checking: page should either be locked or active + ASSERT(LockPage(pPage) != NULL); + } + } // if page not found or page data not valid anymore, use active page to read data if (!pPage) - { + { TRAPD(err, pPage = UpdateActivePageL(aPos)); if (err != KErrNone) - { - // problem occurred reading active page, return immediately. - return; - } - } + { + // problem occurred reading active page, return immediately. + return; + } + } // by now, the page is either locked or active page - ASSERT(pPage && pPage->IsValid() && pPage->IsLocked()); + ASSERT(pPage && pPage->IsValid() && pPage->IsLocked()); - switch (pPage->PageType()) - { - // if the page is the active page, we will need to find a new active page for replacement - case TDynamicDirCachePage::EActivePage: - { - TDynamicDirCachePage* newAP = NULL; - // if there is more cache room available, try to create a new page first - if (!CacheIsFull()) - { - // allocate and lock a new page - TRAPD(err, newAP = AllocateAndLockNewPageL(0)); - // if any error ocurrs, return immediately - if (err != KErrNone) - { - // unlock the page that was originally unlocked before leave - if (pPage->PageType() == TDynamicDirCachePage::EUnlocked) - { - UnlockPage(pPage); - } - return; - } + switch (pPage->PageType()) + { + // if the page is the active page, we will need to find a new active page for replacement + case TDynamicDirCachePage::EActivePage: + { + TDynamicDirCachePage* newAP = NULL; + // if there is more cache room available, try to create a new page first + if (!CacheIsFull()) + { + // allocate and lock a new page + TRAPD(err, newAP = AllocateAndLockNewPageL(0)); + // if any error ocurrs, return immediately + if (err != KErrNone) + { + // unlock the page that was originally unlocked before leave + if (pPage->PageType() == TDynamicDirCachePage::EUnlocked) + { + UnlockPage(pPage); + } + return; + } - if (newAP) - { - // replace the active page with the new page - newAP->SetPageType(TDynamicDirCachePage::EActivePage); - iActivePage = newAP; - } - } + if (newAP) + { + // replace the active page with the new page + newAP->SetPageType(TDynamicDirCachePage::EActivePage); + iActivePage = newAP; + } + } - // if cache has grown to its max size, or new page allocation failed - if (!newAP) - { - // try to lock the LRU page on the unlocked page queque first - if (!iUnlockedQ.IsEmpty()) - { - newAP = iUnlockedQ.Last(); - ASSERT(newAP->IsValid()); - if (LockPage(newAP) != NULL) - { - // deque, reset pos, set new type - DeQueue(newAP); - LookupTblRemove(newAP->StartPos()); - ResetPagePos(newAP); - newAP->SetPageType(TDynamicDirCachePage::EActivePage); - // replace active page - iActivePage = newAP; - } - // if falied locking the LRU page from unclocked queque, - // delete it - else - { - DeQueue(newAP); - LookupTblRemove(newAP->StartPos()); - DecommitPage(newAP); - delete newAP; - newAP = NULL; - } - } - } + // if cache has grown to its max size, or new page allocation failed + if (!newAP) + { + // try to lock the LRU page on the unlocked page queque first + if (!iUnlockedQ.IsEmpty()) + { + newAP = iUnlockedQ.Last(); + ASSERT(newAP->IsValid()); + if (LockPage(newAP) != NULL) + { + // deque, reset pos, set new type + DeQueue(newAP); + LookupTblRemove(newAP->StartPos()); + ResetPagePos(newAP); + newAP->SetPageType(TDynamicDirCachePage::EActivePage); + // replace active page + iActivePage = newAP; + } + // if falied locking the LRU page from unclocked queque, + // delete it + else + { + DeQueue(newAP); + LookupTblRemove(newAP->StartPos()); + DecommitPage(newAP); + delete newAP; + newAP = NULL; + } + } + } - // if still have not found new active page - // grab the LRU page from Locked Page Queue for active page - if (!newAP) - { - ASSERT(!iLockedQ.IsEmpty()); - newAP = iLockedQ.Last(); - // deque, reset pos, set new type - DeQueue(newAP); - LookupTblRemove(newAP->StartPos()); - ResetPagePos(newAP); - newAP->SetPageType(TDynamicDirCachePage::EActivePage); - // replace active page - iActivePage = newAP; - } + // if still have not found new active page + // grab the LRU page from Locked Page Queue for active page + if (!newAP) + { + ASSERT(!iLockedQ.IsEmpty()); + newAP = iLockedQ.Last(); + // deque, reset pos, set new type + DeQueue(newAP); + LookupTblRemove(newAP->StartPos()); + ResetPagePos(newAP); + newAP->SetPageType(TDynamicDirCachePage::EActivePage); + // replace active page + iActivePage = newAP; + } - // we should always be able to find a locked page for active page - ASSERT(newAP != NULL); + // we should always be able to find a locked page for active page + ASSERT(newAP != NULL); - // make original page (i.e. former active page) MRU - // add onto locked queue - AddFirstOntoQueue(pPage, TDynamicDirCachePage::ELocked); - // add onto lookuptbl, as active page is not on lookup tbl originally - LookupTblAdd(pPage); - // check cache limit - CheckThresholds(); - return; - } - case TDynamicDirCachePage::EUnlocked: - { - // if page was originally on Unlocked Page Queque, remove it from Unlocked Page Queue, add it - // to the Locked Page Queue and make it MRU - DeQueue(pPage); - AddFirstOntoQueue(pPage, TDynamicDirCachePage::ELocked); - // check cache limit - CheckThresholds(); - return; - } - case TDynamicDirCachePage::ELocked: - { - // otherwise the page was on Locked Page Queue, make it MRU - // no need to check cache limit - if (pPage != iLockedQ.First()) - { - DeQueue(pPage); - AddFirstOntoQueue(pPage, TDynamicDirCachePage::ELocked); - return; - } - break; - } - default: - ASSERT(0); - } - } + // make original page (i.e. former active page) MRU + // add onto locked queue + AddFirstOntoQueue(pPage, TDynamicDirCachePage::ELocked); + // add onto lookuptbl, as active page is not on lookup tbl originally + LookupTblAdd(pPage); + // check cache limit + CheckThresholds(); + return; + } + case TDynamicDirCachePage::EUnlocked: + { + // if page was originally on Unlocked Page Queque, remove it from Unlocked Page Queue, add it + // to the Locked Page Queue and make it MRU + DeQueue(pPage); + AddFirstOntoQueue(pPage, TDynamicDirCachePage::ELocked); + // check cache limit + CheckThresholds(); + return; + } + case TDynamicDirCachePage::ELocked: + { + // otherwise the page was on Locked Page Queue, make it MRU + // no need to check cache limit + if (pPage != iLockedQ.First()) + { + DeQueue(pPage); + AddFirstOntoQueue(pPage, TDynamicDirCachePage::ELocked); + return; + } + break; + } + default: + ASSERT(0); + } + } //==================================================================== /** Internal query function, to check if aPos is cached or not. iActive page is included in searching. */ TDynamicDirCachePage* CDynamicDirCache::FindPageByPos(TInt64 aPos) - { - __PRINT1(_L("CDynamicDirCache::FindPageByPos(aPos=%lx)"), aPos); + { + __PRINT1(_L("CDynamicDirCache::FindPageByPos(aPos=%lx)"), aPos); // align the page position - TInt64 pageStartMedPos = CalcPageStartPos(aPos); + TInt64 pageStartMedPos = CalcPageStartPos(aPos); - if ((iActivePage->StartPos() == pageStartMedPos)) - { - ASSERT(iActivePage->IsValid()); - return iActivePage; - } + if ((iActivePage->StartPos() == pageStartMedPos)) + { + ASSERT(iActivePage->IsValid()); + return iActivePage; + } - // search in lookup table - return LookupTblFind(pageStartMedPos); - } + // search in lookup table + return LookupTblFind(pageStartMedPos); + } /** read a page length data into iActive page and return iActive page if read is successful. */ TDynamicDirCachePage* CDynamicDirCache::UpdateActivePageL(TInt64 aPos) - { + { // align the page position - TInt64 pageStartMedPos = CalcPageStartPos(aPos); + TInt64 pageStartMedPos = CalcPageStartPos(aPos); - if (iActivePage->StartPos() == pageStartMedPos && iActivePage->IsValid()) - { - return iActivePage; - } + if (iActivePage->StartPos() == pageStartMedPos && iActivePage->IsValid()) + { + return iActivePage; + } - __PRINT2(_L("CDynamicDirCache::UpdateActivePageL(aPos=%lx, active=%lx)"), aPos, iActivePage->StartPos()); + __PRINT2(_L("CDynamicDirCache::UpdateActivePageL(aPos=%lx, active=%lx)"), aPos, iActivePage->StartPos()); - // set start med pos value, no other effects, only available to active page - iActivePage->SetPos(pageStartMedPos); + // set start med pos value, no other effects, only available to active page + iActivePage->SetPos(pageStartMedPos); - // read data, make active page valid - TUint8* data = iActivePage->PtrInPage(iActivePage->iStartMedPos); + // read data, make active page valid + TUint8* data = iActivePage->PtrInPage(iActivePage->iStartMedPos); TPtr8 dataPtr(data, iPageSizeInBytes); const TInt nErr = iDrive.ReadNonCritical(iActivePage->iStartMedPos, iPageSizeInBytes, dataPtr); if(nErr !=KErrNone) @@ -855,73 +864,73 @@ iActivePage->SetValid(ETrue); return iActivePage; - } + } /** Check if the number of (locked pages + iActive page) and unlocked pages have exceeded minimum allowed page number and maximum allowed page number respectively. */ void CDynamicDirCache::CheckThresholds() - { - while (iLockedQCount + 1 > iMinSizeInPages) - { - TDynamicDirCachePage* movePage = iLockedQ.Last(); - UnlockPage(movePage); - DeQueue(movePage); - TInt err = LookupTblRemove(movePage->StartPos()); - ASSERT(err == KErrNone); + { + while (iLockedQCount + 1 > iMinSizeInPages) + { + TDynamicDirCachePage* movePage = iLockedQ.Last(); + UnlockPage(movePage); + DeQueue(movePage); + TInt err = LookupTblRemove(movePage->StartPos()); + ASSERT(err == KErrNone); - // if it is a valid page, add onto unlocked queue - if (movePage->StartPos() != 0) - { - ASSERT(movePage->IsValid()); - AddFirstOntoQueue(movePage, TDynamicDirCachePage::EUnlocked); - err = LookupTblAdd(movePage); - ASSERT(err == KErrNone); - } - else // reserved page, delete - { - DecommitPage(movePage); - delete movePage; - } - } + // if it is a valid page, add onto unlocked queue + if (movePage->StartPos() != 0) + { + ASSERT(movePage->IsValid()); + AddFirstOntoQueue(movePage, TDynamicDirCachePage::EUnlocked); + err = LookupTblAdd(movePage); + ASSERT(err == KErrNone); + } + else // reserved page, delete + { + DecommitPage(movePage); + delete movePage; + } + } - // if unlocked queue exceeds limit, delete LRU page - // note: all pages on unlocked queue should be valid - while (iUnlockedQCount > iMaxSizeInPages - iMinSizeInPages) - { - TDynamicDirCachePage* removePage = iUnlockedQ.Last(); - ASSERT(removePage->StartPos() != 0 && removePage->IsValid()); - DeQueue(removePage); - LookupTblRemove(removePage->StartPos()); - DecommitPage(removePage); - delete removePage; - } - } + // if unlocked queue exceeds limit, delete LRU page + // note: all pages on unlocked queue should be valid + while (iUnlockedQCount > iMaxSizeInPages - iMinSizeInPages) + { + TDynamicDirCachePage* removePage = iUnlockedQ.Last(); + ASSERT(removePage->StartPos() != 0 && removePage->IsValid()); + DeQueue(removePage); + LookupTblRemove(removePage->StartPos()); + DecommitPage(removePage); + delete removePage; + } + } /** Try to create a new page and lock the page content when it is created. This function should only be called when creating iActive page or making a page MRU (which might result in page evictions). -@return the pointer of the newly created page, or NULL if allocation failed. -@param aStartMedPos the starting media address of the page to be created. -@pre aStartMedPos should not already be existing in the cache. +@return the pointer of the newly created page, or NULL if allocation failed. +@param aStartMedPos the starting media address of the page to be created. +@pre aStartMedPos should not already be existing in the cache. */ TDynamicDirCachePage* CDynamicDirCache::AllocateAndLockNewPageL(TInt64 aStartMedPos) - { - __PRINT1(_L("CDynamicDirCache::AllocateAndLockNewPageL(aStartMedPos=%lx)"), aStartMedPos); + { + __PRINT1(_L("CDynamicDirCache::AllocateAndLockNewPageL(aStartMedPos=%lx)"), aStartMedPos); - TUint8* startRamAddr = iCacheMemoryClient->AllocateAndLockSegments(PageSizeInSegs()); - if (startRamAddr) - { - // create new page and return - TDynamicDirCachePage* pPage = TDynamicDirCachePage::NewL(this, aStartMedPos, startRamAddr); - pPage->SetLocked(ETrue); - pPage->SetValid(EFalse); - return pPage; - } + TUint8* startRamAddr = iCacheMemoryClient->AllocateAndLockSegments(PageSizeInSegs()); + if (startRamAddr) + { + // create new page and return + TDynamicDirCachePage* pPage = TDynamicDirCachePage::NewL(this, aStartMedPos, startRamAddr); + pPage->SetLocked(ETrue); + pPage->SetValid(EFalse); + return pPage; + } - return NULL; - } + return NULL; + } #ifdef _DEBUG /** @@ -929,299 +938,299 @@ @see CDynamicDirCache::Control() */ void CDynamicDirCache::Info() const - { - __PRINT(_L("======== CDynamicDirCache::Info =========")); - const TUint32 SegmentSizeInBytesLog2 = CCacheMemoryManagerFactory::CacheMemoryManager()->SegmentSizeInBytesLog2(); - // page size - __PRINT1(_L("=== Pages size: [%d Bytes]"), iPageSizeInBytes); - __PRINT1(_L("=== Segment size: [%d Bytes]"), 1 << SegmentSizeInBytesLog2); + { + __PRINT(_L("======== CDynamicDirCache::Info =========")); + const TUint32 SegmentSizeInBytesLog2 = CCacheMemoryManagerFactory::CacheMemoryManager()->SegmentSizeInBytesLog2(); + // page size + __PRINT1(_L("=== Pages size: [%d Bytes]"), iPageSizeInBytes); + __PRINT1(_L("=== Segment size: [%d Bytes]"), 1 << SegmentSizeInBytesLog2); - // data size: - __PRINT1(_L("=== Min data size: [%d Bytes]"), iMinSizeInPages << iPageSizeLog2); - __PRINT1(_L("=== Max data size: [%d Bytes]"), iMaxSizeInPages << iPageSizeLog2); + // data size: + __PRINT1(_L("=== Min data size: [%d Bytes]"), iMinSizeInPages << iPageSizeLog2); + __PRINT1(_L("=== Max data size: [%d Bytes]"), iMaxSizeInPages << iPageSizeLog2); - // memory size: - const TUint32 pageMemSizeLog2 = iPageSizeLog2 > SegmentSizeInBytesLog2 ? iPageSizeLog2 : SegmentSizeInBytesLog2; - __PRINT1(_L("=== Min memory size: [%d Bytes]"), iMinSizeInPages << pageMemSizeLog2); - __PRINT1(_L("=== Max memory size: [%d Bytes]"), iMaxSizeInPages << pageMemSizeLog2); + // memory size: + const TUint32 pageMemSizeLog2 = iPageSizeLog2 > SegmentSizeInBytesLog2 ? iPageSizeLog2 : SegmentSizeInBytesLog2; + __PRINT1(_L("=== Min memory size: [%d Bytes]"), iMinSizeInPages << pageMemSizeLog2); + __PRINT1(_L("=== Max memory size: [%d Bytes]"), iMaxSizeInPages << pageMemSizeLog2); - // reserved pages - __PRINT1(_L("=== Number of pages reserved: [%d]"), iMinSizeInPages); - __PRINT1(_L("=== Reserved memory: [%d Bytes]"), (iMinSizeInPages * PageSizeInSegs()) << SegmentSizeInBytesLog2); - // locked page num - __PRINT1(_L("=== Number of pages locked: [%d]"), iLockedQCount); - __PRINT1(_L("=== Locked memory: [%d Bytes]"), (iLockedQCount * PageSizeInSegs()) << SegmentSizeInBytesLog2); - // unlocked page num - __PRINT1(_L("=== Number of pages unlocked: [%d]"), iUnlockedQCount); - __PRINT1(_L("=== Unlocked memory: [%d Bytes]"), (iUnlockedQCount * PageSizeInSegs()) << SegmentSizeInBytesLog2); - } + // reserved pages + __PRINT1(_L("=== Number of pages reserved: [%d]"), iMinSizeInPages); + __PRINT1(_L("=== Reserved memory: [%d Bytes]"), (iMinSizeInPages * PageSizeInSegs()) << SegmentSizeInBytesLog2); + // locked page num + __PRINT1(_L("=== Number of pages locked: [%d]"), iLockedQCount); + __PRINT1(_L("=== Locked memory: [%d Bytes]"), (iLockedQCount * PageSizeInSegs()) << SegmentSizeInBytesLog2); + // unlocked page num + __PRINT1(_L("=== Number of pages unlocked: [%d]"), iUnlockedQCount); + __PRINT1(_L("=== Unlocked memory: [%d Bytes]"), (iUnlockedQCount * PageSizeInSegs()) << SegmentSizeInBytesLog2); + } /** Dump cache content, only enabled in debug mode. @see CDynamicDirCache::Control() */ void CDynamicDirCache::Dump() - { - __PRINT(_L("======== CDynamicDirCache::Dump =========")); - if (!iLockedQ.IsEmpty()) - { - TDblQueIter q(iLockedQ); - q.SetToFirst(); - TInt i = 0; - while((TDynamicDirCachePage*)q) - { - TDynamicDirCachePage* pP = q++; - __PRINT3(_L("=== CDynamicDirCache::iLockedQ\t[%4d](pos=%lx, size=%d)"), i++, pP->StartPos(), pP->PageSizeInBytes()); - } - } - if (!iUnlockedQ.IsEmpty()) - { - TDblQueIter q(iUnlockedQ); - q.SetToFirst(); - TInt i = 0; - while((TDynamicDirCachePage*)q) - { - TDynamicDirCachePage* pP = q++; - __PRINT3(_L("=== CDynamicDirCache::iUnlockedQ\t[%4d](pos=%lx, size=%u)"), i++, pP->StartPos(), pP->PageSizeInBytes()); - } - } - __PRINT2(_L("=== CDynamicDirCache::iActivePage\t[*](pos=%lx, size=%u)"), iActivePage->StartPos(), iActivePage->PageSizeInBytes()); + { + __PRINT(_L("======== CDynamicDirCache::Dump =========")); + if (!iLockedQ.IsEmpty()) + { + TDblQueIter q(iLockedQ); + q.SetToFirst(); + TInt i = 0; + while((TDynamicDirCachePage*)q) + { + TDynamicDirCachePage* pP = q++; + __PRINT3(_L("=== CDynamicDirCache::iLockedQ\t[%4d](pos=%lx, size=%d)"), i++, pP->StartPos(), pP->PageSizeInBytes()); + } + } + if (!iUnlockedQ.IsEmpty()) + { + TDblQueIter q(iUnlockedQ); + q.SetToFirst(); + TInt i = 0; + while((TDynamicDirCachePage*)q) + { + TDynamicDirCachePage* pP = q++; + __PRINT3(_L("=== CDynamicDirCache::iUnlockedQ\t[%4d](pos=%lx, size=%u)"), i++, pP->StartPos(), pP->PageSizeInBytes()); + } + } + __PRINT2(_L("=== CDynamicDirCache::iActivePage\t[*](pos=%lx, size=%u)"), iActivePage->StartPos(), iActivePage->PageSizeInBytes()); - if (iLookupTable.Count()) - { - TInt i = 0; - THashSetIter iter(iLookupTable); - TLookupEntry* pEntry; - pEntry = (TLookupEntry*) iter.Next(); - while(pEntry) - { - TDynamicDirCachePage* pP = pEntry->iPage; - __PRINT3(_L("=== CDynamicDirCache::iLookupTable\t[%4d](pos=%lx, size=%u)"), i++, pP->StartPos(), pP->PageSizeInBytes()); - pEntry = (TLookupEntry*) iter.Next(); - }; - } - __PRINT(_L("===========================================\n")); - } + if (iLookupTable.Count()) + { + TInt i = 0; + THashSetIter iter(iLookupTable); + TLookupEntry* pEntry; + pEntry = (TLookupEntry*) iter.Next(); + while(pEntry) + { + TDynamicDirCachePage* pP = pEntry->iPage; + __PRINT3(_L("=== CDynamicDirCache::iLookupTable\t[%4d](pos=%lx, size=%u)"), i++, pP->StartPos(), pP->PageSizeInBytes()); + pEntry = (TLookupEntry*) iter.Next(); + }; + } + __PRINT(_L("===========================================\n")); + } #endif //_DEBUG /** Lock an unlocked page, or do nothing if the page is already locked. -@return TUint8* pointer of the page to be locked, if locking is successful, otherwise return NULL. -@param aPage the pointer of the page to be locked. +@return TUint8* pointer of the page to be locked, if locking is successful, otherwise return NULL. +@param aPage the pointer of the page to be locked. */ TUint8* CDynamicDirCache::LockPage(TDynamicDirCachePage* aPage) - { - ASSERT(aPage != NULL); - if (aPage->IsLocked()) - return aPage->StartPtr(); + { + ASSERT(aPage != NULL); + if (aPage->IsLocked()) + return aPage->StartPtr(); - TInt r = iCacheMemoryClient->LockSegments(aPage->StartPtr(), PageSizeInSegs()); - if (r == KErrNone) - { - aPage->SetLocked(ETrue); - return aPage->StartPtr(); - } + TInt r = iCacheMemoryClient->LockSegments(aPage->StartPtr(), PageSizeInSegs()); + if (r == KErrNone) + { + aPage->SetLocked(ETrue); + return aPage->StartPtr(); + } - return NULL; - } + return NULL; + } /** Unlock a locked page. -@return TInt KErrNone if unlocking was successful, otherwise system-wide error code. -@param aPage the pointer of the page to be unlocked. +@return TInt KErrNone if unlocking was successful, otherwise system-wide error code. +@param aPage the pointer of the page to be unlocked. */ TInt CDynamicDirCache::UnlockPage(TDynamicDirCachePage* aPage) - { - ASSERT(aPage != NULL); - __PRINT1(_L("CDynamicDirCache::UnlockPage(%lx)"), aPage->StartPos()); - TInt r = iCacheMemoryClient->UnlockSegments(aPage->StartPtr(), PageSizeInSegs()); - if (r == KErrNone) - { - aPage->SetLocked(EFalse); - } - return r; - } + { + ASSERT(aPage != NULL); + __PRINT1(_L("CDynamicDirCache::UnlockPage(%lx)"), aPage->StartPos()); + TInt r = iCacheMemoryClient->UnlockSegments(aPage->StartPtr(), PageSizeInSegs()); + if (r == KErrNone) + { + aPage->SetLocked(EFalse); + } + return r; + } /** Decommit a locked or unlocked page. -@return TInt KErrNone if decommition was successful, otherwise system-wide error code. -@param aPage the pointer of the page to be decommitted. +@return TInt KErrNone if decommition was successful, otherwise system-wide error code. +@param aPage the pointer of the page to be decommitted. */ TInt CDynamicDirCache::DecommitPage(TDynamicDirCachePage* aPage) - { - ASSERT(aPage != NULL); - __PRINT1(_L("CDynamicDirCache::DecommitPage(%lx)"), aPage->StartPos()); - if (aPage) - { - TInt r = iCacheMemoryClient->DecommitSegments(aPage->StartPtr(), PageSizeInSegs()); - if (r == KErrNone) - { - aPage->SetLocked(EFalse); - aPage->SetValid(EFalse); - } - return r; - } - return KErrArgument; - } + { + ASSERT(aPage != NULL); + __PRINT1(_L("CDynamicDirCache::DecommitPage(%lx)"), aPage->StartPos()); + if (aPage) + { + TInt r = iCacheMemoryClient->DecommitSegments(aPage->StartPtr(), PageSizeInSegs()); + if (r == KErrNone) + { + aPage->SetLocked(EFalse); + aPage->SetValid(EFalse); + } + return r; + } + return KErrArgument; + } /////////////////////////// aluxiliary functions ////////////////////////////////// /** Calculate the page size in segments. Segment size is the size of the kernel memory unit that cache memory manager manages. We are making assumption here about the page size: page size should always be either less than segment size or multiple times of segment size -@return TUint32 the page size in segments. +@return TUint32 the page size in segments. */ TUint32 CDynamicDirCache::PageSizeInSegs() const - { - // initialize cache memory manager as all file systems have mounted by now - ASSERT(CCacheMemoryManagerFactory::CacheMemoryManager()); - const TUint32 SegmentSizeInBytesLog2 = CCacheMemoryManagerFactory::CacheMemoryManager()->SegmentSizeInBytesLog2(); + { + // initialize cache memory manager as all file systems have mounted by now + ASSERT(CCacheMemoryManagerFactory::CacheMemoryManager()); + const TUint32 SegmentSizeInBytesLog2 = CCacheMemoryManagerFactory::CacheMemoryManager()->SegmentSizeInBytesLog2(); - // Page size should be non-zero - ASSERT(iPageSizeInBytes); + // Page size should be non-zero + ASSERT(iPageSizeInBytes); - TUint32 segs = iPageSizeInBytes >> SegmentSizeInBytesLog2; - return segs > 0 ? segs : 1; - } + TUint32 segs = iPageSizeInBytes >> SegmentSizeInBytesLog2; + return segs > 0 ? segs : 1; + } /** Deque the page from locked queue or unlocked queue. All pages are managed through these two queues, expect iActive page. -@param aPage the pointer of the page to be dequeued -@return TInt KErrArgument if aPage is invalid, otherwise KErrNone. +@param aPage the pointer of the page to be dequeued +@return TInt KErrArgument if aPage is invalid, otherwise KErrNone. */ TInt CDynamicDirCache::DeQueue(TDynamicDirCachePage* aPage) - { - ASSERT(aPage); - if (!aPage) - return KErrArgument; + { + ASSERT(aPage); + if (!aPage) + return KErrArgument; - if (aPage->iType == TDynamicDirCachePage::ELocked) - { - aPage->Deque(); - aPage->SetPageType(TDynamicDirCachePage::EUnknown); - --iLockedQCount; - } - else if (aPage->iType == TDynamicDirCachePage::EUnlocked) - { - aPage->Deque(); - aPage->SetPageType(TDynamicDirCachePage::EUnknown); - --iUnlockedQCount; - } - else - { - ASSERT(0); - return KErrArgument; - } - return KErrNone; - } + if (aPage->iType == TDynamicDirCachePage::ELocked) + { + aPage->Deque(); + aPage->SetPageType(TDynamicDirCachePage::EUnknown); + --iLockedQCount; + } + else if (aPage->iType == TDynamicDirCachePage::EUnlocked) + { + aPage->Deque(); + aPage->SetPageType(TDynamicDirCachePage::EUnknown); + --iUnlockedQCount; + } + else + { + ASSERT(0); + return KErrArgument; + } + return KErrNone; + } /** Insert a page to the first position of locked queue or unlocked queue. -@param aPage the pointer of the page to be inserted. -@param aType the type of the queue to be inserted. -@return TInt KErrArgument if aPage is invalid, otherwise KErrNone. +@param aPage the pointer of the page to be inserted. +@param aType the type of the queue to be inserted. +@return TInt KErrArgument if aPage is invalid, otherwise KErrNone. */ TInt CDynamicDirCache::AddFirstOntoQueue(TDynamicDirCachePage* aPage, TDynamicDirCachePage::TPageType aType) - { - ASSERT(aPage); - if (!aPage) - return KErrArgument; + { + ASSERT(aPage); + if (!aPage) + return KErrArgument; - // page must be dequed first or it is active page - if (aPage->iType != TDynamicDirCachePage::EActivePage && aPage->iType != TDynamicDirCachePage::EUnknown) - { - ASSERT(0); - return KErrArgument; - } + // page must be dequed first or it is active page + if (aPage->iType != TDynamicDirCachePage::EActivePage && aPage->iType != TDynamicDirCachePage::EUnknown) + { + ASSERT(0); + return KErrArgument; + } - if (aType == TDynamicDirCachePage::ELocked) - { - iLockedQ.AddFirst(*aPage); - aPage->SetPageType(TDynamicDirCachePage::ELocked); - ++iLockedQCount; - } - else if (aType == TDynamicDirCachePage::EUnlocked) - { - iUnlockedQ.AddFirst(*aPage); - aPage->SetPageType(TDynamicDirCachePage::EUnlocked); - ++iUnlockedQCount; - } - else - { - ASSERT(0); - return KErrArgument; - } + if (aType == TDynamicDirCachePage::ELocked) + { + iLockedQ.AddFirst(*aPage); + aPage->SetPageType(TDynamicDirCachePage::ELocked); + ++iLockedQCount; + } + else if (aType == TDynamicDirCachePage::EUnlocked) + { + iUnlockedQ.AddFirst(*aPage); + aPage->SetPageType(TDynamicDirCachePage::EUnlocked); + ++iUnlockedQCount; + } + else + { + ASSERT(0); + return KErrArgument; + } - return KErrNone; - } + return KErrNone; + } /** Remove a page from the lookup table, indexed by the starting media address of the page content. -@param aPagePos the starting media position of the page to be removed. +@param aPagePos the starting media position of the page to be removed. */ TInt CDynamicDirCache::LookupTblRemove(TInt64 aPagePos) - { - if (aPagePos == 0) - { - return KErrNone; - } + { + if (aPagePos == 0) + { + return KErrNone; + } - TInt r = iLookupTable.Remove(TLookupEntry(aPagePos, 0, NULL)); - return r; - } + TInt r = iLookupTable.Remove(TLookupEntry(aPagePos, 0, NULL)); + return r; + } /** Insert a page to the lookup table, indexed by the starting media address of the page content. -@param aPagePos the starting media position of the page to be inserted. +@param aPagePos the starting media position of the page to be inserted. */ TInt CDynamicDirCache::LookupTblAdd(TDynamicDirCachePage* aPage) - { - ASSERT(aPage); - if (!aPage) - return KErrArgument; + { + ASSERT(aPage); + if (!aPage) + return KErrArgument; - if (aPage->StartPos() == 0) - { - return KErrNone; - } + if (aPage->StartPos() == 0) + { + return KErrNone; + } - TInt r = iLookupTable.Insert(TLookupEntry(aPage->StartPos(), iPageSizeInBytes, aPage)); - return r; - } + TInt r = iLookupTable.Insert(TLookupEntry(aPage->StartPos(), iPageSizeInBytes, aPage)); + return r; + } /** Reset the media address of the page to 0, also invalidate the page. -@param aPage the pointer of the page to be reset. +@param aPage the pointer of the page to be reset. */ TInt CDynamicDirCache::ResetPagePos(TDynamicDirCachePage* aPage) - { - ASSERT(aPage); - if (!aPage) - return KErrArgument; + { + ASSERT(aPage); + if (!aPage) + return KErrArgument; - aPage->ResetPos(); - return KErrNone; - } + aPage->ResetPos(); + return KErrNone; + } /** Search the lookup table to find the page start with a specific media address. -@param aPos the starting media address to be searched. +@param aPos the starting media address to be searched. */ TDynamicDirCachePage* CDynamicDirCache::LookupTblFind(TInt64 aPos) - { - if (aPos == 0) - { - ASSERT(0); - return NULL; - } + { + if (aPos == 0) + { + ASSERT(0); + return NULL; + } - TLookupEntry* entry = iLookupTable.Find(TLookupEntry(aPos, 0, NULL)); - if(entry) - { - ASSERT(entry->iPage->IsValid()); - return entry->iPage; - } + TLookupEntry* entry = iLookupTable.Find(TLookupEntry(aPos, 0, NULL)); + if(entry) + { + ASSERT(entry->iPage->IsValid()); + return entry->iPage; + } - return NULL; - } + return NULL; + }