webengine/osswebengine/cache/src/HttpCacheEvictionHandler.cpp
changeset 1 7c90e6132015
parent 0 dd21522fd290
child 10 a359256acfc6
equal deleted inserted replaced
0:dd21522fd290 1:7c90e6132015
   122 // -----------------------------------------------------------------------------
   122 // -----------------------------------------------------------------------------
   123 // CHttpCacheEvictionHandler::InsertL
   123 // CHttpCacheEvictionHandler::InsertL
   124 //
   124 //
   125 // -----------------------------------------------------------------------------
   125 // -----------------------------------------------------------------------------
   126 //
   126 //
   127 void CHttpCacheEvictionHandler::Insert(
   127 void CHttpCacheEvictionHandler::Insert( CHttpCacheEntry& aCacheEntry )
   128     CHttpCacheEntry& aCacheEntry )
       
   129     {
   128     {
   130 #ifdef __CACHELOG__
   129 #ifdef __CACHELOG__
   131     HttpCacheUtil::WriteUrlToLog( 0, _L( "Eviction table: item is inserted:" ), aCacheEntry.Url() );
   130     HttpCacheUtil::WriteUrlToLog( 0, _L( "Eviction table: item is inserted:" ), aCacheEntry.Url() );
   132     // check double insert
   131     // check double insert
   133     CHttpCacheEntry* entry;
   132     CHttpCacheEntry* entry;
   134     for( TInt i = 0; i < KHttpCacheBucketNum; i++ )
   133     for ( TInt i = 0; i < KHttpCacheBucketNum; i++ )
   135         {
   134         {
   136         TBucketIter bucketIter( *iBuckets->At( i ) );
   135         TBucketIter bucketIter( *iBuckets->At( i ) );
   137         //
   136         //
   138         bucketIter.SetToFirst();
   137         bucketIter.SetToFirst();
   139         while( ( entry = bucketIter++ ) != NULL )
   138         while ( ( entry = bucketIter++ ) != NULL )
   140             {
   139             {
   141             __ASSERT_DEBUG( ( entry != &aCacheEntry ) , User::Panic( _L("cacheHandler Panic"), KErrCorrupt ) );
   140             __ASSERT_DEBUG( ( entry != &aCacheEntry ) , User::Panic( _L("cacheHandler Panic"), KErrCorrupt ) );
   142             }
   141             }
   143         }
   142         }
   144     //
   143 
   145     HttpCacheUtil::WriteLog( 0, _L( "insert entry to eviction table:" ), BucketIndex( FastLog2( aCacheEntry.Size() ) ) );
   144     HttpCacheUtil::WriteLog( 0, _L( "insert entry to eviction table:" ), BucketIndex( FastLog2( aCacheEntry.BodySize() ) ) );
   146 #endif // __CACHELOG__
   145 #endif // __CACHELOG__
       
   146 
   147     // Objects are classified into a limited number of groups according to log2(Si/refi)
   147     // Objects are classified into a limited number of groups according to log2(Si/refi)
   148     // caclulate to which bucket it goes.
   148     // calculate to which bucket it goes. Buckets are orderd by LRU
   149     // buckets are orderd by LRU
   149     Bucket( BucketIndex( FastLog2( aCacheEntry.BodySize() / aCacheEntry.Ref() ) ) )->AddLast( aCacheEntry );
   150     Bucket( BucketIndex( FastLog2( aCacheEntry.Size() / aCacheEntry.Ref() ) ) )->AddLast( aCacheEntry );
       
   151     }
   150     }
   152 
   151 
   153 // -----------------------------------------------------------------------------
   152 // -----------------------------------------------------------------------------
   154 // CHttpCacheEvictionHandler::Accessed
   153 // CHttpCacheEvictionHandler::Accessed
   155 //
   154 //
   156 // -----------------------------------------------------------------------------
   155 // -----------------------------------------------------------------------------
   157 //
   156 //
   158 void CHttpCacheEvictionHandler::Accessed(
   157 void CHttpCacheEvictionHandler::Accessed( CHttpCacheEntry& aCacheEntry )
   159     CHttpCacheEntry& aCacheEntry )
   158     {
   160     {
   159     HttpCacheUtil::WriteUrlToLog( 0, _L( "CHttpCacheEvictionHandler::Accessed - Eviction table: item is accessed:" ), aCacheEntry.Url() );
   161     HttpCacheUtil::WriteUrlToLog( 0, _L( "Eviction table: item is accessed:" ), aCacheEntry.Url() );
       
   162     // first check where it is now
   160     // first check where it is now
   163     TInt oldRef( aCacheEntry.Ref() - 1 );
   161     TInt oldRef( aCacheEntry.Ref() - 1 );
   164     if( oldRef > 0 )
   162     if( oldRef > 0 )
   165         {
   163         {
   166         //
   164         //
   167         // buckets are orderd by LRU
   165         // buckets are orderd by LRU
   168         // see if we need to move it to a new bucket
   166         // see if we need to move it to a new bucket
   169         TInt currentBucketIndex( BucketIndex( FastLog2( aCacheEntry.Size() / oldRef ) ) );
   167         TInt currentBucketIndex( BucketIndex( FastLog2( aCacheEntry.BodySize() / oldRef ) ) );
   170         TInt newBucketIndex( BucketIndex( FastLog2( aCacheEntry.Size() / aCacheEntry.Ref() ) ) );
   168         TInt newBucketIndex( BucketIndex( FastLog2( aCacheEntry.BodySize() / aCacheEntry.Ref() ) ) );
   171         // check if the item is really there
   169         // check if the item is really there
   172         TBool itemOk( ItemIsInBucket( currentBucketIndex, aCacheEntry ) );
   170         TBool itemOk( ItemIsInBucket( currentBucketIndex, aCacheEntry ) );
   173 
   171 
   174         if( itemOk )
   172         if ( itemOk )
   175             {
   173             {
   176             HttpCacheUtil::WriteLog( 0, _L( "item is in bucket:" ), currentBucketIndex );
   174             if ( currentBucketIndex == newBucketIndex )
   177             if( currentBucketIndex == newBucketIndex )
       
   178                 {
   175                 {
   179                 HttpCacheUtil::WriteLog( 0, _L( "move entry to the end of the bucket. it's safe there" ) );
   176 #ifdef __CACHELOG__
       
   177                 HttpCacheUtil::WriteLogFilenameAndUrl( 0,
       
   178                                                _L("CHttpCacheEvictionHandler::Accessed - MOVED item to end of bucket"),
       
   179                                                aCacheEntry.Filename(),
       
   180                                                aCacheEntry.Url(),
       
   181                                                newBucketIndex,
       
   182                                                ELogBucketIndex );
       
   183 #endif
   180                 TBucket* bucket( Bucket( currentBucketIndex ) );
   184                 TBucket* bucket( Bucket( currentBucketIndex ) );
   181                 // move it to the end
   185                 // move it to the end
   182                 if( !bucket->IsLast( &aCacheEntry ) )
   186                 if ( !bucket->IsLast( &aCacheEntry ) )
   183                     {
   187                     {
   184                     bucket->Remove( aCacheEntry );
   188                     bucket->Remove( aCacheEntry );
   185                     bucket->AddLast( aCacheEntry );
   189                     bucket->AddLast( aCacheEntry );
   186                     }
   190                     }
   187                 }
   191                 }
   188             else
   192             else
   189                 {
   193                 {
   190                 HttpCacheUtil::WriteLog( 0, _L( "move item to a new bucket" ), newBucketIndex );
   194 #ifdef __CACHELOG__
       
   195                 HttpCacheUtil::WriteLogFilenameAndUrl( 0,
       
   196                                                _L("CHttpCacheEvictionHandler::Accessed - MOVED item to new bucket"),
       
   197                                                aCacheEntry.Filename(),
       
   198                                                aCacheEntry.Url(),
       
   199                                                newBucketIndex,
       
   200                                                ELogBucketIndex );
       
   201 #endif
   191                 // new bucket
   202                 // new bucket
   192                 TBucket* currBucket( Bucket( currentBucketIndex ) );
   203                 TBucket* currBucket( Bucket( currentBucketIndex ) );
   193                 TBucket* newBucket( Bucket( newBucketIndex ) );
   204                 TBucket* newBucket( Bucket( newBucketIndex ) );
   194                 // remove from the current and add it to the
   205                 // remove from the current and add it to the
   195                 // new as last item
   206                 // new as last item
   196 
   207 
   197                 // make sure the item is there
   208                 // make sure the item is there, move it to the end
   198                 // move it to the end
       
   199                 currBucket->Remove( aCacheEntry );
   209                 currBucket->Remove( aCacheEntry );
   200                 newBucket->AddLast( aCacheEntry );
   210                 newBucket->AddLast( aCacheEntry );
   201                 }
   211                 }
   202             }
   212             }
   203         else
   213         else
   217         __ASSERT_DEBUG( EFalse , User::Panic( _L("cacheHandler Panic"), KErrCorrupt ) );
   227         __ASSERT_DEBUG( EFalse , User::Panic( _L("cacheHandler Panic"), KErrCorrupt ) );
   218         }
   228         }
   219     }
   229     }
   220 
   230 
   221 // -----------------------------------------------------------------------------
   231 // -----------------------------------------------------------------------------
   222 // CHttpCacheEvictionHandler::Changed
       
   223 //
       
   224 // -----------------------------------------------------------------------------
       
   225 //
       
   226 void CHttpCacheEvictionHandler::Changed(
       
   227     CHttpCacheEntry& /*aCacheEntry*/ )
       
   228     {
       
   229     // check if size changed
       
   230     }
       
   231 
       
   232 // -----------------------------------------------------------------------------
       
   233 // CHttpCacheEvictionHandler::Remove
   232 // CHttpCacheEvictionHandler::Remove
   234 //
   233 //
   235 // -----------------------------------------------------------------------------
   234 // -----------------------------------------------------------------------------
   236 //
   235 //
   237 void CHttpCacheEvictionHandler::Remove(
   236 void CHttpCacheEvictionHandler::Remove( CHttpCacheEntry& aCacheEntry )
   238     CHttpCacheEntry& aCacheEntry )
   237     {
   239     {
   238 #ifdef __CACHELOG__
   240     HttpCacheUtil::WriteUrlToLog( 0, _L( "Eviction table: try to remove item:" ), aCacheEntry.Url() );
   239     HttpCacheUtil::WriteLogFilenameAndUrl( 0,
   241     //
   240                                            _L("CHttpCacheEvictionHandler::Remove - trying to removing entry"),
   242     TInt sizeFreqVal( FastLog2( aCacheEntry.Size() / aCacheEntry.Ref() ) );
   241                                            aCacheEntry.Filename(),
       
   242                                            aCacheEntry.Url(),
       
   243                                            aCacheEntry.BodySize(),
       
   244                                            ELogEntrySize );
       
   245 #endif
       
   246 
       
   247     TInt sizeFreqVal( FastLog2( aCacheEntry.BodySize() / aCacheEntry.Ref() ) );
   243     // check if the item is in the right bucket
   248     // check if the item is in the right bucket
   244     TInt bucketIndex( BucketIndex( sizeFreqVal ) );
   249     TInt bucketIndex( BucketIndex( sizeFreqVal ) );
   245     TBucket* bucket( Bucket( bucketIndex ) );
   250     TBucket* bucket( Bucket( bucketIndex ) );
   246     TBool itemOk( ItemIsInBucket( bucketIndex, aCacheEntry ) );
   251     TBool itemOk( ItemIsInBucket( bucketIndex, aCacheEntry ) );
   247 
   252 
   248     if( itemOk )
   253     if ( itemOk )
   249         {
   254         {
   250         //
   255 #ifdef __CACHELOG__
   251         HttpCacheUtil::WriteLog( 0, _L( "removed from bucket:" ), bucketIndex );
   256         HttpCacheUtil::WriteLogFilenameAndUrl( 0,
       
   257                                            _L("CHttpCacheEvictionHandler::Remove - removing entry from"),
       
   258                                            aCacheEntry.Filename(),
       
   259                                            aCacheEntry.Url(),
       
   260                                            bucketIndex,
       
   261                                            ELogBucketIndex );
       
   262 #endif
   252         bucket->Remove( aCacheEntry );
   263         bucket->Remove( aCacheEntry );
   253         }
   264         }
   254 #ifdef __CACHELOG__
   265 #ifdef __CACHELOG__
   255     else
   266     else
   256         {
   267         {
   257          HttpCacheUtil::WriteLog( 0, _L( "item is not in bucket no." ), bucketIndex );
   268          HttpCacheUtil::WriteLogFilenameAndUrl( 0,
       
   269                                            _L("CHttpCacheEvictionHandler::Remove - item NOT in"),
       
   270                                            aCacheEntry.Filename(),
       
   271                                            aCacheEntry.Url(),
       
   272                                            bucketIndex,
       
   273                                            ELogBucketIndex );
   258         }
   274         }
   259 #endif // __CACHELOG__
   275 #endif // __CACHELOG__
   260     }
   276     }
   261 
   277 
   262 // -----------------------------------------------------------------------------
   278 // -----------------------------------------------------------------------------
   263 // CHttpCacheEvictionHandler::Evict
   279 // CHttpCacheEvictionHandler::EvictL
   264 //
   280 //
   265 // -----------------------------------------------------------------------------
   281 // -----------------------------------------------------------------------------
   266 //
   282 //
   267 CArrayPtrFlat<CHttpCacheEntry>* CHttpCacheEvictionHandler::EvictL(
   283 CArrayPtrFlat<CHttpCacheEntry>* CHttpCacheEvictionHandler::EvictL(
   268     TInt aSpaceNeeded )
   284     TInt aSpaceNeeded )
   269     {
   285     {
   270     HttpCacheUtil::WriteLog( 0, _L( "need space:" ), aSpaceNeeded );
   286 #ifdef __CACHELOG__
   271 #ifdef __CACHELOG__
   287     HttpCacheUtil::WriteLog( 0, _L( "CHttpCacheEvictionHandler::EvictL - aSpaceNeeded = " ), aSpaceNeeded );
   272     LogBuckets();
   288     LogBuckets();
   273 #endif // __CACHELOG__
   289 #endif // __CACHELOG__
   274     //
   290 
   275     CArrayPtrFlat<CHttpCacheEntry>* evictedEntries = new(ELeave)CArrayPtrFlat<CHttpCacheEntry>( 10 );
   291     CArrayPtrFlat<CHttpCacheEntry>* evictedEntries = new(ELeave)CArrayPtrFlat<CHttpCacheEntry>( 10 );
   276     CleanupStack::PushL( evictedEntries );
   292     CleanupStack::PushL( evictedEntries );
   277     //
   293 
   278     // Each group is managed using a LRU
   294     // Each group is managed using a LRU
   279     // policy. The extended cost-to-size model is applied to the
   295     // policy. The extended cost-to-size model is applied to the
   280     // eviction candidates from all nonempty groups, purging the
   296     // eviction candidates from all nonempty groups, purging the
   281     // object with largest ( DeltaT * Size / Ref ) ->delataT == curr time - last accessed
   297     // object with largest ( DeltaT * Size / Ref ) ->delataT == curr time - last accessed
   282     TTime currTime;
   298     TTime currTime;
   297             // get the first (LRU) item from each bucket
   313             // get the first (LRU) item from each bucket
   298             if( !bucket->IsEmpty() )
   314             if( !bucket->IsEmpty() )
   299                 {
   315                 {
   300                 entry = bucket->First();
   316                 entry = bucket->First();
   301                 }
   317                 }
       
   318 #ifdef __CACHELOG__
       
   319             else {
       
   320                 HttpCacheUtil::WriteLog( 0, _L("CHttpCacheEvictionHandler::EvictL : NO entries found in bucket ="), i);
       
   321             }
       
   322 #endif
   302             // evacuate nonactive entries only
   323             // evacuate nonactive entries only
   303             if( entry && entry->State() == CHttpCacheEntry::ECacheComplete )
   324             if( entry && entry->State() == CHttpCacheEntry::ECacheComplete )
   304                 {
   325                 {
   305                 // watch out for 32 bit. it might overflow secInt.
   326                 // watch out for 32 bit. it might overflow secInt.
   306                 currTime.SecondsFrom( entry->LastAccessed(), secInt );
   327                 currTime.SecondsFrom( entry->LastAccessed(), secInt );
   307 
   328 
   308                 TInt val( secInt.Int() * entry->Size() / entry->Ref() );
   329                 TInt val( secInt.Int() * entry->BodySize() / entry->Ref() );
   309                 // get the object with largest ( DeltaT * Size / Ref )
   330                 // get the object with largest ( DeltaT * Size / Ref )
   310                 if( val > maxVal )
   331                 if( val > maxVal )
   311                     {
   332                     {
   312                     maxVal = val;
   333                     maxVal = val;
   313                     bucketInd = i;
   334                     bucketInd = i;
   314                     candidate = entry;
   335                     candidate = entry;
   315                     }
   336                     }
   316                 }
   337                 }
   317             }
   338             }
   318         // remove from the bucket
   339 
   319         // add it to the evicted list
   340         // remove from the bucket, add it to the evicted list, 
   320         // reduce space needed size
   341         // reduce space needed size
   321         if( candidate )
   342         if ( candidate )
   322             {
   343             {
   323 #ifdef __CACHELOG__
   344 #ifdef __CACHELOG__
   324             // no protected entries should be evacuated
   345             // no protected entries should be evacuated
   325             if( candidate->Protected() )
   346             if( candidate->Protected() )
   326             	{
   347             	{
   327 	            HttpCacheUtil::WriteUrlToLog( 0, _L( "PROTECTED entry is about to be removed" ), candidate->Url() );
   348 	            HttpCacheUtil::WriteUrlToLog( 0, _L( "CHttpCacheEvictionHandler::EvictL - PROTECTED entry is about to be removed" ), candidate->Url() );
   328             	}
   349             	}
   329             //
   350 
   330             HttpCacheUtil::WriteUrlToLog( 0, _L( "entry to remove:" ), candidate->Url() );
   351             HttpCacheUtil::WriteLogFilenameAndUrl( 0,
       
   352                                            _L("CHttpCacheEvictionHandler::EvictL - removing entry "),
       
   353                                            candidate->Filename(),
       
   354                                            candidate->Url(),
       
   355                                            candidate->BodySize(), 
       
   356                                            ELogEntrySize );
   331 #endif //__CACHELOG__
   357 #endif //__CACHELOG__
   332             //
   358             
   333             iBuckets->At( bucketInd )->Remove( *candidate );
   359             iBuckets->At( bucketInd )->Remove( *candidate );
   334             // reduce size
   360             // Reduce size needed
   335             aSpaceNeeded-= candidate->Size();
   361             aSpaceNeeded -= candidate->BodySize();
   336             aSpaceNeeded-= candidate->HeaderSize();
   362             aSpaceNeeded -= candidate->HeaderSize();
   337             //
   363 
   338             evictedEntries->AppendL( candidate );
   364             evictedEntries->AppendL( candidate );
   339             //
   365 
   340             HttpCacheUtil::WriteLog( 0, _L( "more space needed" ), aSpaceNeeded );
   366 #ifdef __CACHELOG__
       
   367             if ( aSpaceNeeded > 0 ) {
       
   368                 HttpCacheUtil::WriteLog( 0, _L( "CHttpCacheEvictionHandler::EvictL - more space needed aSpaceNeeded = " ), aSpaceNeeded );
       
   369             	}
       
   370 #endif
   341             }
   371             }
   342         else
   372         else
   343             {
   373             {
   344             // no candidate no free
   374             // no candidate no free
       
   375 #ifdef __CACHELOG__
       
   376             HttpCacheUtil::WriteLog( 0, _L( "CHttpCacheEvictionHandler::EvictL - NO Candidates to remove" ) );
       
   377 #endif
   345             break;
   378             break;
   346             }
   379             }
   347         }
   380         }   // end if while
       
   381 
   348     CleanupStack::Pop(); // evictedEntries
   382     CleanupStack::Pop(); // evictedEntries
       
   383 
   349     return evictedEntries;
   384     return evictedEntries;
   350     }
   385     }
   351 
   386 
   352 // -----------------------------------------------------------------------------
   387 // -----------------------------------------------------------------------------
   353 // CHttpCacheEvictionHandler::RemoveAll
   388 // CHttpCacheEvictionHandler::RemoveAll
   354 //
   389 //
   355 // -----------------------------------------------------------------------------
   390 // -----------------------------------------------------------------------------
   356 //
   391 //
   357 void CHttpCacheEvictionHandler::RemoveAll()
   392 void CHttpCacheEvictionHandler::RemoveAll()
   358     {
   393     {
       
   394 #ifdef __CACHELOG__
   359     HttpCacheUtil::WriteLog( 0, _L( "Eviction table: remove all item:" ) );
   395     HttpCacheUtil::WriteLog( 0, _L( "Eviction table: remove all item:" ) );
   360     //
   396 #endif
   361     for( TInt i = 0; i < KHttpCacheBucketNum; i++ )
   397 
       
   398     for ( TInt i = 0; i < KHttpCacheBucketNum; i++ )
   362         {
   399         {
   363         iBuckets->At( i )->Reset();
   400         iBuckets->At( i )->Reset();
   364         //
   401         //
   365         }
   402         }
   366     }
   403     }
   426         if( entry == &aCacheEntry )
   463         if( entry == &aCacheEntry )
   427             {
   464             {
   428             found = ETrue;
   465             found = ETrue;
   429             break;
   466             break;
   430             }
   467             }
   431         }
   468         }   // end of while
       
   469 
   432 #ifdef __CACHELOG__
   470 #ifdef __CACHELOG__
   433     if( !found )
   471     if( !found )
   434         {
   472         {
   435         HttpCacheUtil::WriteLog( 0, _L( "Eviction table: item NOT FOUND" ) );
   473         HttpCacheUtil::WriteLogFilenameAndUrl( 0,
       
   474                                            _L("CHttpCacheEvictionHandler::ItemIsInBucket - entry NOT found"),
       
   475                                            aCacheEntry.Filename(),
       
   476                                            aCacheEntry.Url(),
       
   477                                            aCacheEntry.BodySize(), 
       
   478                                            ELogEntrySize );
   436         }
   479         }
   437 #endif // __CACHELOG__
   480 #endif // __CACHELOG__
       
   481 
   438     return found;
   482     return found;
   439     }
   483     }
   440 
   484 
   441 // -----------------------------------------------------------------------------
   485 // -----------------------------------------------------------------------------
   442 // CHttpCacheEvictionHandler::FastLog2
   486 // CHttpCacheEvictionHandler::FastLog2
   468         //
   512         //
   469         bucketIter.SetToFirst();
   513         bucketIter.SetToFirst();
   470         while( ( entry = bucketIter++ ) != NULL )
   514         while( ( entry = bucketIter++ ) != NULL )
   471             {
   515             {
   472             _LIT( KDateString,"%D%M%Y%/0%1%/1%2%/2%3%/3 %-B%:0%J%:1%T%:2%S%.%*C4%:3%+B");
   516             _LIT( KDateString,"%D%M%Y%/0%1%/1%2%/2%3%/3 %-B%:0%J%:1%T%:2%S%.%*C4%:3%+B");
   473             _LIT( KRefSizeString,"size: %d refcount:%d");
   517             _LIT( KRefSizeString,"CHttpCacheEvictionHandler::LogBuckets - size: %d refcount:%d");
   474 
   518 
   475             TBuf<50> refStr;
   519             TBuf<50> refStr;
   476             TBuf<50> lastAccessedStr;
   520             TBuf<50> lastAccessedStr;
   477 
   521 
   478             TTime lastAccessed( entry->LastAccessed() );
   522             TTime lastAccessed( entry->LastAccessed() );
   479             lastAccessed.FormatL( lastAccessedStr, KDateString );
   523             TRAP_IGNORE( lastAccessed.FormatL( lastAccessedStr, KDateString ) );
   480             // add size/refcount
   524             // add size/refcount
   481             refStr.Format( KRefSizeString, entry->Size(), entry->Ref() );
   525             refStr.Format( KRefSizeString, entry->BodySize(), entry->Ref() );
   482             // copy to 8bit string
   526             // copy to 8bit string
   483             HttpCacheUtil::WriteUrlToLog( 0, refStr, entry->Url() );
       
   484             HttpCacheUtil::WriteLog( 0, lastAccessedStr );
   527             HttpCacheUtil::WriteLog( 0, lastAccessedStr );
       
   528             HttpCacheUtil::WriteLogFilenameAndUrl( 0,
       
   529                                                _L("CHttpCacheEvictionHandler::LogBuckets - "),
       
   530                                                entry->Filename(),
       
   531                                                entry->Url(),
       
   532                                                i, 
       
   533                                                ELogBucketIndex );
   485             }
   534             }
   486         }
   535         }
   487     }
   536     }
   488 #endif // __CACHELOG__
   537 #endif // __CACHELOG__
   489 
   538