| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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 "chrome/browser/predictors/resource_prefetch_predictor.h" | 5 #include "chrome/browser/predictors/resource_prefetch_predictor.h" |
| 6 | 6 |
| 7 #include <map> | 7 #include <map> |
| 8 #include <set> | 8 #include <set> |
| 9 #include <utility> | 9 #include <utility> |
| 10 | 10 |
| (...skipping 516 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 527 PopulatePrefetcherRequest(iterator->second, urls); | 527 PopulatePrefetcherRequest(iterator->second, urls); |
| 528 } | 528 } |
| 529 } | 529 } |
| 530 | 530 |
| 531 return !urls->empty(); | 531 return !urls->empty(); |
| 532 } | 532 } |
| 533 | 533 |
| 534 void ResourcePrefetchPredictor::PopulatePrefetcherRequest( | 534 void ResourcePrefetchPredictor::PopulatePrefetcherRequest( |
| 535 const PrefetchData& data, | 535 const PrefetchData& data, |
| 536 std::vector<GURL>* urls) { | 536 std::vector<GURL>* urls) { |
| 537 for (const ResourceRow& row : data.resources) { | 537 for (const ResourceData& resource : data.resources) { |
| 538 float confidence = static_cast<float>(row.number_of_hits) / | 538 float confidence = |
| 539 (row.number_of_hits + row.number_of_misses); | 539 static_cast<float>(resource.number_of_hits()) / |
| 540 (resource.number_of_hits() + resource.number_of_misses()); |
| 540 if (confidence < config_.min_resource_confidence_to_trigger_prefetch || | 541 if (confidence < config_.min_resource_confidence_to_trigger_prefetch || |
| 541 row.number_of_hits < config_.min_resource_hits_to_trigger_prefetch) { | 542 resource.number_of_hits() < |
| 543 config_.min_resource_hits_to_trigger_prefetch) { |
| 542 continue; | 544 continue; |
| 543 } | 545 } |
| 544 | 546 |
| 545 urls->push_back(row.resource_url); | 547 urls->push_back(GURL(resource.resource_url())); |
| 546 } | 548 } |
| 547 } | 549 } |
| 548 | 550 |
| 549 void ResourcePrefetchPredictor::StartPrefetching( | 551 void ResourcePrefetchPredictor::StartPrefetching( |
| 550 const NavigationID& navigation_id) { | 552 const NavigationID& navigation_id) { |
| 551 if (!prefetch_manager_.get()) // Prefetching not enabled. | 553 if (!prefetch_manager_.get()) // Prefetching not enabled. |
| 552 return; | 554 return; |
| 553 | 555 |
| 554 // Prefer URL based data first. | 556 // Prefer URL based data first. |
| 555 std::vector<GURL> urls; | 557 std::vector<GURL> urls; |
| (...skipping 206 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 762 cache_entry = data_map->insert(std::make_pair( | 764 cache_entry = data_map->insert(std::make_pair( |
| 763 key, PrefetchData(key_type, key))).first; | 765 key, PrefetchData(key_type, key))).first; |
| 764 cache_entry->second.last_visit = base::Time::Now(); | 766 cache_entry->second.last_visit = base::Time::Now(); |
| 765 size_t new_resources_size = new_resources.size(); | 767 size_t new_resources_size = new_resources.size(); |
| 766 std::set<GURL> resources_seen; | 768 std::set<GURL> resources_seen; |
| 767 for (size_t i = 0; i < new_resources_size; ++i) { | 769 for (size_t i = 0; i < new_resources_size; ++i) { |
| 768 if (resources_seen.find(new_resources[i].resource_url) != | 770 if (resources_seen.find(new_resources[i].resource_url) != |
| 769 resources_seen.end()) { | 771 resources_seen.end()) { |
| 770 continue; | 772 continue; |
| 771 } | 773 } |
| 772 ResourceRow row_to_add; | 774 ResourceData resource_to_add; |
| 773 row_to_add.resource_url = new_resources[i].resource_url; | 775 resource_to_add.set_resource_url(new_resources[i].resource_url.spec()); |
| 774 row_to_add.resource_type = new_resources[i].resource_type; | 776 resource_to_add.set_resource_type(static_cast<ResourceData::ResourceType>( |
| 775 row_to_add.number_of_hits = 1; | 777 new_resources[i].resource_type)); |
| 776 row_to_add.average_position = i + 1; | 778 resource_to_add.set_number_of_hits(1); |
| 777 row_to_add.priority = new_resources[i].priority; | 779 resource_to_add.set_average_position(i + 1); |
| 778 row_to_add.has_validators = new_resources[i].has_validators; | 780 resource_to_add.set_priority( |
| 779 row_to_add.always_revalidate = new_resources[i].always_revalidate; | 781 static_cast<ResourceData::Priority>(new_resources[i].priority)); |
| 780 cache_entry->second.resources.push_back(row_to_add); | 782 resource_to_add.set_has_validators(new_resources[i].has_validators); |
| 783 resource_to_add.set_always_revalidate(new_resources[i].always_revalidate); |
| 784 cache_entry->second.resources.push_back(resource_to_add); |
| 781 resources_seen.insert(new_resources[i].resource_url); | 785 resources_seen.insert(new_resources[i].resource_url); |
| 782 } | 786 } |
| 783 } else { | 787 } else { |
| 784 ResourceRows& old_resources = cache_entry->second.resources; | 788 std::vector<ResourceData>& old_resources = cache_entry->second.resources; |
| 785 cache_entry->second.last_visit = base::Time::Now(); | 789 cache_entry->second.last_visit = base::Time::Now(); |
| 786 | 790 |
| 787 // Build indices over the data. | 791 // Build indices over the data. |
| 788 std::map<GURL, int> new_index, old_index; | 792 std::map<GURL, int> new_index, old_index; |
| 789 int new_resources_size = static_cast<int>(new_resources.size()); | 793 int new_resources_size = static_cast<int>(new_resources.size()); |
| 790 for (int i = 0; i < new_resources_size; ++i) { | 794 for (int i = 0; i < new_resources_size; ++i) { |
| 791 const URLRequestSummary& summary = new_resources[i]; | 795 const URLRequestSummary& summary = new_resources[i]; |
| 792 // Take the first occurence of every url. | 796 // Take the first occurence of every url. |
| 793 if (new_index.find(summary.resource_url) == new_index.end()) | 797 if (new_index.find(summary.resource_url) == new_index.end()) |
| 794 new_index[summary.resource_url] = i; | 798 new_index[summary.resource_url] = i; |
| 795 } | 799 } |
| 796 int old_resources_size = static_cast<int>(old_resources.size()); | 800 int old_resources_size = static_cast<int>(old_resources.size()); |
| 797 for (int i = 0; i < old_resources_size; ++i) { | 801 for (int i = 0; i < old_resources_size; ++i) { |
| 798 const ResourceRow& row = old_resources[i]; | 802 const ResourceData& resource = old_resources[i]; |
| 799 DCHECK(old_index.find(row.resource_url) == old_index.end()); | 803 GURL resource_url(resource.resource_url()); |
| 800 old_index[row.resource_url] = i; | 804 DCHECK(old_index.find(resource_url) == old_index.end()); |
| 805 old_index[resource_url] = i; |
| 801 } | 806 } |
| 802 | 807 |
| 803 // Go through the old urls and update their hit/miss counts. | 808 // Go through the old urls and update their hit/miss counts. |
| 804 for (int i = 0; i < old_resources_size; ++i) { | 809 for (int i = 0; i < old_resources_size; ++i) { |
| 805 ResourceRow& old_row = old_resources[i]; | 810 ResourceData& old_resource = old_resources[i]; |
| 806 if (new_index.find(old_row.resource_url) == new_index.end()) { | 811 GURL resource_url(old_resource.resource_url()); |
| 807 ++old_row.number_of_misses; | 812 if (new_index.find(resource_url) == new_index.end()) { |
| 808 ++old_row.consecutive_misses; | 813 old_resource.set_number_of_misses(old_resource.number_of_misses() + 1); |
| 814 old_resource.set_consecutive_misses(old_resource.consecutive_misses() + |
| 815 1); |
| 809 } else { | 816 } else { |
| 810 const URLRequestSummary& new_row = | 817 const URLRequestSummary& new_summary = |
| 811 new_resources[new_index[old_row.resource_url]]; | 818 new_resources[new_index[resource_url]]; |
| 812 | 819 |
| 813 // Update the resource type since it could have changed. | 820 // Update the resource type since it could have changed. |
| 814 if (new_row.resource_type != content::RESOURCE_TYPE_LAST_TYPE) | 821 if (new_summary.resource_type != content::RESOURCE_TYPE_LAST_TYPE) |
| 815 old_row.resource_type = new_row.resource_type; | 822 old_resource.set_resource_type( |
| 823 static_cast<ResourceData::ResourceType>( |
| 824 new_summary.resource_type)); |
| 816 | 825 |
| 817 old_row.priority = new_row.priority; | 826 old_resource.set_priority( |
| 827 static_cast<ResourceData::Priority>(new_summary.priority)); |
| 818 | 828 |
| 819 int position = new_index[old_row.resource_url] + 1; | 829 int position = new_index[resource_url] + 1; |
| 820 int total = old_row.number_of_hits + old_row.number_of_misses; | 830 int total = |
| 821 old_row.average_position = | 831 old_resource.number_of_hits() + old_resource.number_of_misses(); |
| 822 ((old_row.average_position * total) + position) / (total + 1); | 832 old_resource.set_average_position( |
| 823 ++old_row.number_of_hits; | 833 ((old_resource.average_position() * total) + position) / |
| 824 old_row.consecutive_misses = 0; | 834 (total + 1)); |
| 835 old_resource.set_number_of_hits(old_resource.number_of_hits() + 1); |
| 836 old_resource.set_consecutive_misses(0); |
| 825 } | 837 } |
| 826 } | 838 } |
| 827 | 839 |
| 828 // Add the new ones that we have not seen before. | 840 // Add the new ones that we have not seen before. |
| 829 for (int i = 0; i < new_resources_size; ++i) { | 841 for (int i = 0; i < new_resources_size; ++i) { |
| 830 const URLRequestSummary& summary = new_resources[i]; | 842 const URLRequestSummary& summary = new_resources[i]; |
| 831 if (old_index.find(summary.resource_url) != old_index.end()) | 843 if (old_index.find(summary.resource_url) != old_index.end()) |
| 832 continue; | 844 continue; |
| 833 | 845 |
| 834 // Only need to add new stuff. | 846 // Only need to add new stuff. |
| 835 ResourceRow row_to_add; | 847 ResourceData resource_to_add; |
| 836 row_to_add.resource_url = summary.resource_url; | 848 resource_to_add.set_resource_url(summary.resource_url.spec()); |
| 837 row_to_add.resource_type = summary.resource_type; | 849 resource_to_add.set_resource_type( |
| 838 row_to_add.number_of_hits = 1; | 850 static_cast<ResourceData::ResourceType>(summary.resource_type)); |
| 839 row_to_add.average_position = i + 1; | 851 resource_to_add.set_number_of_hits(1); |
| 840 row_to_add.priority = summary.priority; | 852 resource_to_add.set_average_position(i + 1); |
| 841 row_to_add.has_validators = new_resources[i].has_validators; | 853 resource_to_add.set_priority( |
| 842 row_to_add.always_revalidate = new_resources[i].always_revalidate; | 854 static_cast<ResourceData::Priority>(summary.priority)); |
| 843 old_resources.push_back(row_to_add); | 855 resource_to_add.set_has_validators(new_resources[i].has_validators); |
| 856 resource_to_add.set_always_revalidate(new_resources[i].always_revalidate); |
| 857 old_resources.push_back(resource_to_add); |
| 844 | 858 |
| 845 // To ensure we dont add the same url twice. | 859 // To ensure we dont add the same url twice. |
| 846 old_index[summary.resource_url] = 0; | 860 old_index[summary.resource_url] = 0; |
| 847 } | 861 } |
| 848 } | 862 } |
| 849 | 863 |
| 850 // Trim and sort the resources after the update. | 864 // Trim and sort the resources after the update. |
| 851 ResourceRows& resources = cache_entry->second.resources; | 865 std::vector<ResourceData>& resources = cache_entry->second.resources; |
| 852 for (ResourceRows::iterator it = resources.begin(); | 866 for (auto it = resources.begin(); it != resources.end();) { |
| 853 it != resources.end();) { | 867 if (it->consecutive_misses() >= config_.max_consecutive_misses) |
| 854 it->UpdateScore(); | |
| 855 if (it->consecutive_misses >= config_.max_consecutive_misses) | |
| 856 it = resources.erase(it); | 868 it = resources.erase(it); |
| 857 else | 869 else |
| 858 ++it; | 870 ++it; |
| 859 } | 871 } |
| 860 ResourcePrefetchPredictorTables::SortResourceRows(&resources); | 872 ResourcePrefetchPredictorTables::SortResources(&resources); |
| 861 if (resources.size() > config_.max_resources_per_entry) | 873 if (resources.size() > config_.max_resources_per_entry) |
| 862 resources.resize(config_.max_resources_per_entry); | 874 resources.resize(config_.max_resources_per_entry); |
| 863 | 875 |
| 864 // If the row has no resources, remove it from the cache and delete the | 876 // If the row has no resources, remove it from the cache and delete the |
| 865 // entry in the database. Else update the database. | 877 // entry in the database. Else update the database. |
| 866 if (resources.empty()) { | 878 if (resources.empty()) { |
| 867 data_map->erase(key); | 879 data_map->erase(key); |
| 868 BrowserThread::PostTask( | 880 BrowserThread::PostTask( |
| 869 BrowserThread::DB, FROM_HERE, | 881 BrowserThread::DB, FROM_HERE, |
| 870 base::Bind(&ResourcePrefetchPredictorTables::DeleteSingleDataPoint, | 882 base::Bind(&ResourcePrefetchPredictorTables::DeleteSingleDataPoint, |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 927 // HistoryService is already loaded. Continue with Initialization. | 939 // HistoryService is already loaded. Continue with Initialization. |
| 928 OnHistoryAndCacheLoaded(); | 940 OnHistoryAndCacheLoaded(); |
| 929 return; | 941 return; |
| 930 } | 942 } |
| 931 DCHECK(!history_service_observer_.IsObserving(history_service)); | 943 DCHECK(!history_service_observer_.IsObserving(history_service)); |
| 932 history_service_observer_.Add(history_service); | 944 history_service_observer_.Add(history_service); |
| 933 return; | 945 return; |
| 934 } | 946 } |
| 935 | 947 |
| 936 } // namespace predictors | 948 } // namespace predictors |
| OLD | NEW |