106 @param aDrive local drive interface to read/write media |
104 @param aDrive local drive interface to read/write media |
107 @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. |
108 @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. |
109 @param aPageSizeInBytesLog2 the log2 value of page size in bytes, assumes page size is always a power of two |
107 @param aPageSizeInBytesLog2 the log2 value of page size in bytes, assumes page size is always a power of two |
110 */ |
108 */ |
111 CDynamicDirCache::CDynamicDirCache(TFatDriveInterface& aDrive, TUint32 aMinPageNum, TUint32 aMaxPageNum, TUint32 aPageSizeInBytesLog2) |
109 CDynamicDirCache::CDynamicDirCache(TDriveInterface& aDrive, TUint32 aMinPageNum, TUint32 aMaxPageNum, TUint32 aPageSizeInBytesLog2) |
112 :iPageSizeLog2(aPageSizeInBytesLog2), |
110 :iPageSizeLog2(aPageSizeInBytesLog2), |
113 iMinSizeInPages(aMinPageNum), |
111 iMinSizeInPages(aMinPageNum), |
114 iMaxSizeInPages(aMaxPageNum), |
112 iMaxSizeInPages(aMaxPageNum), |
115 iDrive(aDrive), |
113 iDrive(aDrive), |
116 iLockedQ(_FOFF(TDynamicDirCachePage, iLink)), |
114 iLockedQ(_FOFF(TDynamicDirCachePage, iLink)), |
153 if (!iCacheMemoryClient) |
151 if (!iCacheMemoryClient) |
154 { |
152 { |
155 User::Leave(KErrNoMemory); |
153 User::Leave(KErrNoMemory); |
156 } |
154 } |
157 |
155 |
158 // reserve active page |
156 |
159 iActivePage = AllocateAndLockNewPageL(0); |
157 // allocate as many permanently locked pages as there are threads - plus one |
160 ASSERT(iActivePage); |
158 // otherwise DoMakePageMRU() won't work properly with only one thread |
161 if (!iActivePage) |
159 //-- At present moment the size of TDrive thread pool is 1 (1 drive thread in a pool) |
162 { |
160 iPermanentlyAllocatedPageCount = 1; |
163 User::Leave(KErrNoMemory); |
161 |
164 } |
162 if (iPermanentlyAllocatedPageCount > iMinSizeInPages) |
165 iActivePage->SetPageType(TDynamicDirCachePage::EActivePage); |
163 iMinSizeInPages = iPermanentlyAllocatedPageCount; |
|
164 |
|
165 for (TUint n=0; n<iPermanentlyAllocatedPageCount; n++) |
|
166 { |
|
167 TDynamicDirCachePage* pPage = AllocateAndLockNewPageL(0); |
|
168 AddFirstOntoQueue(pPage, TDynamicDirCachePage::ELocked); |
|
169 LookupTblAdd(pPage); |
|
170 } |
|
171 |
166 } |
172 } |
167 |
173 |
168 /** |
174 /** |
169 Static factory function of CDynamicDirCache |
175 Static factory function of CDynamicDirCache |
170 */ |
176 */ |
171 CDynamicDirCache* CDynamicDirCache::NewL(TFatDriveInterface& aDrive, TUint32 aMinPageNum, TUint32 aMaxPageNum, TUint32 aPageSizeLog2, const TDesC& aClientName) |
177 CDynamicDirCache* CDynamicDirCache::NewL(TDriveInterface& aDrive, TUint32 aMinPageNum, TUint32 aMaxPageNum, TUint32 aPageSizeLog2, const TDesC& aClientName) |
172 { |
178 { |
173 // __PRINT3(_L("CDynamicDirCache::NewL(MinPageNum=%u, MaxPageNum=%u, page=%u)"), aMinPageNum, aMaxPageNum, 1<<aPageSizeLog2); |
179 __PRINT3(_L("CDynamicDirCache::NewL(MinPageNum=%u, MaxPageNum=%u, page=%u)"), aMinPageNum, aMaxPageNum, 1<<aPageSizeLog2); |
174 CDynamicDirCache* pSelf = new (ELeave) CDynamicDirCache(aDrive, aMinPageNum, aMaxPageNum, aPageSizeLog2); |
180 CDynamicDirCache* pSelf = new (ELeave) CDynamicDirCache(aDrive, aMinPageNum, aMaxPageNum, aPageSizeLog2); |
175 CleanupStack::PushL(pSelf); |
181 CleanupStack::PushL(pSelf); |
176 pSelf->ConstructL(aClientName); |
182 pSelf->ConstructL(aClientName); |
177 CleanupStack::Pop(); |
183 CleanupStack::Pop(); |
178 return pSelf; |
184 return pSelf; |
213 iLockedQCount++; |
219 iLockedQCount++; |
214 } |
220 } |
215 } |
221 } |
216 |
222 |
217 /** |
223 /** |
218 Read data from a single page. If the page is not found or not valid anymore, read media onto iActive page |
224 Read data from a single page. If the page is not found or not valid anymore, read media onto iActive page first. |
219 first. |
225 The data will be _Appended_ the the descriptor aDes. The caller is responsible for maintaining this descriptor. |
220 @param aPos the starting position of the media address to be read. |
226 |
221 @param aLength the length of the content to be read. |
227 @param aPos the starting position of the media address to be read. |
222 @param aDes the descriptor to contain the content. |
228 @param aLength the length of the content to be read. |
223 @pre aLength should be no more than page size. |
229 @param aDes the descriptor to contain the content. |
|
230 @pre aLength should be no more than page size. |
224 */ |
231 */ |
225 void CDynamicDirCache::ReadDataFromSinglePageL(TInt64 aPos, TInt aLength, TDes8& aDes) |
232 void CDynamicDirCache::ReadDataFromSinglePageL(TInt64 aPos, TInt aLength, TDes8& aDes) |
226 { |
233 { |
227 //-- the data section is in the cache page entirely, take data directly from the cache |
234 //-- the data section is in the cache page entirely, take data directly from the cache |
228 TDynamicDirCachePage* pPage = FindPageByPos(aPos); |
235 TDynamicDirCachePage* pPage = FindPageByPos(aPos); |
229 if (pPage) |
236 if (pPage) |
230 { |
237 { |
231 // lock page before reading, |
238 // lock page before reading, |
232 if (LockPage(pPage) != NULL) |
239 if (LockPage(pPage) != NULL) |
233 { |
240 { |
234 // read data |
241 // read data and append them to the descriptor |
235 aDes.Copy(pPage->PtrInPage(aPos), aLength); |
242 aDes.Append(pPage->PtrInPage(aPos), aLength); |
|
243 |
236 |
244 |
237 // if page is from unlocked queue, insert it onto the last page of the locked |
245 // if page is from unlocked queue, insert it onto the last page of the locked |
238 // queue. this is to avoid excessive locking and unlocking operations that is |
246 // queue. this is to avoid excessive locking and unlocking operations that is |
239 // highly likely to happen for following reads. |
247 // highly likely to happen for following reads. |
240 if (pPage->PageType() == TDynamicDirCachePage::EUnlocked) |
248 if (pPage->PageType() == TDynamicDirCachePage::EUnlocked) |
303 //-- 1. read data that are already in the current page |
311 //-- 1. read data that are already in the current page |
304 ReadDataFromSinglePageL(currMediaPos, bytesToPageEnd, aDes); |
312 ReadDataFromSinglePageL(currMediaPos, bytesToPageEnd, aDes); |
305 dataLen -= bytesToPageEnd; |
313 dataLen -= bytesToPageEnd; |
306 currMediaPos += bytesToPageEnd; |
314 currMediaPos += bytesToPageEnd; |
307 |
315 |
308 TPtr8 dataNext = aDes.MidTPtr(aDes.Length()); |
|
309 |
|
310 //-- 2. read whole pages of data |
316 //-- 2. read whole pages of data |
311 while (dataLen >= PageSz) |
317 while (dataLen >= PageSz) |
312 { |
318 { |
313 //-- find out if currMediaPos is in cache. If not, find a spare page and read data there |
319 //-- find out if currMediaPos is in cache. If not, find a spare page and read data there |
314 ReadDataFromSinglePageL(currMediaPos, PageSz, dataNext); |
320 ReadDataFromSinglePageL(currMediaPos, PageSz, aDes); |
315 currMediaPos += PageSz; |
321 currMediaPos += PageSz; |
316 dataLen -= PageSz; |
322 dataLen -= PageSz; |
317 dataNext = dataNext.MidTPtr(dataNext.Length()); |
|
318 } |
323 } |
319 |
324 |
320 //-- 3. read the rest of the data |
325 //-- 3. read the rest of the data |
321 if(dataLen > 0) |
326 if(dataLen > 0) |
322 { |
327 { |
323 ReadDataFromSinglePageL(currMediaPos, dataLen, dataNext); |
328 ReadDataFromSinglePageL(currMediaPos, dataLen, aDes); |
324 } |
329 } |
325 } //else((TUint32)aLength <= bytesToPageEnd) |
330 } //else((TUint32)aLength <= bytesToPageEnd) |
326 } |
331 } |
327 |
332 |
328 /** |
333 /** |
445 User::Leave(nErr); |
450 User::Leave(nErr); |
446 } |
451 } |
447 } |
452 } |
448 |
453 |
449 /** |
454 /** |
450 Implementation of pure virtual function. |
455 Invalidate the cache |
451 @see MWTCacheInterface::InvalidateCache() |
456 @see MWTCacheInterface::InvalidateCache() |
452 */ |
457 */ |
453 void CDynamicDirCache::InvalidateCache(void) |
458 void CDynamicDirCache::DoInvalidateCache(void) |
454 { |
459 { |
455 __PRINT2(_L("CDynamicDirCache::InvalidateCache(locked=%d, unlocked=%d)"), iLockedQCount, iUnlockedQCount); |
460 __PRINT2(_L("CDynamicDirCache::InvalidateCache(locked=%d, unlocked=%d)"), iLockedQCount, iUnlockedQCount); |
456 // we should never decommit locked pages as they needs to be reserved anyway |
461 // we should never decommit locked pages as they needs to be reserved anyway |
457 // the overhead of unnecessary page committing operations |
462 // the overhead of unnecessary page committing operations |
458 while(!iLockedQ.IsEmpty()) |
463 |
|
464 TInt pagesToRemoveFromLockedQueue = iLockedQCount - iPermanentlyAllocatedPageCount; |
|
465 TInt n; |
|
466 for (n=0; n<pagesToRemoveFromLockedQueue; n++) |
459 { |
467 { |
460 TDynamicDirCachePage* page = iLockedQ.Last(); |
468 TDynamicDirCachePage* page = iLockedQ.Last(); |
461 DeQueue(page); // remove from queue |
469 DeQueue(page); // remove from queue |
462 LookupTblRemove(page->StartPos()); // remove from lookuptable |
470 LookupTblRemove(page->StartPos()); // remove from lookuptable |
|
471 DecommitPage(page); // inform cache client to decommit page memory |
463 delete page; |
472 delete page; |
464 } |
473 } |
465 ASSERT(iLockedQCount == 0); |
474 ASSERT(iLockedQCount == iPermanentlyAllocatedPageCount); |
|
475 |
|
476 TDblQueIter<TDynamicDirCachePage> q(iLockedQ); |
|
477 q.SetToFirst(); |
|
478 while((TDynamicDirCachePage*) q) |
|
479 { |
|
480 TDynamicDirCachePage* page = q++; |
|
481 LookupTblRemove(page->StartPos());// remove from lookuptable |
|
482 ResetPagePos(page); // reset start media position (0), invalidate page content |
|
483 } |
466 |
484 |
467 // however we should decommit unlocked pages here |
485 // however we should decommit unlocked pages here |
468 while (!iUnlockedQ.IsEmpty()) |
486 while (!iUnlockedQ.IsEmpty()) |
469 { |
487 { |
470 TDynamicDirCachePage* page = iUnlockedQ.Last(); |
488 TDynamicDirCachePage* page = iUnlockedQ.Last(); |
473 DecommitPage(page); // inform cache client to decommit page memory |
491 DecommitPage(page); // inform cache client to decommit page memory |
474 delete page; |
492 delete page; |
475 } |
493 } |
476 ASSERT(iUnlockedQCount == 0); |
494 ASSERT(iUnlockedQCount == 0); |
477 |
495 |
478 ASSERT(iLookupTable.Count() == 0); |
496 ASSERT(iLockedQCount == iPermanentlyAllocatedPageCount); |
479 iLookupTable.Close(); |
|
480 |
497 |
481 ASSERT(iCacheMemoryClient); |
498 ASSERT(iCacheMemoryClient); |
482 |
499 } |
483 // initialize cache state. |
500 |
484 // Note that once the client is reset, all pages lose connection with the client |
501 /** |
485 // including the active page. So we will need to reset and re-allocate active page |
502 Implementation of pure virtual function. |
486 // properly. |
503 @see MWTCacheInterface::InvalidateCache() |
487 if (iCacheMemoryClient) |
504 */ |
488 iCacheMemoryClient->Reset(); |
505 void CDynamicDirCache::InvalidateCache(void) |
489 |
506 { |
490 // reset and re-allocate active page |
507 DoInvalidateCache(); |
491 ResetPagePos(iActivePage); // reset start media position (0), invalidate page content |
508 } |
492 TUint8* startRamAddr = iCacheMemoryClient->AllocateAndLockSegments(PageSizeInSegs()); |
|
493 // this should always succeed as the client has just been reset and there are always reserved pages |
|
494 ASSERT(startRamAddr); |
|
495 iActivePage->SetStartPtr(startRamAddr); // set RAM address |
|
496 } |
|
497 |
|
498 |
509 |
499 /** this method isn't implemented*/ |
510 /** this method isn't implemented*/ |
500 void CDynamicDirCache::InvalidateCachePage(TUint64 /*aPos*/) |
511 void CDynamicDirCache::InvalidateCachePage(TUint64 /*aPos*/) |
501 { |
512 { |
502 ASSERT(0); |
513 ASSERT(0); |
631 TUint32 CDynamicDirCache::PageSizeInBytesLog2() const |
642 TUint32 CDynamicDirCache::PageSizeInBytesLog2() const |
632 { |
643 { |
633 return iPageSizeLog2; |
644 return iPageSizeLog2; |
634 } |
645 } |
635 |
646 |
636 /** |
647 |
637 Implementation of pure virtual function. |
648 void CDynamicDirCache::DoMakePageMRU(TInt64 aPos) |
638 @see MWTCacheInterface::MakePageMRU() |
649 { |
639 */ |
650 // __PRINT1(_L("MakePageMRU (%lx)"), aPos); |
640 void CDynamicDirCache::MakePageMRU(TInt64 aPos) |
|
641 { |
|
642 __PRINT1(_L("MakePageMRU (%lx)"), aPos); |
|
643 // __PRINT4(_L("Current Cache State: iLockedQCount=%d, iUnlockedQCount=%d, iLookupTbl=%d, iMaxSizeInPages=%d"), iLockedQCount, iUnlockedQCount, iLookupTable.Count(), iMaxSizeInPages); |
651 // __PRINT4(_L("Current Cache State: iLockedQCount=%d, iUnlockedQCount=%d, iLookupTbl=%d, iMaxSizeInPages=%d"), iLockedQCount, iUnlockedQCount, iLookupTable.Count(), iMaxSizeInPages); |
644 // check the MRU page first, if it is already the MRU page, we can return immediately |
652 // check the MRU page first, if it is already the MRU page, we can return immediately |
645 TInt64 pageStartMedPos = CalcPageStartPos(aPos); |
653 TInt64 pageStartMedPos = CalcPageStartPos(aPos); |
646 if (!iLockedQ.IsEmpty()) |
654 if (!iLockedQ.IsEmpty()) |
647 { |
655 { |
687 } |
695 } |
688 |
696 |
689 // by now, the page is either locked or active page |
697 // by now, the page is either locked or active page |
690 ASSERT(pPage && pPage->IsValid() && pPage->IsLocked()); |
698 ASSERT(pPage && pPage->IsValid() && pPage->IsLocked()); |
691 |
699 |
|
700 |
|
701 |
|
702 TBool allocateNewPage = pPage == iLockedQ.Last() && !CacheIsFull(); |
|
703 |
|
704 |
692 switch (pPage->PageType()) |
705 switch (pPage->PageType()) |
693 { |
706 { |
694 // if the page is the active page, we will need to find a new active page for replacement |
|
695 case TDynamicDirCachePage::EActivePage: |
|
696 { |
|
697 TDynamicDirCachePage* newAP = NULL; |
|
698 // if there is more cache room available, try to create a new page first |
|
699 if (!CacheIsFull()) |
|
700 { |
|
701 // allocate and lock a new page |
|
702 TRAPD(err, newAP = AllocateAndLockNewPageL(0)); |
|
703 // if any error ocurrs, return immediately |
|
704 if (err != KErrNone) |
|
705 { |
|
706 // unlock the page that was originally unlocked before leave |
|
707 if (pPage->PageType() == TDynamicDirCachePage::EUnlocked) |
|
708 { |
|
709 UnlockPage(pPage); |
|
710 } |
|
711 return; |
|
712 } |
|
713 |
|
714 if (newAP) |
|
715 { |
|
716 // replace the active page with the new page |
|
717 newAP->SetPageType(TDynamicDirCachePage::EActivePage); |
|
718 iActivePage = newAP; |
|
719 } |
|
720 } |
|
721 |
|
722 // if cache has grown to its max size, or new page allocation failed |
|
723 if (!newAP) |
|
724 { |
|
725 // try to lock the LRU page on the unlocked page queque first |
|
726 if (!iUnlockedQ.IsEmpty()) |
|
727 { |
|
728 newAP = iUnlockedQ.Last(); |
|
729 ASSERT(newAP->IsValid()); |
|
730 if (LockPage(newAP) != NULL) |
|
731 { |
|
732 // deque, reset pos, set new type |
|
733 DeQueue(newAP); |
|
734 LookupTblRemove(newAP->StartPos()); |
|
735 ResetPagePos(newAP); |
|
736 newAP->SetPageType(TDynamicDirCachePage::EActivePage); |
|
737 // replace active page |
|
738 iActivePage = newAP; |
|
739 } |
|
740 // if falied locking the LRU page from unclocked queque, |
|
741 // delete it |
|
742 else |
|
743 { |
|
744 DeQueue(newAP); |
|
745 LookupTblRemove(newAP->StartPos()); |
|
746 DecommitPage(newAP); |
|
747 delete newAP; |
|
748 newAP = NULL; |
|
749 } |
|
750 } |
|
751 } |
|
752 |
|
753 // if still have not found new active page |
|
754 // grab the LRU page from Locked Page Queue for active page |
|
755 if (!newAP) |
|
756 { |
|
757 ASSERT(!iLockedQ.IsEmpty()); |
|
758 newAP = iLockedQ.Last(); |
|
759 // deque, reset pos, set new type |
|
760 DeQueue(newAP); |
|
761 LookupTblRemove(newAP->StartPos()); |
|
762 ResetPagePos(newAP); |
|
763 newAP->SetPageType(TDynamicDirCachePage::EActivePage); |
|
764 // replace active page |
|
765 iActivePage = newAP; |
|
766 } |
|
767 |
|
768 // we should always be able to find a locked page for active page |
|
769 ASSERT(newAP != NULL); |
|
770 |
|
771 // make original page (i.e. former active page) MRU |
|
772 // add onto locked queue |
|
773 AddFirstOntoQueue(pPage, TDynamicDirCachePage::ELocked); |
|
774 // add onto lookuptbl, as active page is not on lookup tbl originally |
|
775 LookupTblAdd(pPage); |
|
776 // check cache limit |
|
777 CheckThresholds(); |
|
778 return; |
|
779 } |
|
780 case TDynamicDirCachePage::EUnlocked: |
707 case TDynamicDirCachePage::EUnlocked: |
781 { |
708 { |
782 // if page was originally on Unlocked Page Queque, remove it from Unlocked Page Queue, add it |
709 // if page was originally on Unlocked Page Queque, remove it from Unlocked Page Queue, add it |
783 // to the Locked Page Queue and make it MRU |
710 // to the Locked Page Queue and make it MRU |
784 DeQueue(pPage); |
711 DeQueue(pPage); |
785 AddFirstOntoQueue(pPage, TDynamicDirCachePage::ELocked); |
712 AddFirstOntoQueue(pPage, TDynamicDirCachePage::ELocked); |
786 // check cache limit |
713 // check cache limit |
787 CheckThresholds(); |
714 CheckThresholds(); |
788 return; |
|
789 } |
715 } |
790 case TDynamicDirCachePage::ELocked: |
716 case TDynamicDirCachePage::ELocked: |
791 { |
717 { |
792 // otherwise the page was on Locked Page Queue, make it MRU |
718 // otherwise the page was on Locked Page Queue, make it MRU |
793 // no need to check cache limit |
719 // no need to check cache limit |
794 if (pPage != iLockedQ.First()) |
720 if (pPage != iLockedQ.First()) |
795 { |
721 { |
796 DeQueue(pPage); |
722 DeQueue(pPage); |
797 AddFirstOntoQueue(pPage, TDynamicDirCachePage::ELocked); |
723 AddFirstOntoQueue(pPage, TDynamicDirCachePage::ELocked); |
798 return; |
|
799 } |
724 } |
800 break; |
725 break; |
801 } |
726 } |
802 default: |
727 default: |
803 ASSERT(0); |
728 ASSERT(0); |
804 } |
729 } |
|
730 |
|
731 if (allocateNewPage) |
|
732 { |
|
733 TDynamicDirCachePage* nPage = NULL; |
|
734 TRAPD(err, nPage = AllocateAndLockNewPageL(0)); |
|
735 if (err == KErrNone) |
|
736 { |
|
737 |
|
738 // about to add a page to end of locked queue, so lie about iLockedQCount |
|
739 iLockedQCount++; |
|
740 CheckThresholds(); |
|
741 iLockedQCount--; |
|
742 |
|
743 iLockedQ.AddLast(*nPage); |
|
744 nPage->SetPageType(TDynamicDirCachePage::ELocked); |
|
745 ++iLockedQCount; |
|
746 LookupTblAdd(nPage); |
|
747 } |
|
748 } |
|
749 } |
|
750 |
|
751 /** |
|
752 Implementation of pure virtual function. |
|
753 @see MDiskSpecialAccessor::MakePageMRU() |
|
754 */ |
|
755 void CDynamicDirCache::MakePageMRU(TInt64 aPos) |
|
756 { |
|
757 DoMakePageMRU(aPos); |
805 } |
758 } |
806 |
759 |
807 //==================================================================== |
760 //==================================================================== |
808 /** |
761 /** |
809 Internal query function, to check if aPos is cached or not. iActive page is included in searching. |
762 Internal query function, to check if aPos is cached or not. iActive page is included in searching. |
810 */ |
763 */ |
811 TDynamicDirCachePage* CDynamicDirCache::FindPageByPos(TInt64 aPos) |
764 TDynamicDirCachePage* CDynamicDirCache::FindPageByPos(TInt64 aPos) |
812 { |
765 { |
813 __PRINT1(_L("CDynamicDirCache::FindPageByPos(aPos=%lx)"), aPos); |
766 // __PRINT1(_L("CDynamicDirCache::FindPageByPos(aPos=%lx)"), aPos); |
814 // align the page position |
767 // align the page position |
815 TInt64 pageStartMedPos = CalcPageStartPos(aPos); |
768 TInt64 pageStartMedPos = CalcPageStartPos(aPos); |
816 |
769 |
817 if ((iActivePage->StartPos() == pageStartMedPos)) |
|
818 { |
|
819 ASSERT(iActivePage->IsValid()); |
|
820 return iActivePage; |
|
821 } |
|
822 |
|
823 // search in lookup table |
770 // search in lookup table |
824 return LookupTblFind(pageStartMedPos); |
771 return LookupTblFind(pageStartMedPos); |
825 } |
772 } |
826 |
773 |
827 /** |
774 /** |
830 TDynamicDirCachePage* CDynamicDirCache::UpdateActivePageL(TInt64 aPos) |
777 TDynamicDirCachePage* CDynamicDirCache::UpdateActivePageL(TInt64 aPos) |
831 { |
778 { |
832 // align the page position |
779 // align the page position |
833 TInt64 pageStartMedPos = CalcPageStartPos(aPos); |
780 TInt64 pageStartMedPos = CalcPageStartPos(aPos); |
834 |
781 |
835 if (iActivePage->StartPos() == pageStartMedPos && iActivePage->IsValid()) |
782 ASSERT(!iLockedQ.IsEmpty()); |
836 { |
783 TDynamicDirCachePage* activePage = iLockedQ.Last(); |
837 return iActivePage; |
784 |
838 } |
785 if (activePage->StartPos() == pageStartMedPos && activePage->IsValid()) |
839 |
786 { |
840 __PRINT2(_L("CDynamicDirCache::UpdateActivePageL(aPos=%lx, active=%lx)"), aPos, iActivePage->StartPos()); |
787 return activePage; |
|
788 } |
|
789 |
|
790 __PRINT2(_L("CDynamicDirCache::UpdateActivePageL(aPos=%lx, active=%lx)"), aPos, activePage->StartPos()); |
|
791 |
|
792 activePage->Deque(); |
|
793 LookupTblRemove(activePage->StartPos()); |
841 |
794 |
842 // set start med pos value, no other effects, only available to active page |
795 // set start med pos value, no other effects, only available to active page |
843 iActivePage->SetPos(pageStartMedPos); |
796 activePage->SetPos(pageStartMedPos); |
844 |
797 |
845 // read data, make active page valid |
798 // read data, make active page valid |
846 TUint8* data = iActivePage->PtrInPage(iActivePage->iStartMedPos); |
799 TUint8* data = activePage->PtrInPage(activePage->iStartMedPos); |
847 TPtr8 dataPtr(data, iPageSizeInBytes); |
800 TPtr8 dataPtr(data, iPageSizeInBytes); |
848 const TInt nErr = iDrive.ReadNonCritical(iActivePage->iStartMedPos, iPageSizeInBytes, dataPtr); |
801 |
|
802 const TInt nErr = iDrive.ReadNonCritical(activePage->iStartMedPos, iPageSizeInBytes, dataPtr); |
|
803 |
|
804 iLockedQ.AddLast(*activePage); |
|
805 LookupTblAdd(activePage); |
|
806 |
849 if(nErr !=KErrNone) |
807 if(nErr !=KErrNone) |
850 { |
808 { |
851 // some serious problem occured during reading, invalidate cache. |
809 // some serious problem occured during reading, invalidate cache. |
852 InvalidateCache(); |
810 DoInvalidateCache(); |
853 User::Leave(nErr); |
811 User::Leave(nErr); |
854 } |
812 } |
855 iActivePage->SetValid(ETrue); |
813 activePage->SetValid(ETrue); |
856 |
814 |
857 return iActivePage; |
815 return activePage; |
858 } |
816 } |
859 |
817 |
860 /** |
818 /** |
861 Check if the number of (locked pages + iActive page) and unlocked pages have exceeded minimum allowed page |
819 Check if the number of (locked pages + iActive page) and unlocked pages have exceeded minimum allowed page |
862 number and maximum allowed page number respectively. |
820 number and maximum allowed page number respectively. |
969 q.SetToFirst(); |
927 q.SetToFirst(); |
970 TInt i = 0; |
928 TInt i = 0; |
971 while((TDynamicDirCachePage*)q) |
929 while((TDynamicDirCachePage*)q) |
972 { |
930 { |
973 TDynamicDirCachePage* pP = q++; |
931 TDynamicDirCachePage* pP = q++; |
974 __PRINT3(_L("=== CDynamicDirCache::iLockedQ\t[%4d](pos=%lx, size=%d)"), i++, pP->StartPos(), pP->PageSizeInBytes()); |
932 __PRINT5(_L("=== CDynamicDirCache::iLockedQ\t[%4d](pos=%lx, locked=%d, valid=%d, size=%u)"), i++, pP->StartPos(), pP->IsLocked(), pP->IsValid(), pP->PageSizeInBytes()); |
975 } |
933 } |
976 } |
934 } |
977 if (!iUnlockedQ.IsEmpty()) |
935 if (!iUnlockedQ.IsEmpty()) |
978 { |
936 { |
979 TDblQueIter<TDynamicDirCachePage> q(iUnlockedQ); |
937 TDblQueIter<TDynamicDirCachePage> q(iUnlockedQ); |
980 q.SetToFirst(); |
938 q.SetToFirst(); |
981 TInt i = 0; |
939 TInt i = 0; |
982 while((TDynamicDirCachePage*)q) |
940 while((TDynamicDirCachePage*)q) |
983 { |
941 { |
984 TDynamicDirCachePage* pP = q++; |
942 TDynamicDirCachePage* pP = q++; |
985 __PRINT3(_L("=== CDynamicDirCache::iUnlockedQ\t[%4d](pos=%lx, size=%u)"), i++, pP->StartPos(), pP->PageSizeInBytes()); |
943 __PRINT5(_L("=== CDynamicDirCache::iUnlockedQ\t[%4d](pos=%lx, locked=%d, valid=%d, size=%u)"), i++, pP->StartPos(), pP->IsLocked(), pP->IsValid(), pP->PageSizeInBytes()); |
986 } |
944 } |
987 } |
945 } |
988 __PRINT2(_L("=== CDynamicDirCache::iActivePage\t[*](pos=%lx, size=%u)"), iActivePage->StartPos(), iActivePage->PageSizeInBytes()); |
|
989 |
946 |
990 if (iLookupTable.Count()) |
947 if (iLookupTable.Count()) |
991 { |
948 { |
992 TInt i = 0; |
949 TInt i = 0; |
993 THashSetIter<TLookupEntry> iter(iLookupTable); |
950 THashSetIter<TLookupEntry> iter(iLookupTable); |
994 TLookupEntry* pEntry; |
951 TLookupEntry* pEntry; |
995 pEntry = (TLookupEntry*) iter.Next(); |
952 pEntry = (TLookupEntry*) iter.Next(); |
996 while(pEntry) |
953 while(pEntry) |
997 { |
954 { |
998 TDynamicDirCachePage* pP = pEntry->iPage; |
955 TDynamicDirCachePage* pP = pEntry->iPage; |
999 __PRINT3(_L("=== CDynamicDirCache::iLookupTable\t[%4d](pos=%lx, size=%u)"), i++, pP->StartPos(), pP->PageSizeInBytes()); |
956 __PRINT5(_L("=== CDynamicDirCache::iLookupTable\t[%4d](pos=%lx, locked=%d, valid=%d, size=%u)"), i++, pP->StartPos(), pP->IsLocked(), pP->IsValid(), pP->PageSizeInBytes()); |
1000 pEntry = (TLookupEntry*) iter.Next(); |
957 pEntry = (TLookupEntry*) iter.Next(); |
1001 }; |
958 }; |
1002 } |
959 } |
1003 __PRINT(_L("===========================================\n")); |
960 __PRINT(_L("===========================================\n")); |
1004 } |
961 } |