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

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

Issue 2881010: Revert 51456 - Disk cache: Switch the disk cache to use the cache_thread.... (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Created 10 years, 5 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/backend_impl.h ('k') | net/disk_cache/backend_unittest.cc » ('j') | 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-2010 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2006-2010 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 #include "net/disk_cache/backend_impl.h" 5 #include "net/disk_cache/backend_impl.h"
6 6
7 #include "base/field_trial.h" 7 #include "base/field_trial.h"
8 #include "base/file_path.h" 8 #include "base/file_path.h"
9 #include "base/file_util.h" 9 #include "base/file_util.h"
10 #include "base/histogram.h" 10 #include "base/histogram.h"
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after
155 if (!first) 155 if (!first)
156 return; 156 return;
157 157
158 // Field trials involve static objects so we have to do this only once. 158 // Field trials involve static objects so we have to do this only once.
159 first = false; 159 first = false;
160 scoped_refptr<FieldTrial> trial1 = new FieldTrial("CacheSize", 10); 160 scoped_refptr<FieldTrial> trial1 = new FieldTrial("CacheSize", 10);
161 std::string group1 = StringPrintf("CacheSizeGroup_%d", size_group); 161 std::string group1 = StringPrintf("CacheSizeGroup_%d", size_group);
162 trial1->AppendGroup(group1, FieldTrial::kAllRemainingProbability); 162 trial1->AppendGroup(group1, FieldTrial::kAllRemainingProbability);
163 } 163 }
164 164
165 // ------------------------------------------------------------------------
166
167 // This class takes care of building an instance of the backend.
168 class CacheCreator {
169 public:
170 CacheCreator(const FilePath& path, bool force, int max_bytes,
171 net::CacheType type, uint32 flags,
172 base::MessageLoopProxy* thread, disk_cache::Backend** backend,
173 net::CompletionCallback* callback)
174 : path_(path), force_(force), retry_(false), max_bytes_(max_bytes),
175 type_(type), flags_(flags), thread_(thread), backend_(backend),
176 callback_(callback), cache_(NULL),
177 ALLOW_THIS_IN_INITIALIZER_LIST(
178 my_callback_(this, &CacheCreator::OnIOComplete)) {
179 }
180 ~CacheCreator() {}
181
182 // Creates the backend.
183 int Run();
184
185 // Callback implementation.
186 void OnIOComplete(int result);
187
188 private:
189 void DoCallback(int result);
190
191 const FilePath& path_;
192 bool force_;
193 bool retry_;
194 int max_bytes_;
195 net::CacheType type_;
196 uint32 flags_;
197 scoped_refptr<base::MessageLoopProxy> thread_;
198 disk_cache::Backend** backend_;
199 net::CompletionCallback* callback_;
200 disk_cache::BackendImpl* cache_;
201 net::CompletionCallbackImpl<CacheCreator> my_callback_;
202
203 DISALLOW_COPY_AND_ASSIGN(CacheCreator);
204 };
205
206 int CacheCreator::Run() {
207 cache_ = new disk_cache::BackendImpl(path_, thread_);
208 cache_->SetMaxSize(max_bytes_);
209 cache_->SetType(type_);
210 cache_->SetFlags(flags_);
211 int rv = cache_->Init(&my_callback_);
212 DCHECK_EQ(net::ERR_IO_PENDING, rv);
213 return rv;
214 }
215
216 void CacheCreator::OnIOComplete(int result) {
217 if (result == net::OK || !force_ || retry_)
218 return DoCallback(result);
219
220 // This is a failure and we are supposed to try again, so delete the object,
221 // delete all the files, and try again.
222 retry_ = true;
223 delete cache_;
224 if (!DelayedCacheCleanup(path_))
225 return DoCallback(result);
226
227 // The worker thread will start deleting files soon, but the original folder
228 // is not there anymore... let's create a new set of files.
229 int rv = Run();
230 DCHECK_EQ(net::ERR_IO_PENDING, rv);
231 }
232
233 void CacheCreator::DoCallback(int result) {
234 DCHECK_NE(net::ERR_IO_PENDING, result);
235 if (result == net::OK) {
236 *backend_ = cache_;
237 } else {
238 LOG(ERROR) << "Unable to create cache";
239 *backend_ = NULL;
240 delete cache_;
241 }
242 callback_->Run(result);
243 delete this;
244 }
245
246 // ------------------------------------------------------------------------
247
248 // A task to perform final cleanup on the background thread.
249 class FinalCleanup : public Task {
250 public:
251 explicit FinalCleanup(disk_cache::BackendImpl* backend) : backend_(backend) {}
252 ~FinalCleanup() {}
253
254 virtual void Run();
255 private:
256 disk_cache::BackendImpl* backend_;
257 DISALLOW_EVIL_CONSTRUCTORS(FinalCleanup);
258 };
259
260 void FinalCleanup::Run() {
261 backend_->CleanupCache();
262 }
263
264 } // namespace 165 } // namespace
265 166
266 // ------------------------------------------------------------------------ 167 // ------------------------------------------------------------------------
267 168
268 namespace disk_cache { 169 namespace disk_cache {
269 170
270 int CreateCacheBackend(net::CacheType type, const FilePath& path, int max_bytes, 171 int CreateCacheBackend(net::CacheType type, const FilePath& path, int max_bytes,
271 bool force, base::MessageLoopProxy* thread, 172 bool force, base::MessageLoopProxy* thread,
272 Backend** backend, CompletionCallback* callback) { 173 Backend** backend, CompletionCallback* callback) {
273 DCHECK(callback); 174 DCHECK(callback);
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
320 // still fail if we are not able to rename the cache folder (for instance due to 221 // still fail if we are not able to rename the cache folder (for instance due to
321 // a sharing violation), and in that case a cache for this profile (on the 222 // a sharing violation), and in that case a cache for this profile (on the
322 // desired path) cannot be created. 223 // desired path) cannot be created.
323 // 224 //
324 // Static. 225 // Static.
325 int BackendImpl::CreateBackend(const FilePath& full_path, bool force, 226 int BackendImpl::CreateBackend(const FilePath& full_path, bool force,
326 int max_bytes, net::CacheType type, 227 int max_bytes, net::CacheType type,
327 uint32 flags, base::MessageLoopProxy* thread, 228 uint32 flags, base::MessageLoopProxy* thread,
328 Backend** backend, 229 Backend** backend,
329 CompletionCallback* callback) { 230 CompletionCallback* callback) {
330 CacheCreator* creator = new CacheCreator(full_path, force, max_bytes, type, 231 BackendImpl* cache = new BackendImpl(full_path, thread);
331 flags, thread, backend, callback); 232 cache->SetMaxSize(max_bytes);
332 // This object will self-destroy when finished. 233 cache->SetType(type);
333 return creator->Run(); 234 cache->SetFlags(flags);
334 } 235 if (cache->Init()) {
236 *backend = cache;
237 return net::OK;
238 }
335 239
336 int BackendImpl::SyncInit() { 240 *backend = NULL;
337 if (Init()) 241 delete cache;
242 if (!force)
243 return net::ERR_FAILED;
244
245 if (!DelayedCacheCleanup(full_path))
246 return net::ERR_FAILED;
247
248 // The worker thread will start deleting files soon, but the original folder
249 // is not there anymore... let's create a new set of files.
250 cache = new BackendImpl(full_path, thread);
251 cache->SetMaxSize(max_bytes);
252 cache->SetType(type);
253 cache->SetFlags(flags);
254 if (cache->Init()) {
255 *backend = cache;
338 return net::OK; 256 return net::OK;
257 }
339 258
259 delete cache;
260 LOG(ERROR) << "Unable to create cache";
340 return net::ERR_FAILED; 261 return net::ERR_FAILED;
341 } 262 }
342 263
343 bool BackendImpl::Init() { 264 bool BackendImpl::Init() {
344 DCHECK(!init_); 265 DCHECK(!init_);
345 if (init_) 266 if (init_)
346 return false; 267 return false;
347 268
348 bool create_files = false; 269 bool create_files = false;
349 if (!InitBackingStore(&create_files)) { 270 if (!InitBackingStore(&create_files)) {
(...skipping 26 matching lines...) Expand all
376 new_eviction_ = (cache_type_ == net::DISK_CACHE); 297 new_eviction_ = (cache_type_ == net::DISK_CACHE);
377 } 298 }
378 299
379 if (!CheckIndex()) { 300 if (!CheckIndex()) {
380 ReportError(ERR_INIT_FAILED); 301 ReportError(ERR_INIT_FAILED);
381 return false; 302 return false;
382 } 303 }
383 304
384 // We don't care if the value overflows. The only thing we care about is that 305 // We don't care if the value overflows. The only thing we care about is that
385 // the id cannot be zero, because that value is used as "not dirty". 306 // the id cannot be zero, because that value is used as "not dirty".
386 // Increasing the value once per second gives us many years before we start 307 // Increasing the value once per second gives us many years before a we start
387 // having collisions. 308 // having collisions.
388 data_->header.this_id++; 309 data_->header.this_id++;
389 if (!data_->header.this_id) 310 if (!data_->header.this_id)
390 data_->header.this_id++; 311 data_->header.this_id++;
391 312
392 if (data_->header.crash) { 313 if (data_->header.crash) {
393 ReportError(ERR_PREVIOUS_CRASH); 314 ReportError(ERR_PREVIOUS_CRASH);
394 } else { 315 } else {
395 ReportError(0); 316 ReportError(0);
396 data_->header.crash = 1; 317 data_->header.crash = 1;
(...skipping 10 matching lines...) Expand all
407 disabled_ = !rankings_.Init(this, new_eviction_); 328 disabled_ = !rankings_.Init(this, new_eviction_);
408 eviction_.Init(this); 329 eviction_.Init(this);
409 330
410 // Setup load-time data only for the main cache. 331 // Setup load-time data only for the main cache.
411 if (cache_type() == net::DISK_CACHE) 332 if (cache_type() == net::DISK_CACHE)
412 SetFieldTrialInfo(GetSizeGroup()); 333 SetFieldTrialInfo(GetSizeGroup());
413 334
414 return !disabled_; 335 return !disabled_;
415 } 336 }
416 337
417 int BackendImpl::Init(CompletionCallback* callback) {
418 background_queue_.Init(callback);
419 return net::ERR_IO_PENDING;
420 }
421
422 BackendImpl::~BackendImpl() { 338 BackendImpl::~BackendImpl() {
339 Trace("Backend destructor");
423 if (!init_) 340 if (!init_)
424 return; 341 return;
425 342
426 if (data_) 343 if (data_)
427 data_->header.crash = 0; 344 data_->header.crash = 0;
428 345
429 background_queue_.WaitForPendingIO(); 346 timer_.Stop();
430 347
431 if (background_queue_.BackgroundIsCurrentThread()) {
432 // Unit tests may use the same thread for everything.
433 CleanupCache();
434 } else {
435 background_queue_.background_thread()->PostTask(FROM_HERE,
436 new FinalCleanup(this));
437 done_.Wait();
438 }
439 }
440
441 void BackendImpl::CleanupCache() {
442 Trace("Backend Cleanup");
443 timer_.Stop();
444 File::WaitForPendingIO(&num_pending_io_); 348 File::WaitForPendingIO(&num_pending_io_);
445 DCHECK(!num_refs_); 349 DCHECK(!num_refs_);
446 factory_.RevokeAll();
447 done_.Signal();
448 } 350 }
449 351
450 // ------------------------------------------------------------------------ 352 // ------------------------------------------------------------------------
451 353
452 int32 BackendImpl::GetEntryCount() const { 354 int32 BackendImpl::GetEntryCount() const {
453 if (!index_) 355 if (!index_)
454 return 0; 356 return 0;
455 // num_entries includes entries already evicted. 357 // num_entries includes entries already evicted.
456 int32 not_deleted = data_->header.num_entries - 358 int32 not_deleted = data_->header.num_entries -
457 data_->header.lru.sizes[Rankings::DELETED]; 359 data_->header.lru.sizes[Rankings::DELETED];
(...skipping 26 matching lines...) Expand all
484 return NULL; 386 return NULL;
485 } 387 }
486 388
487 eviction_.OnOpenEntry(cache_entry); 389 eviction_.OnOpenEntry(cache_entry);
488 390
489 CACHE_UMA(AGE_MS, "OpenTime", GetSizeGroup(), start); 391 CACHE_UMA(AGE_MS, "OpenTime", GetSizeGroup(), start);
490 stats_.OnEvent(Stats::OPEN_HIT); 392 stats_.OnEvent(Stats::OPEN_HIT);
491 return cache_entry; 393 return cache_entry;
492 } 394 }
493 395
494 int BackendImpl::SyncOpenEntry(const std::string& key, Entry** entry) { 396 bool BackendImpl::OpenEntry(const std::string& key, Entry** entry) {
495 DCHECK(entry); 397 DCHECK(entry);
496 *entry = OpenEntryImpl(key); 398 *entry = OpenEntryImpl(key);
497 return (*entry) ? net::OK : net::ERR_FAILED; 399 return (*entry) ? true : false;
498 } 400 }
499 401
500 int BackendImpl::OpenEntry(const std::string& key, Entry** entry, 402 int BackendImpl::OpenEntry(const std::string& key, Entry** entry,
501 CompletionCallback* callback) { 403 CompletionCallback* callback) {
502 DCHECK(callback); 404 if (OpenEntry(key, entry))
503 background_queue_.OpenEntry(key, entry, callback); 405 return net::OK;
504 return net::ERR_IO_PENDING; 406
407 return net::ERR_FAILED;
505 } 408 }
506 409
507 EntryImpl* BackendImpl::CreateEntryImpl(const std::string& key) { 410 EntryImpl* BackendImpl::CreateEntryImpl(const std::string& key) {
508 if (disabled_ || key.empty()) 411 if (disabled_ || key.empty())
509 return NULL; 412 return NULL;
510 413
511 TimeTicks start = TimeTicks::Now(); 414 TimeTicks start = TimeTicks::Now();
512 uint32 hash = Hash(key); 415 uint32 hash = Hash(key);
513 416
514 scoped_refptr<EntryImpl> parent; 417 scoped_refptr<EntryImpl> parent;
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
574 eviction_.OnCreateEntry(cache_entry); 477 eviction_.OnCreateEntry(cache_entry);
575 if (!parent.get()) 478 if (!parent.get())
576 data_->table[hash & mask_] = entry_address.value(); 479 data_->table[hash & mask_] = entry_address.value();
577 480
578 CACHE_UMA(AGE_MS, "CreateTime", GetSizeGroup(), start); 481 CACHE_UMA(AGE_MS, "CreateTime", GetSizeGroup(), start);
579 stats_.OnEvent(Stats::CREATE_HIT); 482 stats_.OnEvent(Stats::CREATE_HIT);
580 Trace("create entry hit "); 483 Trace("create entry hit ");
581 return cache_entry.release(); 484 return cache_entry.release();
582 } 485 }
583 486
584 int BackendImpl::SyncCreateEntry(const std::string& key, Entry** entry) { 487 bool BackendImpl::CreateEntry(const std::string& key, Entry** entry) {
585 DCHECK(entry); 488 DCHECK(entry);
586 *entry = CreateEntryImpl(key); 489 *entry = CreateEntryImpl(key);
587 return (*entry) ? net::OK : net::ERR_FAILED; 490 return (*entry) ? true : false;
588 } 491 }
589 492
590 int BackendImpl::CreateEntry(const std::string& key, Entry** entry, 493 int BackendImpl::CreateEntry(const std::string& key, Entry** entry,
591 CompletionCallback* callback) { 494 CompletionCallback* callback) {
592 DCHECK(callback); 495 if (CreateEntry(key, entry))
593 background_queue_.CreateEntry(key, entry, callback);
594 return net::ERR_IO_PENDING;
595 }
596
597 int BackendImpl::SyncDoomEntry(const std::string& key) {
598 if (DoomEntry(key))
599 return net::OK; 496 return net::OK;
600 497
601 return net::ERR_FAILED; 498 return net::ERR_FAILED;
602 } 499 }
603 500
604 bool BackendImpl::DoomEntry(const std::string& key) { 501 bool BackendImpl::DoomEntry(const std::string& key) {
605 if (disabled_) 502 if (disabled_)
606 return false; 503 return false;
607 504
608 EntryImpl* entry = OpenEntryImpl(key); 505 Entry* entry;
609 if (!entry) 506 if (!OpenEntry(key, &entry))
610 return false; 507 return false;
611 508
612 entry->DoomImpl(); 509 // Note that you'd think you could just pass &entry_impl to OpenEntry,
613 entry->Release(); 510 // but that triggers strict aliasing problems with gcc.
511 EntryImpl* entry_impl = reinterpret_cast<EntryImpl*>(entry);
512 entry_impl->Doom();
513 entry_impl->Release();
614 return true; 514 return true;
615 } 515 }
616 516
617 int BackendImpl::DoomEntry(const std::string& key, 517 int BackendImpl::DoomEntry(const std::string& key,
618 CompletionCallback* callback) { 518 CompletionCallback* callback) {
619 DCHECK(callback); 519 if (DoomEntry(key))
620 background_queue_.DoomEntry(key, callback);
621 return net::ERR_IO_PENDING;
622 }
623
624 int BackendImpl::SyncDoomAllEntries() {
625 if (DoomAllEntries())
626 return net::OK; 520 return net::OK;
627 521
628 return net::ERR_FAILED; 522 return net::ERR_FAILED;
629 } 523 }
630 524
631 bool BackendImpl::DoomAllEntries() { 525 bool BackendImpl::DoomAllEntries() {
632 if (!num_refs_) { 526 if (!num_refs_) {
633 PrepareForRestart(); 527 PrepareForRestart();
634 DeleteCache(path_, false); 528 DeleteCache(path_, false);
635 return Init(); 529 return Init();
636 } else { 530 } else {
637 if (disabled_) 531 if (disabled_)
638 return false; 532 return false;
639 533
640 eviction_.TrimCache(true); 534 eviction_.TrimCache(true);
641 stats_.OnEvent(Stats::DOOM_CACHE); 535 stats_.OnEvent(Stats::DOOM_CACHE);
642 return true; 536 return true;
643 } 537 }
644 } 538 }
645 539
646 int BackendImpl::DoomAllEntries(CompletionCallback* callback) { 540 int BackendImpl::DoomAllEntries(CompletionCallback* callback) {
647 DCHECK(callback); 541 if (DoomAllEntries())
648 background_queue_.DoomAllEntries(callback);
649 return net::ERR_IO_PENDING;
650 }
651
652 int BackendImpl::SyncDoomEntriesBetween(const base::Time initial_time,
653 const base::Time end_time) {
654 if (DoomEntriesBetween(initial_time, end_time))
655 return net::OK; 542 return net::OK;
656 543
657 return net::ERR_FAILED; 544 return net::ERR_FAILED;
658 } 545 }
659 546
660 bool BackendImpl::DoomEntriesBetween(const Time initial_time, 547 bool BackendImpl::DoomEntriesBetween(const Time initial_time,
661 const Time end_time) { 548 const Time end_time) {
662 if (end_time.is_null()) 549 if (end_time.is_null())
663 return DoomEntriesSince(initial_time); 550 return DoomEntriesSince(initial_time);
664 551
665 DCHECK(end_time >= initial_time); 552 DCHECK(end_time >= initial_time);
666 553
667 if (disabled_) 554 if (disabled_)
668 return false; 555 return false;
669 556
670 EntryImpl* node; 557 Entry* node, *next;
671 void* iter = NULL; 558 void* iter = NULL;
672 EntryImpl* next = OpenNextEntryImpl(&iter); 559 if (!OpenNextEntry(&iter, &next))
673 if (!next)
674 return true; 560 return true;
675 561
676 while (next) { 562 while (next) {
677 node = next; 563 node = next;
678 next = OpenNextEntryImpl(&iter); 564 if (!OpenNextEntry(&iter, &next))
565 next = NULL;
679 566
680 if (node->GetLastUsed() >= initial_time && 567 if (node->GetLastUsed() >= initial_time &&
681 node->GetLastUsed() < end_time) { 568 node->GetLastUsed() < end_time) {
682 node->DoomImpl(); 569 node->Doom();
683 } else if (node->GetLastUsed() < initial_time) { 570 } else if (node->GetLastUsed() < initial_time) {
684 if (next) 571 if (next)
685 next->Release(); 572 next->Close();
686 next = NULL; 573 next = NULL;
687 SyncEndEnumeration(iter); 574 EndEnumeration(&iter);
688 } 575 }
689 576
690 node->Release(); 577 node->Close();
691 } 578 }
692 579
693 return true; 580 return true;
694 } 581 }
695 582
696 int BackendImpl::DoomEntriesBetween(const base::Time initial_time, 583 int BackendImpl::DoomEntriesBetween(const base::Time initial_time,
697 const base::Time end_time, 584 const base::Time end_time,
698 CompletionCallback* callback) { 585 CompletionCallback* callback) {
699 DCHECK(callback); 586 if (DoomEntriesBetween(initial_time, end_time))
700 background_queue_.DoomEntriesBetween(initial_time, end_time, callback); 587 return net::OK;
701 return net::ERR_IO_PENDING; 588
589 return net::ERR_FAILED;
702 } 590 }
703 591
704 int BackendImpl::SyncDoomEntriesSince(const base::Time initial_time) { 592 // We use OpenNextEntry to retrieve elements from the cache, until we get
593 // entries that are too old.
594 bool BackendImpl::DoomEntriesSince(const Time initial_time) {
595 if (disabled_)
596 return false;
597
598 for (;;) {
599 Entry* entry;
600 void* iter = NULL;
601 if (!OpenNextEntry(&iter, &entry))
602 return true;
603
604 if (initial_time > entry->GetLastUsed()) {
605 entry->Close();
606 EndEnumeration(&iter);
607 return true;
608 }
609
610 entry->Doom();
611 entry->Close();
612 EndEnumeration(&iter); // Dooming the entry invalidates the iterator.
613 }
614 }
615
616 int BackendImpl::DoomEntriesSince(const base::Time initial_time,
617 CompletionCallback* callback) {
705 if (DoomEntriesSince(initial_time)) 618 if (DoomEntriesSince(initial_time))
706 return net::OK; 619 return net::OK;
707 620
708 return net::ERR_FAILED; 621 return net::ERR_FAILED;
709 } 622 }
710 623
711 // We use OpenNextEntryImpl to retrieve elements from the cache, until we get 624 bool BackendImpl::OpenNextEntry(void** iter, Entry** next_entry) {
712 // entries that are too old. 625 return OpenFollowingEntry(true, iter, next_entry);
713 bool BackendImpl::DoomEntriesSince(const Time initial_time) {
714 if (disabled_)
715 return false;
716
717 for (;;) {
718 void* iter = NULL;
719 EntryImpl* entry = OpenNextEntryImpl(&iter);
720 if (!entry)
721 return true;
722
723 if (initial_time > entry->GetLastUsed()) {
724 entry->Release();
725 SyncEndEnumeration(iter);
726 return true;
727 }
728
729 entry->DoomImpl();
730 entry->Release();
731 SyncEndEnumeration(iter); // Dooming the entry invalidates the iterator.
732 }
733 }
734
735 int BackendImpl::DoomEntriesSince(const base::Time initial_time,
736 CompletionCallback* callback) {
737 DCHECK(callback);
738 background_queue_.DoomEntriesSince(initial_time, callback);
739 return net::ERR_IO_PENDING;
740 }
741
742 int BackendImpl::SyncOpenNextEntry(void** iter, Entry** next_entry) {
743 *next_entry = OpenNextEntryImpl(iter);
744 return (*next_entry) ? net::OK : net::ERR_FAILED;
745 }
746
747 EntryImpl* BackendImpl::OpenNextEntryImpl(void** iter) {
748 return OpenFollowingEntry(true, iter);
749 } 626 }
750 627
751 int BackendImpl::OpenNextEntry(void** iter, Entry** next_entry, 628 int BackendImpl::OpenNextEntry(void** iter, Entry** next_entry,
752 CompletionCallback* callback) { 629 CompletionCallback* callback) {
753 DCHECK(callback); 630 if (OpenNextEntry(iter, next_entry))
754 background_queue_.OpenNextEntry(iter, next_entry, callback); 631 return net::OK;
755 return net::ERR_IO_PENDING;
756 }
757 632
758 void BackendImpl::SyncEndEnumeration(void* iter) { 633 return net::ERR_FAILED;
759 scoped_ptr<Rankings::Iterator> iterator(
760 reinterpret_cast<Rankings::Iterator*>(iter));
761 } 634 }
762 635
763 void BackendImpl::EndEnumeration(void** iter) { 636 void BackendImpl::EndEnumeration(void** iter) {
764 background_queue_.EndEnumeration(*iter); 637 scoped_ptr<Rankings::Iterator> iterator(
638 reinterpret_cast<Rankings::Iterator*>(*iter));
765 *iter = NULL; 639 *iter = NULL;
766 } 640 }
767 641
768 void BackendImpl::GetStats(StatsItems* stats) { 642 void BackendImpl::GetStats(StatsItems* stats) {
769 if (disabled_) 643 if (disabled_)
770 return; 644 return;
771 645
772 std::pair<std::string, std::string> item; 646 std::pair<std::string, std::string> item;
773 647
774 item.first = "Entries"; 648 item.first = "Entries";
(...skipping 360 matching lines...) Expand 10 before | Expand all | Expand 10 after
1135 } 1009 }
1136 1010
1137 void BackendImpl::SetFlags(uint32 flags) { 1011 void BackendImpl::SetFlags(uint32 flags) {
1138 user_flags_ |= flags; 1012 user_flags_ |= flags;
1139 } 1013 }
1140 1014
1141 void BackendImpl::ClearRefCountForTest() { 1015 void BackendImpl::ClearRefCountForTest() {
1142 num_refs_ = 0; 1016 num_refs_ = 0;
1143 } 1017 }
1144 1018
1145 int BackendImpl::FlushQueueForTest(CompletionCallback* callback) {
1146 background_queue_.FlushQueue(callback);
1147 return net::ERR_IO_PENDING;
1148 }
1149
1150 int BackendImpl::SelfCheck() { 1019 int BackendImpl::SelfCheck() {
1151 if (!init_) { 1020 if (!init_) {
1152 LOG(ERROR) << "Init failed"; 1021 LOG(ERROR) << "Init failed";
1153 return ERR_INIT_FAILED; 1022 return ERR_INIT_FAILED;
1154 } 1023 }
1155 1024
1156 int num_entries = rankings_.SelfCheck(); 1025 int num_entries = rankings_.SelfCheck();
1157 if (num_entries < 0) { 1026 if (num_entries < 0) {
1158 LOG(ERROR) << "Invalid rankings list, error " << num_entries; 1027 LOG(ERROR) << "Invalid rankings list, error " << num_entries;
1159 return num_entries; 1028 return num_entries;
1160 } 1029 }
1161 1030
1162 if (num_entries != data_->header.num_entries) { 1031 if (num_entries != data_->header.num_entries) {
1163 LOG(ERROR) << "Number of entries mismatch"; 1032 LOG(ERROR) << "Number of entries mismatch";
1164 return ERR_NUM_ENTRIES_MISMATCH; 1033 return ERR_NUM_ENTRIES_MISMATCH;
1165 } 1034 }
1166 1035
1167 return CheckAllEntries(); 1036 return CheckAllEntries();
1168 } 1037 }
1169 1038
1170 int BackendImpl::SyncOpenPrevEntry(void** iter, Entry** prev_entry) { 1039 bool BackendImpl::OpenPrevEntry(void** iter, Entry** prev_entry) {
1171 *prev_entry = OpenPrevEntryImpl(iter); 1040 return OpenFollowingEntry(false, iter, prev_entry);
1172 return (*prev_entry) ? net::OK : net::ERR_FAILED;
1173 }
1174
1175 int BackendImpl::OpenPrevEntry(void** iter, Entry** prev_entry,
1176 CompletionCallback* callback) {
1177 DCHECK(callback);
1178 background_queue_.OpenPrevEntry(iter, prev_entry, callback);
1179 return net::ERR_IO_PENDING;
1180 }
1181
1182 EntryImpl* BackendImpl::OpenPrevEntryImpl(void** iter) {
1183 return OpenFollowingEntry(false, iter);
1184 } 1041 }
1185 1042
1186 // ------------------------------------------------------------------------ 1043 // ------------------------------------------------------------------------
1187 1044
1188 // We just created a new file so we're going to write the header and set the 1045 // We just created a new file so we're going to write the header and set the
1189 // file length to include the hash table (zero filled). 1046 // file length to include the hash table (zero filled).
1190 bool BackendImpl::CreateBackingStore(disk_cache::File* file) { 1047 bool BackendImpl::CreateBackingStore(disk_cache::File* file) {
1191 AdjustMaxCacheSize(0); 1048 AdjustMaxCacheSize(0);
1192 1049
1193 IndexHeader header; 1050 IndexHeader header;
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after
1287 DCHECK(!open_entries_.size()); 1144 DCHECK(!open_entries_.size());
1288 PrepareForRestart(); 1145 PrepareForRestart();
1289 DelayedCacheCleanup(path_); 1146 DelayedCacheCleanup(path_);
1290 1147
1291 int64 errors = stats_.GetCounter(Stats::FATAL_ERROR); 1148 int64 errors = stats_.GetCounter(Stats::FATAL_ERROR);
1292 1149
1293 // Don't call Init() if directed by the unit test: we are simulating a failure 1150 // Don't call Init() if directed by the unit test: we are simulating a failure
1294 // trying to re-enable the cache. 1151 // trying to re-enable the cache.
1295 if (unit_test_) 1152 if (unit_test_)
1296 init_ = true; // Let the destructor do proper cleanup. 1153 init_ = true; // Let the destructor do proper cleanup.
1297 else if (SyncInit()) 1154 else if (Init())
1298 stats_.SetCounter(Stats::FATAL_ERROR, errors + 1); 1155 stats_.SetCounter(Stats::FATAL_ERROR, errors + 1);
1299 } 1156 }
1300 1157
1301 void BackendImpl::PrepareForRestart() { 1158 void BackendImpl::PrepareForRestart() {
1302 // Reset the mask_ if it was not given by the user. 1159 // Reset the mask_ if it was not given by the user.
1303 if (!(user_flags_ & kMask)) 1160 if (!(user_flags_ & kMask))
1304 mask_ = 0; 1161 mask_ = 0;
1305 1162
1306 if (!(user_flags_ & kNewEviction)) 1163 if (!(user_flags_ & kNewEviction))
1307 new_eviction_ = false; 1164 new_eviction_ = false;
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after
1437 parent_entry = NULL; 1294 parent_entry = NULL;
1438 1295
1439 if (cache_entry && (find_parent || !found)) 1296 if (cache_entry && (find_parent || !found))
1440 cache_entry = NULL; 1297 cache_entry = NULL;
1441 1298
1442 find_parent ? parent_entry.swap(&tmp) : cache_entry.swap(&tmp); 1299 find_parent ? parent_entry.swap(&tmp) : cache_entry.swap(&tmp);
1443 return tmp; 1300 return tmp;
1444 } 1301 }
1445 1302
1446 // This is the actual implementation for OpenNextEntry and OpenPrevEntry. 1303 // This is the actual implementation for OpenNextEntry and OpenPrevEntry.
1447 EntryImpl* BackendImpl::OpenFollowingEntry(bool forward, void** iter) { 1304 bool BackendImpl::OpenFollowingEntry(bool forward, void** iter,
1305 Entry** next_entry) {
1448 if (disabled_) 1306 if (disabled_)
1449 return NULL; 1307 return false;
1450 1308
1451 DCHECK(iter); 1309 DCHECK(iter);
1310 DCHECK(next_entry);
1311 *next_entry = NULL;
1452 1312
1453 const int kListsToSearch = 3; 1313 const int kListsToSearch = 3;
1454 scoped_refptr<EntryImpl> entries[kListsToSearch]; 1314 scoped_refptr<EntryImpl> entries[kListsToSearch];
1455 scoped_ptr<Rankings::Iterator> iterator( 1315 scoped_ptr<Rankings::Iterator> iterator(
1456 reinterpret_cast<Rankings::Iterator*>(*iter)); 1316 reinterpret_cast<Rankings::Iterator*>(*iter));
1457 *iter = NULL; 1317 *iter = NULL;
1458 1318
1459 if (!iterator.get()) { 1319 if (!iterator.get()) {
1460 iterator.reset(new Rankings::Iterator(&rankings_)); 1320 iterator.reset(new Rankings::Iterator(&rankings_));
1461 bool ret = false; 1321 bool ret = false;
1462 1322
1463 // Get an entry from each list. 1323 // Get an entry from each list.
1464 for (int i = 0; i < kListsToSearch; i++) { 1324 for (int i = 0; i < kListsToSearch; i++) {
1465 EntryImpl* temp = NULL; 1325 EntryImpl* temp = NULL;
1466 ret |= OpenFollowingEntryFromList(forward, static_cast<Rankings::List>(i), 1326 ret |= OpenFollowingEntryFromList(forward, static_cast<Rankings::List>(i),
1467 &iterator->nodes[i], &temp); 1327 &iterator->nodes[i], &temp);
1468 entries[i].swap(&temp); // The entry was already addref'd. 1328 entries[i].swap(&temp); // The entry was already addref'd.
1469 } 1329 }
1470 if (!ret) 1330 if (!ret)
1471 return NULL; 1331 return false;
1472 } else { 1332 } else {
1473 // Get the next entry from the last list, and the actual entries for the 1333 // Get the next entry from the last list, and the actual entries for the
1474 // elements on the other lists. 1334 // elements on the other lists.
1475 for (int i = 0; i < kListsToSearch; i++) { 1335 for (int i = 0; i < kListsToSearch; i++) {
1476 EntryImpl* temp = NULL; 1336 EntryImpl* temp = NULL;
1477 if (iterator->list == i) { 1337 if (iterator->list == i) {
1478 OpenFollowingEntryFromList(forward, iterator->list, 1338 OpenFollowingEntryFromList(forward, iterator->list,
1479 &iterator->nodes[i], &temp); 1339 &iterator->nodes[i], &temp);
1480 } else { 1340 } else {
1481 temp = GetEnumeratedEntry(iterator->nodes[i], false); 1341 temp = GetEnumeratedEntry(iterator->nodes[i], false);
(...skipping 15 matching lines...) Expand all
1497 continue; 1357 continue;
1498 } 1358 }
1499 if (access_times[i] > access_times[newest]) 1359 if (access_times[i] > access_times[newest])
1500 newest = i; 1360 newest = i;
1501 if (access_times[i] < access_times[oldest]) 1361 if (access_times[i] < access_times[oldest])
1502 oldest = i; 1362 oldest = i;
1503 } 1363 }
1504 } 1364 }
1505 1365
1506 if (newest < 0 || oldest < 0) 1366 if (newest < 0 || oldest < 0)
1507 return NULL; 1367 return false;
1508 1368
1509 EntryImpl* next_entry;
1510 if (forward) { 1369 if (forward) {
1511 next_entry = entries[newest].release(); 1370 entries[newest].swap(reinterpret_cast<EntryImpl**>(next_entry));
1512 iterator->list = static_cast<Rankings::List>(newest); 1371 iterator->list = static_cast<Rankings::List>(newest);
1513 } else { 1372 } else {
1514 next_entry = entries[oldest].release(); 1373 entries[oldest].swap(reinterpret_cast<EntryImpl**>(next_entry));
1515 iterator->list = static_cast<Rankings::List>(oldest); 1374 iterator->list = static_cast<Rankings::List>(oldest);
1516 } 1375 }
1517 1376
1518 *iter = iterator.release(); 1377 *iter = iterator.release();
1519 return next_entry; 1378 return true;
1520 } 1379 }
1521 1380
1522 bool BackendImpl::OpenFollowingEntryFromList(bool forward, Rankings::List list, 1381 bool BackendImpl::OpenFollowingEntryFromList(bool forward, Rankings::List list,
1523 CacheRankingsBlock** from_entry, 1382 CacheRankingsBlock** from_entry,
1524 EntryImpl** next_entry) { 1383 EntryImpl** next_entry) {
1525 if (disabled_) 1384 if (disabled_)
1526 return false; 1385 return false;
1527 1386
1528 if (!new_eviction_ && Rankings::NO_USE != list) 1387 if (!new_eviction_ && Rankings::NO_USE != list)
1529 return false; 1388 return false;
(...skipping 320 matching lines...) Expand 10 before | Expand all | Expand 10 after
1850 1709
1851 return num_dirty; 1710 return num_dirty;
1852 } 1711 }
1853 1712
1854 bool BackendImpl::CheckEntry(EntryImpl* cache_entry) { 1713 bool BackendImpl::CheckEntry(EntryImpl* cache_entry) {
1855 RankingsNode* rankings = cache_entry->rankings()->Data(); 1714 RankingsNode* rankings = cache_entry->rankings()->Data();
1856 return !rankings->dummy; 1715 return !rankings->dummy;
1857 } 1716 }
1858 1717
1859 } // namespace disk_cache 1718 } // namespace disk_cache
OLDNEW
« no previous file with comments | « net/disk_cache/backend_impl.h ('k') | net/disk_cache/backend_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698