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 } |
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 |