Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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 "webkit/appcache/appcache_storage_impl.h" | 5 #include "webkit/appcache/appcache_storage_impl.h" |
| 6 | 6 |
| 7 #include "app/sql/connection.h" | 7 #include "app/sql/connection.h" |
| 8 #include "app/sql/transaction.h" | 8 #include "app/sql/transaction.h" |
| 9 #include "base/file_util.h" | 9 #include "base/file_util.h" |
| 10 #include "base/logging.h" | 10 #include "base/logging.h" |
| 11 #include "base/message_loop.h" | 11 #include "base/message_loop.h" |
| (...skipping 490 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 502 would_exceed_quota_ = true; | 502 would_exceed_quota_ = true; |
| 503 success_ = false; | 503 success_ = false; |
| 504 return; | 504 return; |
| 505 } | 505 } |
| 506 | 506 |
| 507 success_ = transaction.Commit(); | 507 success_ = transaction.Commit(); |
| 508 } | 508 } |
| 509 | 509 |
| 510 void AppCacheStorageImpl::StoreGroupAndCacheTask::RunCompleted() { | 510 void AppCacheStorageImpl::StoreGroupAndCacheTask::RunCompleted() { |
| 511 if (success_) { | 511 if (success_) { |
| 512 // TODO(kkanetkar): Add to creation time when that's enabled. | |
| 513 storage_->origins_with_groups_.insert(group_->manifest_url().GetOrigin()); | 512 storage_->origins_with_groups_.insert(group_->manifest_url().GetOrigin()); |
| 514 if (cache_ != group_->newest_complete_cache()) { | 513 if (cache_ != group_->newest_complete_cache()) { |
| 515 cache_->set_complete(true); | 514 cache_->set_complete(true); |
| 516 group_->AddCache(cache_); | 515 group_->AddCache(cache_); |
| 516 if (group_->creation_time().is_null()) | |
|
jennb
2011/04/12 00:07:56
Why only set the group's creation time if cache is
michaeln
2011/04/14 23:41:23
Done.
| |
| 517 group_->set_creation_time(group_record_.creation_time); | |
|
adamk
2011/04/11 20:45:16
Is this related to the preferred manifest url chan
michaeln
2011/04/14 23:41:23
This is unrelated, i just noticed the very minor T
| |
| 517 } | 518 } |
| 518 group_->AddNewlyDeletableResponseIds(&newly_deletable_response_ids_); | 519 group_->AddNewlyDeletableResponseIds(&newly_deletable_response_ids_); |
| 519 } | 520 } |
| 520 FOR_EACH_DELEGATE(delegates_, | 521 FOR_EACH_DELEGATE(delegates_, |
| 521 OnGroupAndNewestCacheStored(group_, cache_, success_, | 522 OnGroupAndNewestCacheStored(group_, cache_, success_, |
| 522 would_exceed_quota_)); | 523 would_exceed_quota_)); |
| 523 group_ = NULL; | 524 group_ = NULL; |
| 524 cache_ = NULL; | 525 cache_ = NULL; |
| 525 } | 526 } |
| 526 | 527 |
| 527 void AppCacheStorageImpl::StoreGroupAndCacheTask::CancelCompletion() { | 528 void AppCacheStorageImpl::StoreGroupAndCacheTask::CancelCompletion() { |
| 528 // Overriden to safely drop our reference to the group and cache | 529 // Overriden to safely drop our reference to the group and cache |
| 529 // which are not thread safe refcounted. | 530 // which are not thread safe refcounted. |
| 530 DatabaseTask::CancelCompletion(); | 531 DatabaseTask::CancelCompletion(); |
| 531 group_ = NULL; | 532 group_ = NULL; |
| 532 cache_ = NULL; | 533 cache_ = NULL; |
| 533 } | 534 } |
| 534 | 535 |
| 535 // FindMainResponseTask ------- | 536 // FindMainResponseTask ------- |
| 536 | 537 |
| 537 class AppCacheStorageImpl::FindMainResponseTask : public DatabaseTask { | 538 class AppCacheStorageImpl::FindMainResponseTask : public DatabaseTask { |
| 538 public: | 539 public: |
| 539 FindMainResponseTask(AppCacheStorageImpl* storage, const GURL& url, | 540 FindMainResponseTask(AppCacheStorageImpl* storage, const GURL& url, |
|
adamk
2011/04/11 20:45:16
Nit: while you're here, may as well follow that sa
michaeln
2011/04/14 23:41:23
Done.
| |
| 541 const GURL& preferred_manifest_url, | |
| 540 const AppCacheWorkingSet::GroupMap* groups_in_use) | 542 const AppCacheWorkingSet::GroupMap* groups_in_use) |
| 541 : DatabaseTask(storage), url_(url), cache_id_(kNoCacheId) { | 543 : DatabaseTask(storage), url_(url), |
| 544 preferred_manifest_url_(preferred_manifest_url), | |
| 545 cache_id_(kNoCacheId) { | |
| 542 if (groups_in_use) { | 546 if (groups_in_use) { |
| 543 for (AppCacheWorkingSet::GroupMap::const_iterator it = | 547 for (AppCacheWorkingSet::GroupMap::const_iterator it = |
| 544 groups_in_use->begin(); | 548 groups_in_use->begin(); |
| 545 it != groups_in_use->end(); ++it) { | 549 it != groups_in_use->end(); ++it) { |
| 546 AppCacheGroup* group = it->second; | 550 AppCacheGroup* group = it->second; |
| 547 AppCache* cache = group->newest_complete_cache(); | 551 AppCache* cache = group->newest_complete_cache(); |
| 548 if (group->is_obsolete() || !cache) | 552 if (group->is_obsolete() || !cache) |
| 549 continue; | 553 continue; |
| 550 cache_ids_in_use_.insert(cache->cache_id()); | 554 cache_ids_in_use_.insert(cache->cache_id()); |
| 551 } | 555 } |
| 552 } | 556 } |
| 553 } | 557 } |
| 554 | 558 |
| 555 virtual void Run(); | 559 virtual void Run(); |
| 556 virtual void RunCompleted(); | 560 virtual void RunCompleted(); |
| 557 | 561 |
| 558 GURL url_; | 562 GURL url_; |
| 563 GURL preferred_manifest_url_; | |
| 559 std::set<int64> cache_ids_in_use_; | 564 std::set<int64> cache_ids_in_use_; |
| 560 AppCacheEntry entry_; | 565 AppCacheEntry entry_; |
| 561 AppCacheEntry fallback_entry_; | 566 AppCacheEntry fallback_entry_; |
| 562 GURL fallback_url_; | 567 GURL fallback_url_; |
| 563 int64 cache_id_; | 568 int64 cache_id_; |
| 564 GURL manifest_url_; | 569 GURL manifest_url_; |
| 565 }; | 570 }; |
| 566 | 571 |
| 567 // Helpers for FindMainResponseTask::Run() | 572 // Helpers for FindMainResponseTask::Run() |
| 568 namespace { | 573 namespace { |
| 574 struct SortByCacheId | |
|
adamk
2011/04/11 20:45:16
"struct" here isn't helping much, since you have p
michaeln
2011/04/14 23:41:23
Done.
| |
| 575 : public std::binary_function< | |
| 576 AppCacheDatabase::EntryRecord, | |
| 577 AppCacheDatabase::EntryRecord, | |
| 578 bool> { | |
| 579 SortByCacheId(int64 preferred_id, const std::set<int64>* in_use_ids) | |
|
adamk
2011/04/11 20:45:16
Minor point, but why not just a const ref? Instan
michaeln
2011/04/14 23:41:23
Done.
| |
| 580 : preferred_id_(preferred_id), in_use_ids_(in_use_ids) { | |
| 581 } | |
| 582 bool operator()( | |
| 583 const AppCacheDatabase::EntryRecord& lhs, | |
| 584 const AppCacheDatabase::EntryRecord& rhs) { | |
| 585 return compute_value(lhs) > compute_value(rhs); | |
| 586 } | |
| 587 private: | |
| 588 int compute_value(const AppCacheDatabase::EntryRecord& entry) { | |
| 589 if (entry.cache_id == preferred_id_) | |
| 590 return 100; | |
| 591 else if (in_use_ids_->find(entry.cache_id) != in_use_ids_->end()) | |
|
jennb
2011/04/12 00:07:56
It would be nice if in_use_ids was sorted by LRU s
michaeln
2011/04/14 23:41:23
I'm sure the logic to disambiguate between multipl
| |
| 592 return 50; | |
| 593 return 0; | |
| 594 } | |
| 595 int64 preferred_id_; | |
| 596 const std::set<int64>* in_use_ids_; | |
| 597 }; | |
| 598 | |
| 569 bool SortByLength( | 599 bool SortByLength( |
| 570 const AppCacheDatabase::FallbackNameSpaceRecord& lhs, | 600 const AppCacheDatabase::FallbackNameSpaceRecord& lhs, |
| 571 const AppCacheDatabase::FallbackNameSpaceRecord& rhs) { | 601 const AppCacheDatabase::FallbackNameSpaceRecord& rhs) { |
| 572 return lhs.namespace_url.spec().length() > rhs.namespace_url.spec().length(); | 602 return lhs.namespace_url.spec().length() > rhs.namespace_url.spec().length(); |
| 573 } | 603 } |
| 574 | 604 |
| 575 class NetworkNamespaceHelper { | 605 class NetworkNamespaceHelper { |
| 576 public: | 606 public: |
| 577 explicit NetworkNamespaceHelper(AppCacheDatabase* database) | 607 explicit NetworkNamespaceHelper(AppCacheDatabase* database) |
| 578 : database_(database) { | 608 : database_(database) { |
| (...skipping 23 matching lines...) Expand all Loading... | |
| 602 urls->push_back(iter->namespace_url); | 632 urls->push_back(iter->namespace_url); |
| 603 ++iter; | 633 ++iter; |
| 604 } | 634 } |
| 605 } | 635 } |
| 606 | 636 |
| 607 // Key is cache id | 637 // Key is cache id |
| 608 typedef std::map<int64, std::vector<GURL> > WhiteListMap; | 638 typedef std::map<int64, std::vector<GURL> > WhiteListMap; |
| 609 WhiteListMap namespaces_map_; | 639 WhiteListMap namespaces_map_; |
| 610 AppCacheDatabase* database_; | 640 AppCacheDatabase* database_; |
| 611 }; | 641 }; |
| 642 | |
| 643 bool IsValidForMainResponse(const AppCacheDatabase::EntryRecord& entry_record, | |
|
adamk
2011/04/11 20:45:16
I'd name this slightly differently, since it's not
jennb
2011/04/12 00:07:56
This could be 2 functions as it's doing 2 complete
michaeln
2011/04/15 02:07:00
Done.
| |
| 644 AppCacheDatabase* database, | |
| 645 GURL* manifest_url_out) { | |
| 646 if (entry_record.flags & AppCacheEntry::FOREIGN) | |
| 647 return false; | |
| 648 AppCacheDatabase::GroupRecord group_record; | |
| 649 if (!database->FindGroupForCache(entry_record.cache_id, &group_record)) { | |
| 650 NOTREACHED() << "A cache without a group is not expected."; | |
| 651 return false; | |
| 652 } | |
| 653 *manifest_url_out = group_record.manifest_url; | |
| 654 return true; | |
| 655 } | |
| 656 | |
| 612 } // namespace | 657 } // namespace |
| 613 | 658 |
| 614 void AppCacheStorageImpl::FindMainResponseTask::Run() { | 659 void AppCacheStorageImpl::FindMainResponseTask::Run() { |
| 615 // We have a bias for hits from caches that are in use. | 660 // NOTE: The heuristics around choosing amoungst multiple candidates |
| 661 // is under specified, and just plain not fully understood. This needs | |
|
adamk
2011/04/11 20:45:16
Grammar nit: s/under specified/underspecified/
michaeln
2011/04/14 23:41:23
Done.
| |
| 662 // to be refined. | |
| 616 | 663 |
| 617 // TODO(michaeln): The heuristics around choosing amoungst | 664 // The 'preferred_manifest_url' is the url of the manifest associated |
| 618 // multiple candidates is under specified, and just plain | 665 // with the page that opened or embedded the page being loaded now. |
| 619 // not fully understood. Refine these over time. In particular, | 666 // We have a strong preference to use resources from that cache. |
| 620 // * prefer candidates from newer caches | 667 // We also have a lesser bias to use resources from caches that are currently |
| 621 // * take into account the cache associated with the document | 668 // being used by other unrelated pages. |
| 622 // that initiated the navigation | 669 // TODO(michaeln): come up with a 'preferred_manifest_url' in more cases |
| 623 // * take into account the cache associated with the document | 670 // - when navigating a frame whose current contents are from an appcache |
| 624 // currently residing in the frame being navigated | 671 // - when clicking an href in a frame that is appcached |
| 672 int64 preferred_cache_id = kNoCacheId; | |
| 673 if (!preferred_manifest_url_.is_empty()) { | |
| 674 AppCacheDatabase::GroupRecord preferred_group; | |
| 675 AppCacheDatabase::CacheRecord preferred_cache; | |
| 676 if (database_->FindGroupForManifestUrl( | |
| 677 preferred_manifest_url_, &preferred_group) && | |
| 678 database_->FindCacheForGroup( | |
| 679 preferred_group.group_id, &preferred_cache)) { | |
| 680 preferred_cache_id = preferred_cache.cache_id; | |
| 681 } | |
| 682 } | |
| 625 | 683 |
| 626 // First look for an exact match. We don't worry about whether | 684 // First look for an exact match. |
| 627 // the containing cache is in-use in this loop because the | |
| 628 // storage class's FindResponseForMainRequest method does that | |
| 629 // as a pre-optimization. | |
| 630 std::vector<AppCacheDatabase::EntryRecord> entries; | 685 std::vector<AppCacheDatabase::EntryRecord> entries; |
|
jennb
2011/04/12 00:07:56
This routine is rather long. You could break out
| |
| 631 if (database_->FindEntriesForUrl(url_, &entries) && !entries.empty()) { | 686 if (database_->FindEntriesForUrl(url_, &entries) && !entries.empty()) { |
| 687 // Sort them in order of preference, from the preferred_cache first, | |
| 688 // followed by hits from caches that are 'in use', then the rest. | |
| 689 std::sort(entries.begin(), entries.end(), | |
| 690 SortByCacheId(preferred_cache_id, &cache_ids_in_use_)); | |
|
jennb
2011/04/12 00:07:56
SortByCacheId makes me think the IDs are being sor
michaeln
2011/04/14 23:41:23
Done.
| |
| 691 | |
| 692 // Take the first with a valid entry. | |
| 632 std::vector<AppCacheDatabase::EntryRecord>::iterator iter; | 693 std::vector<AppCacheDatabase::EntryRecord>::iterator iter; |
| 633 for (iter = entries.begin(); iter < entries.end(); ++iter) { | 694 for (iter = entries.begin(); iter < entries.end(); ++iter) { |
| 634 if (iter->flags & AppCacheEntry::FOREIGN) | 695 if (!IsValidForMainResponse(*iter, database_, &manifest_url_)) |
| 635 continue; | 696 continue; |
| 636 | |
| 637 AppCacheDatabase::GroupRecord group_record; | |
| 638 if (!database_->FindGroupForCache(iter->cache_id, &group_record)) { | |
| 639 NOTREACHED() << "A cache without a group is not expected."; | |
| 640 continue; | |
| 641 } | |
| 642 entry_ = AppCacheEntry(iter->flags, iter->response_id); | 697 entry_ = AppCacheEntry(iter->flags, iter->response_id); |
| 643 cache_id_ = iter->cache_id; | 698 cache_id_ = iter->cache_id; |
| 644 manifest_url_ = group_record.manifest_url; | 699 return; // We found an exact match. |
| 645 return; | |
| 646 } | 700 } |
| 647 } | 701 } |
| 648 | 702 |
| 649 // No exact matches, look at the fallback namespaces for this origin. | 703 // No exact matches, look at the fallback namespaces for this origin. |
| 650 std::vector<AppCacheDatabase::FallbackNameSpaceRecord> fallbacks; | 704 std::vector<AppCacheDatabase::FallbackNameSpaceRecord> all_fallbacks; |
| 651 if (!database_->FindFallbackNameSpacesForOrigin(url_.GetOrigin(), &fallbacks) | 705 if (!database_->FindFallbackNameSpacesForOrigin( |
| 652 || fallbacks.empty()) { | 706 url_.GetOrigin(), &all_fallbacks) |
| 707 || all_fallbacks.empty()) { | |
| 653 return; | 708 return; |
| 654 } | 709 } |
| 655 | 710 |
| 656 // Sort by namespace url string length, longest to shortest, | 711 // Sort them by length, longer matches within the same cache/bucket take |
| 657 // since longer matches trump when matching a url to a namespace. | 712 // precedence. |
| 658 std::sort(fallbacks.begin(), fallbacks.end(), SortByLength); | 713 std::sort(all_fallbacks.begin(), all_fallbacks.end(), SortByLength); |
| 659 | 714 |
| 660 bool has_candidate = false; | 715 // Filter the list and bin them into buckets. |
| 661 GURL candidate_fallback_namespace; | 716 NetworkNamespaceHelper network_namespace_helper(database_); |
| 717 std::vector<AppCacheDatabase::FallbackNameSpaceRecord*> preferred_fallbacks; | |
|
adamk
2011/04/11 20:45:16
I think this would actually be easier to read if y
michaeln
2011/04/15 02:07:00
Done.
| |
| 718 std::vector<AppCacheDatabase::FallbackNameSpaceRecord*> inuse_fallbacks; | |
| 719 std::vector<AppCacheDatabase::FallbackNameSpaceRecord*> other_fallbacks; | |
| 662 std::vector<AppCacheDatabase::FallbackNameSpaceRecord>::iterator iter; | 720 std::vector<AppCacheDatabase::FallbackNameSpaceRecord>::iterator iter; |
| 663 NetworkNamespaceHelper network_namespace_helper(database_); | 721 for (iter = all_fallbacks.begin(); iter < all_fallbacks.end(); ++iter) { |
| 664 for (iter = fallbacks.begin(); iter < fallbacks.end(); ++iter) { | 722 // Skip those that aren't a prefix match. |
| 665 // Skip this fallback namespace if the requested url falls into a network | 723 if (!StartsWithASCII(url_.spec(), iter->namespace_url.spec(), true)) |
| 666 // namespace of the containing appcache. | 724 continue; |
| 725 | |
| 726 // Skip fallback namespaces where the requested url falls into a network | |
| 727 // namespace of its containing appcache. | |
| 667 if (network_namespace_helper.IsInNetworkNamespace(url_, iter->cache_id)) | 728 if (network_namespace_helper.IsInNetworkNamespace(url_, iter->cache_id)) |
| 668 continue; | 729 continue; |
| 669 | 730 |
| 670 if (has_candidate && | 731 // Bin them into one of our three buckets. |
| 671 (candidate_fallback_namespace.spec().length() > | 732 if (iter->cache_id == preferred_cache_id) |
| 672 iter->namespace_url.spec().length())) { | 733 preferred_fallbacks.push_back(&(*iter)); |
| 673 break; // Stop iterating since longer namespace prefix matches win. | 734 else if (cache_ids_in_use_.find(iter->cache_id) != cache_ids_in_use_.end()) |
| 674 } | 735 inuse_fallbacks.push_back(&(*iter)); |
| 736 else | |
| 737 other_fallbacks.push_back(&(*iter)); | |
| 738 } | |
| 675 | 739 |
| 676 if (StartsWithASCII(url_.spec(), iter->namespace_url.spec(), true)) { | 740 // Assemble into a single ordered list. |
|
jennb
2011/04/12 00:07:56
Instead of building one single list out of the thr
michaeln
2011/04/15 02:07:00
Done.
| |
| 677 bool is_cache_in_use = cache_ids_in_use_.find(iter->cache_id) != | 741 std::vector<AppCacheDatabase::FallbackNameSpaceRecord*> ordered_fallbacks; |
| 678 cache_ids_in_use_.end(); | 742 if (!preferred_fallbacks.empty()) |
| 743 ordered_fallbacks.insert(ordered_fallbacks.end(), | |
| 744 preferred_fallbacks.begin(), | |
| 745 preferred_fallbacks.end()); | |
| 746 if (!inuse_fallbacks.empty()) | |
| 747 ordered_fallbacks.insert(ordered_fallbacks.end(), | |
| 748 inuse_fallbacks.begin(), | |
| 749 inuse_fallbacks.end()); | |
| 750 if (!other_fallbacks.empty()) | |
| 751 ordered_fallbacks.insert(ordered_fallbacks.end(), | |
| 752 other_fallbacks.begin(), | |
| 753 other_fallbacks.end()); | |
| 679 | 754 |
| 680 bool take_new_candidate = !has_candidate || is_cache_in_use; | 755 // Take the first with a valid entry. |
| 681 | 756 std::vector<AppCacheDatabase::FallbackNameSpaceRecord*>::const_iterator iter2; |
|
adamk
2011/04/11 20:45:16
The fact that this is called "iter2" suggests to m
michaeln
2011/04/15 02:07:00
Done, got rid of iter2 but did the split in a diff
| |
| 682 AppCacheDatabase::EntryRecord entry_record; | 757 for (iter2 = ordered_fallbacks.begin(); iter2 < ordered_fallbacks.end(); |
| 683 if (take_new_candidate && | 758 ++iter2) { |
| 684 database_->FindEntry(iter->cache_id, iter->fallback_entry_url, | 759 AppCacheDatabase::EntryRecord entry_record; |
| 685 &entry_record)) { | 760 if (database_->FindEntry((*iter2)->cache_id, (*iter2)->fallback_entry_url, |
| 686 if (entry_record.flags & AppCacheEntry::FOREIGN) | 761 &entry_record)) { |
| 687 continue; | 762 if (!IsValidForMainResponse(entry_record, database_, &manifest_url_)) |
| 688 AppCacheDatabase::GroupRecord group_record; | 763 continue; |
| 689 if (!database_->FindGroupForCache(iter->cache_id, &group_record)) { | 764 cache_id_ = (*iter2)->cache_id; |
| 690 NOTREACHED() << "A cache without a group is not expected."; | 765 fallback_url_ = (*iter2)->fallback_entry_url; |
| 691 continue; | 766 fallback_entry_ = AppCacheEntry( |
| 692 } | 767 entry_record.flags, entry_record.response_id); |
| 693 cache_id_ = iter->cache_id; | 768 return; // We found a matching fallback entry. |
| 694 fallback_url_ = iter->fallback_entry_url; | |
| 695 manifest_url_ = group_record.manifest_url; | |
| 696 fallback_entry_ = AppCacheEntry( | |
| 697 entry_record.flags, entry_record.response_id); | |
| 698 if (is_cache_in_use) | |
| 699 break; // Stop iterating since we favor hits from in-use caches. | |
| 700 candidate_fallback_namespace = iter->namespace_url; | |
| 701 has_candidate = true; | |
| 702 } | |
| 703 } | 769 } |
| 704 } | 770 } |
| 771 | |
| 772 // We didn't find antything. | |
|
adamk
2011/04/11 20:45:16
s/antything/anything/
michaeln
2011/04/14 23:41:23
Done.
| |
| 773 DCHECK(cache_id_ == kNoCacheId && manifest_url_.is_empty()); | |
| 705 } | 774 } |
| 706 | 775 |
| 707 void AppCacheStorageImpl::FindMainResponseTask::RunCompleted() { | 776 void AppCacheStorageImpl::FindMainResponseTask::RunCompleted() { |
| 708 storage_->CheckPolicyAndCallOnMainResponseFound( | 777 storage_->CheckPolicyAndCallOnMainResponseFound( |
| 709 &delegates_, url_, entry_, fallback_url_, fallback_entry_, | 778 &delegates_, url_, entry_, fallback_url_, fallback_entry_, |
| 710 cache_id_, manifest_url_); | 779 cache_id_, manifest_url_); |
| 711 } | 780 } |
| 712 | 781 |
| 713 // MarkEntryAsForeignTask ------- | 782 // MarkEntryAsForeignTask ------- |
| 714 | 783 |
| (...skipping 316 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1031 // the simple update case in a very heavy weight way (delete all and | 1100 // the simple update case in a very heavy weight way (delete all and |
| 1032 // the reinsert all over again). | 1101 // the reinsert all over again). |
| 1033 DCHECK(group && delegate && newest_cache); | 1102 DCHECK(group && delegate && newest_cache); |
| 1034 scoped_refptr<StoreGroupAndCacheTask> task( | 1103 scoped_refptr<StoreGroupAndCacheTask> task( |
| 1035 new StoreGroupAndCacheTask(this, group, newest_cache)); | 1104 new StoreGroupAndCacheTask(this, group, newest_cache)); |
| 1036 task->AddDelegate(GetOrCreateDelegateReference(delegate)); | 1105 task->AddDelegate(GetOrCreateDelegateReference(delegate)); |
| 1037 task->Schedule(); | 1106 task->Schedule(); |
| 1038 } | 1107 } |
| 1039 | 1108 |
| 1040 void AppCacheStorageImpl::FindResponseForMainRequest( | 1109 void AppCacheStorageImpl::FindResponseForMainRequest( |
| 1041 const GURL& url, Delegate* delegate) { | 1110 const GURL& url, const GURL& preferred_manifest_url, |
| 1111 Delegate* delegate) { | |
| 1042 DCHECK(delegate); | 1112 DCHECK(delegate); |
| 1043 | 1113 |
| 1044 const GURL* url_ptr = &url; | 1114 const GURL* url_ptr = &url; |
| 1045 GURL url_no_ref; | 1115 GURL url_no_ref; |
| 1046 if (url.has_ref()) { | 1116 if (url.has_ref()) { |
| 1047 GURL::Replacements replacements; | 1117 GURL::Replacements replacements; |
| 1048 replacements.ClearRef(); | 1118 replacements.ClearRef(); |
| 1049 url_no_ref = url.ReplaceComponents(replacements); | 1119 url_no_ref = url.ReplaceComponents(replacements); |
| 1050 url_ptr = &url_no_ref; | 1120 url_ptr = &url_no_ref; |
| 1051 } | 1121 } |
| 1052 | 1122 |
| 1053 const GURL origin = url.GetOrigin(); | 1123 const GURL origin = url.GetOrigin(); |
| 1054 | 1124 |
| 1055 // First look in our working set for a direct hit without having to query | 1125 // First look in our working set for a direct hit without having to query |
| 1056 // the database. | 1126 // the database. |
| 1057 const AppCacheWorkingSet::GroupMap* groups_in_use = | 1127 const AppCacheWorkingSet::GroupMap* groups_in_use = |
| 1058 working_set()->GetGroupsInOrigin(origin); | 1128 working_set()->GetGroupsInOrigin(origin); |
| 1059 if (groups_in_use) { | 1129 if (groups_in_use) { |
| 1060 for (AppCacheWorkingSet::GroupMap::const_iterator it = | 1130 if (!preferred_manifest_url.is_empty()) { |
| 1061 groups_in_use->begin(); | 1131 AppCacheWorkingSet::GroupMap::const_iterator found = |
| 1062 it != groups_in_use->end(); ++it) { | 1132 groups_in_use->find(preferred_manifest_url); |
| 1063 AppCacheGroup* group = it->second; | 1133 if (found != groups_in_use->end() && |
| 1064 AppCache* cache = group->newest_complete_cache(); | 1134 FindResponseForMainRequestInGroup( |
| 1065 if (group->is_obsolete() || !cache) | 1135 found->second, *url_ptr, delegate)) { |
| 1066 continue; | 1136 return; |
|
adamk
2011/04/11 20:45:16
Nit: indentation
| |
| 1067 | 1137 } |
| 1068 AppCacheEntry* entry = cache->GetEntry(*url_ptr); | 1138 } else { |
| 1069 if (entry && !entry->IsForeign()) { | 1139 for (AppCacheWorkingSet::GroupMap::const_iterator it = |
| 1070 ScheduleSimpleTask(method_factory_.NewRunnableMethod( | 1140 groups_in_use->begin(); |
| 1071 &AppCacheStorageImpl::DeliverShortCircuitedFindMainResponse, | 1141 it != groups_in_use->end(); ++it) { |
| 1072 url, *entry, make_scoped_refptr(group), make_scoped_refptr(cache), | 1142 if (FindResponseForMainRequestInGroup( |
| 1073 make_scoped_refptr(GetOrCreateDelegateReference(delegate)))); | 1143 it->second, *url_ptr, delegate)) { |
| 1074 return; | 1144 return; |
| 1145 } | |
| 1075 } | 1146 } |
| 1076 } | 1147 } |
| 1077 } | 1148 } |
| 1078 | 1149 |
| 1079 if (IsInitTaskComplete() && | 1150 if (IsInitTaskComplete() && |
| 1080 origins_with_groups_.find(origin) == origins_with_groups_.end()) { | 1151 origins_with_groups_.find(origin) == origins_with_groups_.end()) { |
| 1081 // No need to query the database, return async'ly but without going thru | 1152 // No need to query the database, return async'ly but without going thru |
| 1082 // the DB thread. | 1153 // the DB thread. |
| 1083 scoped_refptr<AppCacheGroup> no_group; | 1154 scoped_refptr<AppCacheGroup> no_group; |
| 1084 scoped_refptr<AppCache> no_cache; | 1155 scoped_refptr<AppCache> no_cache; |
| 1085 ScheduleSimpleTask(method_factory_.NewRunnableMethod( | 1156 ScheduleSimpleTask(method_factory_.NewRunnableMethod( |
| 1086 &AppCacheStorageImpl::DeliverShortCircuitedFindMainResponse, | 1157 &AppCacheStorageImpl::DeliverShortCircuitedFindMainResponse, |
| 1087 url, AppCacheEntry(), no_group, no_cache, | 1158 url, AppCacheEntry(), no_group, no_cache, |
| 1088 make_scoped_refptr(GetOrCreateDelegateReference(delegate)))); | 1159 make_scoped_refptr(GetOrCreateDelegateReference(delegate)))); |
| 1089 return; | 1160 return; |
| 1090 } | 1161 } |
| 1091 | 1162 |
| 1092 // We have to query the database, schedule a database task to do so. | 1163 // We have to query the database, schedule a database task to do so. |
| 1093 scoped_refptr<FindMainResponseTask> task( | 1164 scoped_refptr<FindMainResponseTask> task( |
| 1094 new FindMainResponseTask(this, *url_ptr, groups_in_use)); | 1165 new FindMainResponseTask(this, *url_ptr, preferred_manifest_url, |
| 1166 groups_in_use)); | |
| 1095 task->AddDelegate(GetOrCreateDelegateReference(delegate)); | 1167 task->AddDelegate(GetOrCreateDelegateReference(delegate)); |
| 1096 task->Schedule(); | 1168 task->Schedule(); |
| 1097 } | 1169 } |
| 1098 | 1170 |
| 1171 bool AppCacheStorageImpl::FindResponseForMainRequestInGroup( | |
| 1172 AppCacheGroup* group, const GURL& url, Delegate* delegate) { | |
|
jennb
2011/04/12 00:07:56
extra space before const
| |
| 1173 AppCache* cache = group->newest_complete_cache(); | |
| 1174 if (group->is_obsolete() || !cache) | |
| 1175 return false; | |
| 1176 | |
| 1177 AppCacheEntry* entry = cache->GetEntry(url); | |
| 1178 if (!entry || entry->IsForeign()) | |
| 1179 return false; | |
| 1180 | |
| 1181 ScheduleSimpleTask(method_factory_.NewRunnableMethod( | |
| 1182 &AppCacheStorageImpl::DeliverShortCircuitedFindMainResponse, | |
| 1183 url, *entry, make_scoped_refptr(group), make_scoped_refptr(cache), | |
| 1184 make_scoped_refptr(GetOrCreateDelegateReference(delegate)))); | |
| 1185 return true; | |
| 1186 } | |
| 1187 | |
| 1099 void AppCacheStorageImpl::DeliverShortCircuitedFindMainResponse( | 1188 void AppCacheStorageImpl::DeliverShortCircuitedFindMainResponse( |
| 1100 const GURL& url, AppCacheEntry found_entry, | 1189 const GURL& url, AppCacheEntry found_entry, |
| 1101 scoped_refptr<AppCacheGroup> group, scoped_refptr<AppCache> cache, | 1190 scoped_refptr<AppCacheGroup> group, scoped_refptr<AppCache> cache, |
| 1102 scoped_refptr<DelegateReference> delegate_ref) { | 1191 scoped_refptr<DelegateReference> delegate_ref) { |
| 1103 if (delegate_ref->delegate) { | 1192 if (delegate_ref->delegate) { |
| 1104 DelegateReferenceVector delegates(1, delegate_ref); | 1193 DelegateReferenceVector delegates(1, delegate_ref); |
| 1105 CheckPolicyAndCallOnMainResponseFound( | 1194 CheckPolicyAndCallOnMainResponseFound( |
| 1106 &delegates, url, found_entry, | 1195 &delegates, url, found_entry, |
| 1107 GURL(), AppCacheEntry(), | 1196 GURL(), AppCacheEntry(), |
| 1108 cache.get() ? cache->cache_id() : kNoCacheId, | 1197 cache.get() ? cache->cache_id() : kNoCacheId, |
| (...skipping 270 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1379 Disable(); | 1468 Disable(); |
| 1380 if (!is_incognito_) { | 1469 if (!is_incognito_) { |
| 1381 VLOG(1) << "Deleting existing appcache data and starting over."; | 1470 VLOG(1) << "Deleting existing appcache data and starting over."; |
| 1382 AppCacheThread::PostTask(AppCacheThread::db(), FROM_HERE, | 1471 AppCacheThread::PostTask(AppCacheThread::db(), FROM_HERE, |
| 1383 NewRunnableFunction(DeleteDirectory, cache_directory_)); | 1472 NewRunnableFunction(DeleteDirectory, cache_directory_)); |
| 1384 } | 1473 } |
| 1385 } | 1474 } |
| 1386 } | 1475 } |
| 1387 | 1476 |
| 1388 } // namespace appcache | 1477 } // namespace appcache |
| OLD | NEW |