diff -r 10e98eab6f85 -r a359256acfc6 webengine/osswebengine/cache/src/HttpCacheManager.cpp --- a/webengine/osswebengine/cache/src/HttpCacheManager.cpp Fri Jul 03 15:54:40 2009 +0100 +++ b/webengine/osswebengine/cache/src/HttpCacheManager.cpp Thu Aug 27 07:44:59 2009 +0300 @@ -19,6 +19,7 @@ #include "HttpCacheManager.h" #include "HttpCacheHandler.h" #include "HttpCacheUtil.h" +#include "HttpCacheFileWriteHandler.h" #include #include #include @@ -40,10 +41,13 @@ // kbyte const TUint KDefaultCacheSize = 1048576; // 1MB = 1024*1024 _LIT( KDefaultCacheDir, "c:\\cache\\"); +_LIT( KDefaultOperatorCacheDir, "c:\\cache\\op\\"); +_LIT( KDefaultVssCacheDir, "c:\\cache\\vss\\"); _LIT( KDefaultIndexFile, "index.dat" ); _LIT( KDefaultOpIndexFile, "index_op.dat" ); _LIT( KDefaultVSSIndexFile, "index_vss.dat" ); _LIT( KIndexFileExtension, ".dat" ); +_LIT( KValidationFileExtension, ".val" ); _LIT8( KVSSHeaderFileldName, "X-Vodafone-Content" ); _LIT8( KVSSHeaderFileldValue, "Portal" ); @@ -115,7 +119,9 @@ return self; } +// ----------------------------------------------------------------------------- // Destructor +// ----------------------------------------------------------------------------- CHttpCacheManager::~CHttpCacheManager() { delete iOfflineNotifyHandler; @@ -125,6 +131,7 @@ delete iOpDomain; delete iphoneSpecificCache; delete iVSSWhiteList; + delete iFileWriteHandler; } // ----------------------------------------------------------------------------- @@ -132,9 +139,9 @@ // // ----------------------------------------------------------------------------- // -TBool CHttpCacheManager::VSSRequestCheck( const RHTTPTransaction& aTrans, - const RHTTPHeaders& aHttpHeader, - const TDesC8& aUrl ) +TBool CHttpCacheManager::VSSRequestCheckL( const RHTTPTransaction& aTrans, + const RHTTPHeaders& aHttpHeader, + const TDesC8& aUrl ) { TBool VSSTransaction ( EFalse ); if ( iVSSCacheEnabled && HttpCacheUtil::VSSCacheContent( aUrl, iVSSWhiteList ) ) @@ -178,9 +185,9 @@ } CleanupStack::PopAndDestroy(); // VSSnameStr } //end if( iVSSCacheEnabled && HttpCacheUtil::VSSCacheContent( aUrl, iVSSWhiteList ) ) - return VSSTransaction; } + // ----------------------------------------------------------------------------- // CHttpCacheManager::RequestL // @@ -214,18 +221,18 @@ status = iphoneSpecificCache->RequestL( aTrans, aCacheMode, aCacheEntry ); if( (status == KErrNotReady) || (status == KErrNone ) ) { - aCacheEntry.iCacheHandler = iphoneSpecificCache; + aCacheEntry.iCacheHandler = iphoneSpecificCache; } else { // No entry found in any cache. Default to normal cache - aCacheEntry.iCacheHandler = cache; + aCacheEntry.iCacheHandler = cache; } - } + } else { - aCacheEntry.iCacheHandler = cache; - } + aCacheEntry.iCacheHandler = cache; + } } //end if( cache ) }//end if( iCacheEnabled || iVSSCacheEnabled ) @@ -260,11 +267,11 @@ THttpCacheEntry& aCacheEntry ) { HBufC8* bodyStr = NULL; - if( ( iCacheEnabled || iVSSCacheEnabled ) && aCacheEntry.iCacheHandler ) { bodyStr = aCacheEntry.iCacheHandler->RequestNextChunkL( aTrans, aLastChunk, aCacheEntry ); } + return bodyStr; } @@ -292,15 +299,16 @@ RHTTPTransaction& aTrans, THttpCacheEntry& aCacheEntry ) { - if( iCacheEnabled || iVSSCacheEnabled ) + if ( iCacheEnabled || iVSSCacheEnabled ) { - if( iVSSCacheEnabled && VSSRequestCheck( aTrans, aTrans.Response().GetHeaderCollection(), - aTrans.Request().URI().UriDes() ) ) + if ( iVSSCacheEnabled && + VSSRequestCheckL( aTrans, aTrans.Response().GetHeaderCollection(), + aTrans.Request().URI().UriDes() ) ) { //Modify the cache handler if VSS specific aCacheEntry.iCacheHandler = iphoneSpecificCache; } - if( aCacheEntry.iCacheHandler ) + if ( aCacheEntry.iCacheHandler ) { aCacheEntry.iCacheHandler->ReceivedResponseHeadersL( aTrans, aCacheEntry ); } @@ -340,7 +348,7 @@ // ----------------------------------------------------------------------------- // CHttpCacheManager::RemoveAllL -// Removes all files from HTTP cache. Also tries to remove orphaned files, +// Removes all files from HTTP cache. Also tries to remove orphaned files, // i.e files found on disk, but not registered in the cache's lookup table // ----------------------------------------------------------------------------- // @@ -352,43 +360,46 @@ { numOfBytes = iCache->RemoveAllL(); } - + //failure here is not mission critical - TRAP_IGNORE( RemoveOrphanedFilesL() ); - + TRAP_IGNORE( RemoveOrphanedFilesL() ); + return numOfBytes; } - +// ----------------------------------------------------------------------------- +// FilePathHash // Hash function for Symbian file paths: discards case first +// ----------------------------------------------------------------------------- static TUint32 FilepathHash(const TDesC& aDes) { - //since this function is intensively used by the HashMap, - //keeping (slow) heap allocation out of it. - TBuf normalized ( aDes ); - + //since this function is intensively used by the HashMap, + //keeping (slow) heap allocation out of it. + TBuf normalized ( aDes ); + normalized.LowerCase(); return DefaultHash::Des16( normalized ); } -// Comparator for Symbian file paths: Use case-insensitive compare +// ----------------------------------------------------------------------------- +// FilepathIdent +// Comparator for Symbian file paths: Use case-insensitive compare +// ----------------------------------------------------------------------------- static TBool FilepathIdent(const TDesC& aL, const TDesC& aR) { - return ( aL.CompareF(aR) == 0 ); + return ( aL.CompareF(aR) == 0 ); } - // ----------------------------------------------------------------------------- -// CHttpCacheManager::RemoveOrphanedFilesL +// CHttpCacheManager::RemoveOrphanedFilesL // Removes header/body files that exist on the file-system, but are not known to the in-memory Cache lookup table(s) -// We do this because cache performance degrades substantially if there are too many files in a Symbian FAT32 directory. -// Browser crash or out-of-battery situations may cause SaveLookuptable() to be not called, leading to such "orphaned files". -// Due to high file-server interaction, don't call this method from performance critical code. +// We do this because cache performance degrades substantially if there are too many files in a Symbian FAT32 directory. +// Browser crash or out-of-battery situations may cause SaveLookuptable() to be not called, leading to such "orphaned files". +// Due to high file-server interaction, don't call this method from performance critical code. // ----------------------------------------------------------------------------- void CHttpCacheManager::RemoveOrphanedFilesL() { - - //Map that contains pointers to fully-qualified file paths as Keys, and "to be deleted flag" as Value. + //Map that contains pointers to fully-qualified file paths as Keys, and "to be deleted flag" as Value. RPtrHashMap onDiskFilesMap(&FilepathHash, &FilepathIdent); CleanupClosePushL( onDiskFilesMap ); @@ -397,7 +408,7 @@ const TInt needsDelete( 1 ); const TInt noDelete( 0 ); - //collects objects that need to be deleted later on + //collects objects that need to be deleted later on RPointerArray cleanupList; CleanupResetAndDestroyPushL( cleanupList ); @@ -411,20 +422,22 @@ //Step 1. Find out all files on disk: by walking the directory hierarchy, one directory at a time for (;;) { - //1a. Get list of files in current directory, NULL if no directory left in tree + //1a. Get list of files in current directory, NULL if no directory left in tree scanner->NextL( matchingFiles ); if ( !matchingFiles ) break; - TPtrC dir( scanner->FullPath() ); - + TPtrC dir( scanner->FullPath() ); + //1b. Add any files found to the HashTable const TInt nMatches = matchingFiles->Count(); for ( TInt i = 0; i < nMatches; i++ ) { - TEntry entry ( (*matchingFiles)[i] ) ; - if (entry.iName.Right( KIndexFileExtension().Length() ). - CompareF( KIndexFileExtension ) != 0) // ignore any .dat index files + TEntry entry ( (*matchingFiles)[i] ) ; + TPtrC ext( entry.iName.Right( KIndexFileExtension().Length() )); + + if ( ext.CompareF( KIndexFileExtension ) != 0 && // ignore any .dat index files + ext.CompareF( KValidationFileExtension ) != 0 ) // ignore any .val index files { HBufC* fullPath = HBufC::NewL( dir.Length() + entry.iName.Length() ); cleanupList.Append( fullPath ); //keep object safe for later destruction @@ -433,7 +446,6 @@ onDiskFilesMap.Insert( fullPath, &needsDelete ); //add to the hash } } - delete matchingFiles; } // End of step 1: adding all known files on disk to Map @@ -442,29 +454,29 @@ #ifdef __CACHELOG__ { - RDebug::Print(_L("-----------START PRINTING MAP OF SIZE %d---------"), onDiskFilesMap.Count()); + HttpCacheUtil::WriteFormatLog(0, _L("-----------START PRINTING MAP OF SIZE %d---------"), onDiskFilesMap.Count()); TPtrHashMapIter iter(onDiskFilesMap); const TDesC* key; while ((key = iter.NextKey()) != 0) { const TInt val = *(iter.CurrentValue()); - RDebug::Print(_L("MAP WALK: %S, with value = %d "), key, val); + HttpCacheUtil::WriteFormatLog(0, _L("MAP WALK: %S, with value = %d "), key, val); } - RDebug::Print(_L("-----------DONE PRINTING MAP-------------")); + HttpCacheUtil::WriteFormatLog(0, _L("-----------DONE PRINTING MAP-------------")); } #endif - + //Step 2. Get list of known (non-orphaned) files in each Cache's in-memory lookup table. Flag them as DO NOT DELETE - RPointerArray knownFiles; + RPointerArray knownFiles; CleanupClosePushL( knownFiles ); - //Ask CacheHandlers to add their KNOWN files to this array. No ownership transfer occurs. + //Ask CacheHandlers to add their KNOWN files to this array. No ownership transfer occurs. //Don't go ahead if any of the cache handlers choke to insure correct deletion of files. if (iCache) - User::LeaveIfError( iCache->ListFiles( knownFiles ) ); + User::LeaveIfError( iCache->ListFiles( knownFiles ) ); if (iOperatorCache) User::LeaveIfError( iOperatorCache->ListFiles( knownFiles ) ); if (iphoneSpecificCache) - User::LeaveIfError( iphoneSpecificCache->ListFiles( knownFiles ) ); + User::LeaveIfError( iphoneSpecificCache->ListFiles( knownFiles ) ); //2a. HashTable lookup, and modification of flag for (TInt i = 0; i < knownFiles.Count(); i++) @@ -474,18 +486,19 @@ if (ptr) { // Reinsert into Map, this time with NO DELETE - onDiskFilesMap.Insert( knownFiles[i], &noDelete ); - + onDiskFilesMap.Insert( knownFiles[i], &noDelete ); +#if 0 // no header files any more. // Add the header file to HashMap - HBufC* headerFile = HBufC::NewL( KHttpCacheHeaderExt().Length() + (*(knownFiles[i])).Length() ); + HBufC* headerFile = HBufC::NewL( KHttpCacheHeaderExt().Length() + (*(knownFiles[i])).Length() ); cleanupList.Append( headerFile ); //keep for later destruction - TPtr ptr( headerFile->Des() ); + TPtr ptr( headerFile->Des() ); HttpCacheUtil::GetHeaderFileName( *(knownFiles[i]), ptr ); onDiskFilesMap.Insert( headerFile, &noDelete ); // register Header files as NO DELETE +#endif } } - knownFiles.Close(); + knownFiles.Close(); CleanupStack::Pop( 1, &knownFiles ); //Step 3. Delete all files on disk that don't belong to any of the Cache Handlers. @@ -501,12 +514,12 @@ } delete fileMan; - CleanupStack::Pop(1, &cleanupList); + CleanupStack::Pop(1, &cleanupList); cleanupList.ResetAndDestroy(); //should delete all HBufC objects - + CleanupStack::Pop(1, &onDiskFilesMap); onDiskFilesMap.Close(); // doesn't own any K,V object - + } // ----------------------------------------------------------------------------- @@ -667,6 +680,17 @@ CRepository* repositoryDiskLevel = CRepository::NewLC( KCRUidDiskLevel ); TInt err; + // Get Cache Postpone Parameters. + // + THttpCachePostponeParameters postpone; + + if (KErrNone == repository->Get(KCacheWritePostponeEnabled, postpone.iEnabled) ) + { + User::LeaveIfError( repository->Get( KCacheWritePostponeFreeRAMThreshold, postpone.iFreeRamThreshold ) ); + User::LeaveIfError( repository->Get( KCacheWritePostponeImmediateWriteThreshold, postpone.iImmediateWriteThreshold ) ); + User::LeaveIfError( repository->Get( KCacheWritePostponeWriteTimeout, postpone.iWriteTimeout ) ); + } + // cache on/off TInt cacheEnabled( 0 ); err = repository->Get( KCacheManagerHttpCacheEnabled, cacheEnabled ); @@ -684,61 +708,62 @@ { iCacheFolder.Append( _L("\\") ); } - - // get drive letter for sysutil - TParsePtrC pathParser( iCacheFolder ); - TDriveUnit drive = pathParser.Drive(); - // get critical level - // RAM drive can have different critical level - TVolumeInfo vinfo; - User::LeaveIfError( CCoeEnv::Static()->FsSession().Volume( vinfo, drive ) ); - // - TInt criticalLevel; - User::LeaveIfError( repositoryDiskLevel->Get( ( vinfo.iDrive.iType == EMediaRam ? KRamDiskCriticalLevel : KDiskCriticalThreshold ), - criticalLevel ) ); - if( (err == KErrNone) && iCacheEnabled ) + // get drive letter for sysutil + TParsePtrC pathParser( iCacheFolder ); + TDriveUnit drive = pathParser.Drive(); + // get critical level + // RAM drive can have different critical level + TVolumeInfo vinfo; + User::LeaveIfError( CCoeEnv::Static()->FsSession().Volume( vinfo, drive ) ); + // + TInt criticalLevel; + User::LeaveIfError( repositoryDiskLevel->Get( ( vinfo.iDrive.iType == EMediaRam ? KRamDiskCriticalLevel : KDiskCriticalThreshold ), + criticalLevel ) ); + + if ( (err == KErrNone) && iCacheEnabled ) { // create cache handler - iCache = CHttpCacheHandler::NewL( cacheSize, iCacheFolder, KDefaultIndexFile(), criticalLevel ); + iCache = CHttpCacheHandler::NewL( cacheSize, iCacheFolder, KDefaultIndexFile(), criticalLevel, postpone); // create operator cache. same settings - if( FeatureManager::FeatureSupported( KFeatureIdOperatorCache ) ) + if ( FeatureManager::FeatureSupported( KFeatureIdOperatorCache ) ) { TBuf<512> url; // if domain is missing, then no need to read further - if( repository->Get( KOperatorDomainUrl, url ) == KErrNone ) + if ( repository->Get( KOperatorDomainUrl, url ) == KErrNone ) { HBufC8* opDomain8 = HBufC8::NewL( url.Length() ); - CleanupStack::PushL(opDomain8); - opDomain8->Des().Append( url ); + CleanupStack::PushL(opDomain8); + opDomain8->Des().Append( url ); - TInt slashPos = opDomain8->LocateReverse('/'); - if(slashPos == -1) - { - slashPos = 0; - } - TPtrC8 temp = opDomain8->Left(slashPos); - iOpDomain = temp.AllocL(); - CleanupStack::PopAndDestroy(opDomain8); + TInt slashPos = opDomain8->LocateReverse('/'); + if (slashPos == -1) + { + slashPos = 0; + } + + TPtrC8 temp = opDomain8->Left(slashPos); + iOpDomain = temp.AllocL(); + CleanupStack::PopAndDestroy(opDomain8); // op cache size TInt opCacheSize( KDefaultCacheSize ); repository->Get( KOperatorCacheSize, opCacheSize ); // op cache folder - TFileName opCacheFolder( KDefaultCacheDir ); + TFileName opCacheFolder( KDefaultOperatorCacheDir ); repository->Get( KOperatorCacheFolder, opCacheFolder ); - if( opCacheFolder.LocateReverse( '\\' ) != opCacheFolder.Length() - 1 ) + if ( opCacheFolder.LocateReverse( '\\' ) != opCacheFolder.Length() - 1 ) { opCacheFolder.Append( _L("\\") ); } // create op cache - iOperatorCache = CHttpCacheHandler::NewL( opCacheSize, opCacheFolder, KDefaultOpIndexFile(), criticalLevel ); - } + iOperatorCache = CHttpCacheHandler::NewL( opCacheSize, opCacheFolder, KDefaultOpIndexFile(), criticalLevel, postpone); + } } //end if( FeatureManager::FeatureSupported( KFeatureIdOperatorCache ) ) } //end if( iCacheEnabled ) @@ -746,15 +771,15 @@ err = repository->Get( KPhoneSpecificCacheEnabled, VSScacheEnabled ); iVSSCacheEnabled = VSScacheEnabled; - - if( (err == KErrNone) && iVSSCacheEnabled ) + + if ( (err == KErrNone) && iVSSCacheEnabled ) { // cache size TInt VSScacheSize( KDefaultCacheSize ); repository->Get( KPhoneSpecificCacheSize, VSScacheSize ); // cache folder - TFileName VSScacheFolder( KDefaultCacheDir ); + TFileName VSScacheFolder( KDefaultVssCacheDir ); // ignore cache folder. use c:\ to save memory. (same for operator cache. see below) repository->Get( KPhoneSpecificCacheFolder, VSScacheFolder ); // fix folder by appending trailing \\ to the end -symbian thing @@ -767,7 +792,7 @@ //Get the white list TBuf<2048> whiteList; - if( repository->Get( KPhoneSpecificCacheDomainUrl, whiteList ) == KErrNone ) + if ( repository->Get( KPhoneSpecificCacheDomainUrl, whiteList ) == KErrNone ) { iVSSWhiteList = HBufC8::NewL( whiteList.Length() ); iVSSWhiteList->Des().Append( whiteList ); @@ -778,8 +803,9 @@ } // create cache handler - iphoneSpecificCache = CHttpCacheHandler::NewL( VSScacheSize, VSScacheFolder, KDefaultVSSIndexFile(), criticalLevel ); + iphoneSpecificCache = CHttpCacheHandler::NewL( VSScacheSize, VSScacheFolder, KDefaultVSSIndexFile(), criticalLevel, postpone); } + CleanupStack::PopAndDestroy(2); // repository, , repositoryDiskLevel } @@ -804,4 +830,3 @@ return cache; } // End of File -