| 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 541 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 552 PopulatePrefetcherRequest(iterator->second, prefetch_requests); | 552 PopulatePrefetcherRequest(iterator->second, prefetch_requests); |
| 553 } | 553 } |
| 554 } | 554 } |
| 555 | 555 |
| 556 return !prefetch_requests->empty(); | 556 return !prefetch_requests->empty(); |
| 557 } | 557 } |
| 558 | 558 |
| 559 void ResourcePrefetchPredictor::PopulatePrefetcherRequest( | 559 void ResourcePrefetchPredictor::PopulatePrefetcherRequest( |
| 560 const PrefetchData& data, | 560 const PrefetchData& data, |
| 561 ResourcePrefetcher::RequestVector* requests) { | 561 ResourcePrefetcher::RequestVector* requests) { |
| 562 for (const ResourceRow& row : data.resources) { | 562 for (const ResourceData& resource : data.resources) { |
| 563 float confidence = static_cast<float>(row.number_of_hits) / | 563 float confidence = |
| 564 (row.number_of_hits + row.number_of_misses); | 564 static_cast<float>(resource.number_of_hits()) / |
| 565 (resource.number_of_hits() + resource.number_of_misses()); |
| 565 if (confidence < config_.min_resource_confidence_to_trigger_prefetch || | 566 if (confidence < config_.min_resource_confidence_to_trigger_prefetch || |
| 566 row.number_of_hits < config_.min_resource_hits_to_trigger_prefetch) { | 567 resource.number_of_hits() < |
| 568 config_.min_resource_hits_to_trigger_prefetch) { |
| 567 continue; | 569 continue; |
| 568 } | 570 } |
| 569 | 571 |
| 570 ResourcePrefetcher::Request* req = | 572 ResourcePrefetcher::Request* req = |
| 571 new ResourcePrefetcher::Request(row.resource_url); | 573 new ResourcePrefetcher::Request(GURL(resource.resource_url())); |
| 572 requests->push_back(req); | 574 requests->push_back(req); |
| 573 } | 575 } |
| 574 } | 576 } |
| 575 | 577 |
| 576 void ResourcePrefetchPredictor::StartPrefetching( | 578 void ResourcePrefetchPredictor::StartPrefetching( |
| 577 const NavigationID& navigation_id) { | 579 const NavigationID& navigation_id) { |
| 578 if (!prefetch_manager_.get()) // Prefetching not enabled. | 580 if (!prefetch_manager_.get()) // Prefetching not enabled. |
| 579 return; | 581 return; |
| 580 | 582 |
| 581 // Prefer URL based data first. | 583 // Prefer URL based data first. |
| (...skipping 222 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 804 cache_entry = data_map->insert(std::make_pair( | 806 cache_entry = data_map->insert(std::make_pair( |
| 805 key, PrefetchData(key_type, key))).first; | 807 key, PrefetchData(key_type, key))).first; |
| 806 cache_entry->second.last_visit = base::Time::Now(); | 808 cache_entry->second.last_visit = base::Time::Now(); |
| 807 size_t new_resources_size = new_resources.size(); | 809 size_t new_resources_size = new_resources.size(); |
| 808 std::set<GURL> resources_seen; | 810 std::set<GURL> resources_seen; |
| 809 for (size_t i = 0; i < new_resources_size; ++i) { | 811 for (size_t i = 0; i < new_resources_size; ++i) { |
| 810 if (resources_seen.find(new_resources[i].resource_url) != | 812 if (resources_seen.find(new_resources[i].resource_url) != |
| 811 resources_seen.end()) { | 813 resources_seen.end()) { |
| 812 continue; | 814 continue; |
| 813 } | 815 } |
| 814 ResourceRow row_to_add; | 816 ResourceData resource_to_add; |
| 815 row_to_add.resource_url = new_resources[i].resource_url; | 817 resource_to_add.set_resource_url(new_resources[i].resource_url.spec()); |
| 816 row_to_add.resource_type = new_resources[i].resource_type; | 818 resource_to_add.set_resource_type(static_cast<ResourceData::ResourceType>( |
| 817 row_to_add.number_of_hits = 1; | 819 new_resources[i].resource_type)); |
| 818 row_to_add.average_position = i + 1; | 820 resource_to_add.set_number_of_hits(1); |
| 819 row_to_add.priority = new_resources[i].priority; | 821 resource_to_add.set_average_position(i + 1); |
| 820 row_to_add.has_validators = new_resources[i].has_validators; | 822 resource_to_add.set_priority( |
| 821 row_to_add.always_revalidate = new_resources[i].always_revalidate; | 823 static_cast<ResourceData::Priority>(new_resources[i].priority)); |
| 822 cache_entry->second.resources.push_back(row_to_add); | 824 resource_to_add.set_has_validators(new_resources[i].has_validators); |
| 825 resource_to_add.set_always_revalidate(new_resources[i].always_revalidate); |
| 826 cache_entry->second.resources.push_back(resource_to_add); |
| 823 resources_seen.insert(new_resources[i].resource_url); | 827 resources_seen.insert(new_resources[i].resource_url); |
| 824 } | 828 } |
| 825 } else { | 829 } else { |
| 826 ResourceRows& old_resources = cache_entry->second.resources; | 830 std::vector<ResourceData>& old_resources = cache_entry->second.resources; |
| 827 cache_entry->second.last_visit = base::Time::Now(); | 831 cache_entry->second.last_visit = base::Time::Now(); |
| 828 | 832 |
| 829 // Build indices over the data. | 833 // Build indices over the data. |
| 830 std::map<GURL, int> new_index, old_index; | 834 std::map<GURL, int> new_index, old_index; |
| 831 int new_resources_size = static_cast<int>(new_resources.size()); | 835 int new_resources_size = static_cast<int>(new_resources.size()); |
| 832 for (int i = 0; i < new_resources_size; ++i) { | 836 for (int i = 0; i < new_resources_size; ++i) { |
| 833 const URLRequestSummary& summary = new_resources[i]; | 837 const URLRequestSummary& summary = new_resources[i]; |
| 834 // Take the first occurence of every url. | 838 // Take the first occurence of every url. |
| 835 if (new_index.find(summary.resource_url) == new_index.end()) | 839 if (new_index.find(summary.resource_url) == new_index.end()) |
| 836 new_index[summary.resource_url] = i; | 840 new_index[summary.resource_url] = i; |
| 837 } | 841 } |
| 838 int old_resources_size = static_cast<int>(old_resources.size()); | 842 int old_resources_size = static_cast<int>(old_resources.size()); |
| 839 for (int i = 0; i < old_resources_size; ++i) { | 843 for (int i = 0; i < old_resources_size; ++i) { |
| 840 const ResourceRow& row = old_resources[i]; | 844 const ResourceData& resource = old_resources[i]; |
| 841 DCHECK(old_index.find(row.resource_url) == old_index.end()); | 845 GURL resource_url(resource.resource_url()); |
| 842 old_index[row.resource_url] = i; | 846 DCHECK(old_index.find(resource_url) == old_index.end()); |
| 847 old_index[resource_url] = i; |
| 843 } | 848 } |
| 844 | 849 |
| 845 // Go through the old urls and update their hit/miss counts. | 850 // Go through the old urls and update their hit/miss counts. |
| 846 for (int i = 0; i < old_resources_size; ++i) { | 851 for (int i = 0; i < old_resources_size; ++i) { |
| 847 ResourceRow& old_row = old_resources[i]; | 852 ResourceData& old_resource = old_resources[i]; |
| 848 if (new_index.find(old_row.resource_url) == new_index.end()) { | 853 GURL resource_url(old_resource.resource_url()); |
| 849 ++old_row.number_of_misses; | 854 if (new_index.find(resource_url) == new_index.end()) { |
| 850 ++old_row.consecutive_misses; | 855 old_resource.set_number_of_misses(old_resource.number_of_misses() + 1); |
| 856 old_resource.set_consecutive_misses(old_resource.consecutive_misses() + |
| 857 1); |
| 851 } else { | 858 } else { |
| 852 const URLRequestSummary& new_row = | 859 const URLRequestSummary& new_summary = |
| 853 new_resources[new_index[old_row.resource_url]]; | 860 new_resources[new_index[resource_url]]; |
| 854 | 861 |
| 855 // Update the resource type since it could have changed. | 862 // Update the resource type since it could have changed. |
| 856 if (new_row.resource_type != content::RESOURCE_TYPE_LAST_TYPE) | 863 if (new_summary.resource_type != content::RESOURCE_TYPE_LAST_TYPE) |
| 857 old_row.resource_type = new_row.resource_type; | 864 old_resource.set_resource_type( |
| 865 static_cast<ResourceData::ResourceType>( |
| 866 new_summary.resource_type)); |
| 858 | 867 |
| 859 old_row.priority = new_row.priority; | 868 old_resource.set_priority( |
| 869 static_cast<ResourceData::Priority>(new_summary.priority)); |
| 860 | 870 |
| 861 int position = new_index[old_row.resource_url] + 1; | 871 int position = new_index[resource_url] + 1; |
| 862 int total = old_row.number_of_hits + old_row.number_of_misses; | 872 int total = |
| 863 old_row.average_position = | 873 old_resource.number_of_hits() + old_resource.number_of_misses(); |
| 864 ((old_row.average_position * total) + position) / (total + 1); | 874 old_resource.set_average_position( |
| 865 ++old_row.number_of_hits; | 875 ((old_resource.average_position() * total) + position) / |
| 866 old_row.consecutive_misses = 0; | 876 (total + 1)); |
| 877 old_resource.set_number_of_hits(old_resource.number_of_hits() + 1); |
| 878 old_resource.set_consecutive_misses(0); |
| 867 } | 879 } |
| 868 } | 880 } |
| 869 | 881 |
| 870 // Add the new ones that we have not seen before. | 882 // Add the new ones that we have not seen before. |
| 871 for (int i = 0; i < new_resources_size; ++i) { | 883 for (int i = 0; i < new_resources_size; ++i) { |
| 872 const URLRequestSummary& summary = new_resources[i]; | 884 const URLRequestSummary& summary = new_resources[i]; |
| 873 if (old_index.find(summary.resource_url) != old_index.end()) | 885 if (old_index.find(summary.resource_url) != old_index.end()) |
| 874 continue; | 886 continue; |
| 875 | 887 |
| 876 // Only need to add new stuff. | 888 // Only need to add new stuff. |
| 877 ResourceRow row_to_add; | 889 ResourceData resource_to_add; |
| 878 row_to_add.resource_url = summary.resource_url; | 890 resource_to_add.set_resource_url(summary.resource_url.spec()); |
| 879 row_to_add.resource_type = summary.resource_type; | 891 resource_to_add.set_resource_type( |
| 880 row_to_add.number_of_hits = 1; | 892 static_cast<ResourceData::ResourceType>(summary.resource_type)); |
| 881 row_to_add.average_position = i + 1; | 893 resource_to_add.set_number_of_hits(1); |
| 882 row_to_add.priority = summary.priority; | 894 resource_to_add.set_average_position(i + 1); |
| 883 row_to_add.has_validators = new_resources[i].has_validators; | 895 resource_to_add.set_priority( |
| 884 row_to_add.always_revalidate = new_resources[i].always_revalidate; | 896 static_cast<ResourceData::Priority>(summary.priority)); |
| 885 old_resources.push_back(row_to_add); | 897 resource_to_add.set_has_validators(new_resources[i].has_validators); |
| 898 resource_to_add.set_always_revalidate(new_resources[i].always_revalidate); |
| 899 old_resources.push_back(resource_to_add); |
| 886 | 900 |
| 887 // To ensure we dont add the same url twice. | 901 // To ensure we dont add the same url twice. |
| 888 old_index[summary.resource_url] = 0; | 902 old_index[summary.resource_url] = 0; |
| 889 } | 903 } |
| 890 } | 904 } |
| 891 | 905 |
| 892 // Trim and sort the resources after the update. | 906 // Trim and sort the resources after the update. |
| 893 ResourceRows& resources = cache_entry->second.resources; | 907 std::vector<ResourceData>& resources = cache_entry->second.resources; |
| 894 for (ResourceRows::iterator it = resources.begin(); | 908 for (auto it = resources.begin(); it != resources.end();) { |
| 895 it != resources.end();) { | 909 if (it->consecutive_misses() >= config_.max_consecutive_misses) |
| 896 it->UpdateScore(); | |
| 897 if (it->consecutive_misses >= config_.max_consecutive_misses) | |
| 898 it = resources.erase(it); | 910 it = resources.erase(it); |
| 899 else | 911 else |
| 900 ++it; | 912 ++it; |
| 901 } | 913 } |
| 902 ResourcePrefetchPredictorTables::SortResourceRows(&resources); | 914 ResourcePrefetchPredictorTables::SortResources(&resources); |
| 903 if (resources.size() > config_.max_resources_per_entry) | 915 if (resources.size() > config_.max_resources_per_entry) |
| 904 resources.resize(config_.max_resources_per_entry); | 916 resources.resize(config_.max_resources_per_entry); |
| 905 | 917 |
| 906 // If the row has no resources, remove it from the cache and delete the | 918 // If the row has no resources, remove it from the cache and delete the |
| 907 // entry in the database. Else update the database. | 919 // entry in the database. Else update the database. |
| 908 if (resources.empty()) { | 920 if (resources.empty()) { |
| 909 data_map->erase(key); | 921 data_map->erase(key); |
| 910 BrowserThread::PostTask( | 922 BrowserThread::PostTask( |
| 911 BrowserThread::DB, FROM_HERE, | 923 BrowserThread::DB, FROM_HERE, |
| 912 base::Bind(&ResourcePrefetchPredictorTables::DeleteSingleDataPoint, | 924 base::Bind(&ResourcePrefetchPredictorTables::DeleteSingleDataPoint, |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 969 // HistoryService is already loaded. Continue with Initialization. | 981 // HistoryService is already loaded. Continue with Initialization. |
| 970 OnHistoryAndCacheLoaded(); | 982 OnHistoryAndCacheLoaded(); |
| 971 return; | 983 return; |
| 972 } | 984 } |
| 973 DCHECK(!history_service_observer_.IsObserving(history_service)); | 985 DCHECK(!history_service_observer_.IsObserving(history_service)); |
| 974 history_service_observer_.Add(history_service); | 986 history_service_observer_.Add(history_service); |
| 975 return; | 987 return; |
| 976 } | 988 } |
| 977 | 989 |
| 978 } // namespace predictors | 990 } // namespace predictors |
| OLD | NEW |