Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(539)

Side by Side Diff: net/disk_cache/eviction.cc

Issue 48112: Disk cache: First implementation of TrimDeleted() and a few... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: Created 11 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « net/disk_cache/eviction.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 // The eviction policy is a very simple pure LRU, so the elements at the end of 5 // The eviction policy is a very simple pure LRU, so the elements at the end of
6 // the list are evicted until kCleanUpMargin free space is available. There is 6 // the list are evicted until kCleanUpMargin free space is available. There is
7 // only one list in use (Rankings::NO_USE), and elements are sent to the front 7 // only one list in use (Rankings::NO_USE), and elements are sent to the front
8 // of the list whenever they are accessed. 8 // of the list whenever they are accessed.
9 9
10 // The new (in-development) eviction policy ads re-use as a factor to evict 10 // The new (in-development) eviction policy ads re-use as a factor to evict
(...skipping 191 matching lines...) Expand 10 before | Expand all | Expand 10 after
202 if (done) 202 if (done)
203 continue; 203 continue;
204 next[i].reset(rankings_->GetPrev(NULL, static_cast<Rankings::List>(i))); 204 next[i].reset(rankings_->GetPrev(NULL, static_cast<Rankings::List>(i)));
205 if (!empty && NodeIsOldEnough(next[i].get(), i)) { 205 if (!empty && NodeIsOldEnough(next[i].get(), i)) {
206 list = static_cast<Rankings::List>(i); 206 list = static_cast<Rankings::List>(i);
207 done = true; 207 done = true;
208 } 208 }
209 } 209 }
210 210
211 // If we are not meeting the time targets lets move on to list length. 211 // If we are not meeting the time targets lets move on to list length.
212 if (!empty && Rankings::LAST_ELEMENT == list) 212 if (!empty && Rankings::LAST_ELEMENT == list) {
213 list = SelectListByLenght(); 213 list = SelectListByLenght();
214 // Make sure that frequently used items are kept for a minimum time.
215 if (Rankings::HIGH_USE == list &&
216 !NodeIsOldEnough(next[Rankings::HIGH_USE].get(), 0))
Nicolas Sylvain 2009/03/18 17:17:35 the zero here, it should not be "list" ?
rvargas (doing something else) 2009/03/18 17:32:13 no 'cause NodeIsOldEnough(next[2], 2) was already
217 list = 0;
218 }
214 219
215 if (empty) 220 if (empty)
216 list = 0; 221 list = 0;
217 222
218 Rankings::ScopedRankingsBlock node(rankings_); 223 Rankings::ScopedRankingsBlock node(rankings_);
219 224
220 int target_size = empty ? 0 : max_size_; 225 int target_size = empty ? 0 : max_size_;
221 int deleted = 0; 226 int deleted = 0;
222 for (; list < kListsToSearch; list++) { 227 for (; list < kListsToSearch; list++) {
223 while (header_->num_bytes > target_size && next[list].get()) { 228 while (header_->num_bytes > target_size && next[list].get()) {
224 node.reset(next[list].release()); 229 node.reset(next[list].release());
225 next[list].reset(rankings_->GetPrev(node.get(), 230 next[list].reset(rankings_->GetPrev(node.get(),
226 static_cast<Rankings::List>(list))); 231 static_cast<Rankings::List>(list)));
227 if (!node->Data()->pointer || empty) { 232 if (!node->Data()->pointer || empty) {
228 // This entry is not being used by anybody. 233 // This entry is not being used by anybody.
229 if (!EvictEntry(node.get(), empty)) 234 if (!EvictEntry(node.get(), empty))
230 continue; 235 continue;
231 236
232 if (++deleted == 4 && !empty) { 237 if (++deleted == 4 && !empty) {
233 MessageLoop::current()->PostTask(FROM_HERE, 238 MessageLoop::current()->PostTask(FROM_HERE,
234 factory_.NewRunnableMethod(&Eviction::TrimCache, false)); 239 factory_.NewRunnableMethod(&Eviction::TrimCache, false));
235 break; 240 break;
236 } 241 }
237 } 242 }
238 } 243 }
239 if (!empty) 244 if (!empty)
240 list = kListsToSearch; 245 list = kListsToSearch;
241 } 246 }
242 247
243 if (empty || header_->lru.sizes[Rankings::DELETED] > header_->num_entries / 4) 248 if (empty) {
249 TrimDeleted(true);
250 } else if (header_->lru.sizes[Rankings::DELETED] > header_->num_entries / 4) {
244 MessageLoop::current()->PostTask(FROM_HERE, 251 MessageLoop::current()->PostTask(FROM_HERE,
245 factory_.NewRunnableMethod(&Eviction::TrimDeleted, empty)); 252 factory_.NewRunnableMethod(&Eviction::TrimDeleted, empty));
253 }
246 254
247 UMA_HISTOGRAM_TIMES("DiskCache.TotalTrimTime", Time::Now() - start); 255 UMA_HISTOGRAM_TIMES("DiskCache.TotalTrimTime", Time::Now() - start);
248 Trace("*** Trim Cache end ***"); 256 Trace("*** Trim Cache end ***");
249 return; 257 return;
250 } 258 }
251 259
252 void Eviction::UpdateRankV2(EntryImpl* entry, bool modified) { 260 void Eviction::UpdateRankV2(EntryImpl* entry, bool modified) {
253 rankings_->UpdateRank(entry->rankings(), modified, GetListForEntryV2(entry)); 261 rankings_->UpdateRank(entry->rankings(), modified, GetListForEntryV2(entry));
254 } 262 }
255 263
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
325 333
326 if (!info->reuse_count) 334 if (!info->reuse_count)
327 return Rankings::NO_USE; 335 return Rankings::NO_USE;
328 336
329 if (info->reuse_count < kHighUse) 337 if (info->reuse_count < kHighUse)
330 return Rankings::LOW_USE; 338 return Rankings::LOW_USE;
331 339
332 return Rankings::HIGH_USE; 340 return Rankings::HIGH_USE;
333 } 341 }
334 342
343 // This is a minimal implementation that just discards the oldest nodes.
344 // TODO(rvargas): Do something better here.
335 void Eviction::TrimDeleted(bool empty) { 345 void Eviction::TrimDeleted(bool empty) {
346 Trace("*** Trim Deleted ***");
347 if (backend_->disabled_)
348 return;
349
350 Time start = Time::Now();
351 Rankings::ScopedRankingsBlock node(rankings_);
352 Rankings::ScopedRankingsBlock next(rankings_,
353 rankings_->GetPrev(node.get(), Rankings::DELETED));
354 DCHECK(next.get());
355 for (int i = 0; (i < 4 || empty) && next.get(); i++) {
356 node.reset(next.release());
357 next.reset(rankings_->GetPrev(node.get(), Rankings::DELETED));
358 RemoveDeletedNode(node.get());
359 }
360
361 if (header_->lru.sizes[Rankings::DELETED] > header_->num_entries / 4)
362 MessageLoop::current()->PostTask(FROM_HERE,
363 factory_.NewRunnableMethod(&Eviction::TrimDeleted, false));
364
365 UMA_HISTOGRAM_TIMES("DiskCache.TotalTrimDeletedTime", Time::Now() - start);
366 Trace("*** Trim Deleted end ***");
367 return;
368 }
369
370 bool Eviction::RemoveDeletedNode(CacheRankingsBlock* node) {
371 EntryImpl* entry;
372 bool dirty;
373 if (backend_->NewEntry(Addr(node->Data()->contents), &entry, &dirty)) {
374 Trace("NewEntry failed on Trim 0x%x", node->address().value());
375 return false;
376 }
377
378 if (node->Data()->pointer) {
379 entry = EntryImpl::Update(entry);
380 }
381 entry->entry()->Data()->state = ENTRY_DOOMED;
382 entry->Doom();
383 entry->Release();
384 return true;
336 } 385 }
337 386
338 bool Eviction::NodeIsOldEnough(CacheRankingsBlock* node, int list) { 387 bool Eviction::NodeIsOldEnough(CacheRankingsBlock* node, int list) {
339 if (!node) 388 if (!node)
340 return false; 389 return false;
341 390
342 // If possible, we want to keep entries on each list at least kTargetTime 391 // If possible, we want to keep entries on each list at least kTargetTime
343 // hours. Each successive list on the enumeration has 2x the target time of 392 // hours. Each successive list on the enumeration has 2x the target time of
344 // the previous list. 393 // the previous list.
345 Time used = Time::FromInternalValue(node->Data()->last_used); 394 Time used = Time::FromInternalValue(node->Data()->last_used);
346 int multiplier = 1 << list; 395 int multiplier = 1 << list;
347 return (Time::Now() - used).InHours() > kTargetTime * multiplier; 396 return (Time::Now() - used).InHours() > kTargetTime * multiplier;
348 } 397 }
349 398
350 int Eviction::SelectListByLenght() { 399 int Eviction::SelectListByLenght() {
400 int data_entries = header_->num_entries -
401 header_->lru.sizes[Rankings::DELETED];
351 // Start by having each list to be roughly the same size. 402 // Start by having each list to be roughly the same size.
352 if (header_->lru.sizes[0] > header_->num_entries / 4) 403 if (header_->lru.sizes[0] > data_entries / 3)
353 return 0; 404 return 0;
354 if (header_->lru.sizes[1] > header_->num_entries / 4) 405 if (header_->lru.sizes[1] > data_entries / 3)
355 return 1; 406 return 1;
356 return 2; 407 return 2;
357 } 408 }
358 409
359 } // namespace disk_cache 410 } // namespace disk_cache
OLDNEW
« no previous file with comments | « net/disk_cache/eviction.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698