Index: chrome/browser/net/predictor.cc |
=================================================================== |
--- chrome/browser/net/predictor.cc (revision 54027) |
+++ chrome/browser/net/predictor.cc (working copy) |
@@ -26,6 +26,14 @@ |
namespace chrome_browser_net { |
+// static |
+const double Predictor::kPreconnectWorthyExpectedValue = 0.7; |
+// static |
+const double Predictor::kDNSPreresolutionWorthyExpectedValue = 0.2; |
+// static |
+const double Predictor::kPersistWorthyExpectedValue = 0.1; |
+ |
+ |
class Predictor::LookupRequest { |
public: |
LookupRequest(Predictor* predictor, |
@@ -118,60 +126,6 @@ |
AppendToResolutionQueue(url, motivation); |
} |
-bool Predictor::AccruePrefetchBenefits(const GURL& referrer, |
- UrlInfo* navigation_info) { |
- DCHECK(ChromeThread::CurrentlyOn(ChromeThread::IO)); |
- GURL url = navigation_info->url(); |
- Results::iterator it = results_.find(url); |
- if (it == results_.end()) { |
- // Use UMA histogram to quantify potential future gains here. |
- UMA_HISTOGRAM_LONG_TIMES("DNS.UnexpectedResolutionL", |
- navigation_info->resolve_duration()); |
- navigation_info->DLogResultsStats("DNS UnexpectedResolution"); |
- |
- LearnFromNavigation(referrer, navigation_info->url()); |
- return false; |
- } |
- UrlInfo& prefetched_host_info(it->second); |
- |
- // Sometimes a host is used as a subresource by several referrers, so it is |
- // in our list, but was never motivated by a page-link-scan. In that case, it |
- // really is an "unexpected" navigation, and we should tally it, and augment |
- // our referrers_. |
- bool referrer_based_prefetch = !prefetched_host_info.was_linked(); |
- if (referrer_based_prefetch) { |
- // This wasn't the first time this host refered to *some* referrer. |
- LearnFromNavigation(referrer, navigation_info->url()); |
- } |
- |
- DnsBenefit benefit = prefetched_host_info.AccruePrefetchBenefits( |
- navigation_info); |
- switch (benefit) { |
- case PREFETCH_NAME_FOUND: |
- case PREFETCH_NAME_NONEXISTANT: |
- dns_cache_hits_.push_back(*navigation_info); |
- if (referrer_based_prefetch) { |
- if (referrer.has_host()) { |
- referrers_[referrer].AccrueValue( |
- navigation_info->benefits_remaining(), url); |
- } |
- } |
- return true; |
- |
- case PREFETCH_CACHE_EVICTION: |
- cache_eviction_map_[url] = *navigation_info; |
- return false; |
- |
- case PREFETCH_NO_BENEFIT: |
- // Prefetch never hit the network. Name was pre-cached. |
- return false; |
- |
- default: |
- NOTREACHED(); |
- return false; |
- } |
-} |
- |
void Predictor::LearnFromNavigation(const GURL& referring_url, |
const GURL& target_url) { |
DCHECK(ChromeThread::CurrentlyOn(ChromeThread::IO)); |
@@ -182,22 +136,12 @@ |
} |
} |
-void Predictor::PredictSubresources(const GURL& url) { |
- DCHECK(ChromeThread::CurrentlyOn(ChromeThread::IO)); |
- Referrers::iterator it = referrers_.find(url); |
- if (referrers_.end() == it) |
- return; |
- Referrer* referrer = &(it->second); |
- referrer->IncrementUseCount(); |
- for (Referrer::iterator future_url = referrer->begin(); |
- future_url != referrer->end(); ++future_url) { |
- UrlInfo* queued_info = AppendToResolutionQueue( |
- future_url->first, |
- UrlInfo::LEARNED_REFERAL_MOTIVATED); |
- if (queued_info) |
- queued_info->SetReferringHostname(url); |
- } |
-} |
+enum SubresourceValue { |
+ PRECONNECTION, |
+ PRERESOLUTION, |
+ TOO_NEW, |
+ SUBRESOURCE_VALUE_MAX |
+}; |
void Predictor::PredictFrameSubresources(const GURL& url) { |
DCHECK(ChromeThread::CurrentlyOn(ChromeThread::IO)); |
@@ -207,19 +151,36 @@ |
return; |
Referrer* referrer = &(it->second); |
referrer->IncrementUseCount(); |
+ const UrlInfo::ResolutionMotivation motivation = |
+ UrlInfo::LEARNED_REFERAL_MOTIVATED; |
for (Referrer::iterator future_url = referrer->begin(); |
future_url != referrer->end(); ++future_url) { |
- if (future_url->second.IsPreconnectWorthDoing()) |
- Preconnect::PreconnectOnIOThread(future_url->first); |
+ SubresourceValue evalution(TOO_NEW); |
+ double connection_expectation = future_url->second.subresource_use_rate(); |
+ UMA_HISTOGRAM_CUSTOM_COUNTS("Net.PreconnectSubresourceExpectation", |
+ static_cast<int>(connection_expectation * 100), |
+ 10, 5000, 50); |
+ future_url->second.ReferrerWasObserved(); |
+ if (preconnect_enabled_ && |
+ kPreconnectWorthyExpectedValue < connection_expectation) { |
+ evalution = PRECONNECTION; |
+ future_url->second.IncrementPreconnectionCount(); |
+ Preconnect::PreconnectOnIOThread(future_url->first, motivation); |
+ } else if (kDNSPreresolutionWorthyExpectedValue < connection_expectation) { |
+ evalution = PRERESOLUTION; |
+ future_url->second.preresolution_increment(); |
+ UrlInfo* queued_info = AppendToResolutionQueue(future_url->first, |
+ motivation); |
+ if (queued_info) |
+ queued_info->SetReferringHostname(url); |
+ } |
+ UMA_HISTOGRAM_ENUMERATION("Net.PreconnectSubresourceEval", evalution, |
+ SUBRESOURCE_VALUE_MAX); |
} |
} |
// Provide sort order so all .com's are together, etc. |
struct RightToLeftStringSorter { |
- bool operator()(const net::HostPortPair& left, |
- const net::HostPortPair& right) const { |
- return string_compare(left.host(), right.host()); |
- } |
bool operator()(const GURL& left, |
const GURL& right) const { |
return string_compare(left.host(), right.host()); |
@@ -301,8 +262,8 @@ |
"<th>Page Load<br>Count</th>" |
"<th>Subresource<br>Navigations</th>" |
"<th>Subresource<br>PreConnects</th>" |
+ "<th>Subresource<br>PreResolves</th>" |
"<th>Expected<br>Connects</th>" |
- "<th>DNS<br>Savings</th>" |
"<th>Subresource Spec</th></tr>"); |
for (SortedNames::iterator it = sorted_names.begin(); |
@@ -320,11 +281,11 @@ |
static_cast<int>(referrer->use_count())); |
first_set_of_futures = false; |
StringAppendF(output, |
- "<td>%d</td><td>%d</td><td>%2.3f</td><td>%dms</td><td>%s</td></tr>", |
+ "<td>%d</td><td>%d</td><td>%d</td><td>%2.3f</td><td>%s</td></tr>", |
static_cast<int>(future_url->second.navigation_count()), |
static_cast<int>(future_url->second.preconnection_count()), |
+ static_cast<int>(future_url->second.preresolution_count()), |
static_cast<double>(future_url->second.subresource_use_rate()), |
- static_cast<int>(future_url->second.latency().InMilliseconds()), |
future_url->first.spec().c_str()); |
} |
} |
@@ -334,53 +295,26 @@ |
void Predictor::GetHtmlInfo(std::string* output) { |
DCHECK(ChromeThread::CurrentlyOn(ChromeThread::IO)); |
// Local lists for calling UrlInfo |
- UrlInfo::DnsInfoTable cache_hits; |
- UrlInfo::DnsInfoTable cache_evictions; |
- UrlInfo::DnsInfoTable name_not_found; |
- UrlInfo::DnsInfoTable network_hits; |
- UrlInfo::DnsInfoTable already_cached; |
+ UrlInfo::UrlInfoTable name_not_found; |
+ UrlInfo::UrlInfoTable name_preresolved; |
// Get copies of all useful data. |
- typedef std::map<GURL, UrlInfo, RightToLeftStringSorter> |
- Snapshot; |
- Snapshot snapshot; |
- { |
- // UrlInfo supports value semantics, so we can do a shallow copy. |
- for (Results::iterator it(results_.begin()); it != results_.end(); it++) { |
- snapshot[it->first] = it->second; |
- } |
- for (Results::iterator it(cache_eviction_map_.begin()); |
- it != cache_eviction_map_.end(); |
- it++) { |
- cache_evictions.push_back(it->second); |
- } |
- // Reverse list as we copy cache hits, so that new hits are at the top. |
- size_t index = dns_cache_hits_.size(); |
- while (index > 0) { |
- index--; |
- cache_hits.push_back(dns_cache_hits_[index]); |
- } |
- } |
+ typedef std::map<GURL, UrlInfo, RightToLeftStringSorter> SortedUrlInfo; |
+ SortedUrlInfo snapshot; |
+ // UrlInfo supports value semantics, so we can do a shallow copy. |
+ for (Results::iterator it(results_.begin()); it != results_.end(); it++) |
+ snapshot[it->first] = it->second; |
// Partition the UrlInfo's into categories. |
- for (Snapshot::iterator it(snapshot.begin()); it != snapshot.end(); it++) { |
+ for (SortedUrlInfo::iterator it(snapshot.begin()); |
+ it != snapshot.end(); it++) { |
if (it->second.was_nonexistant()) { |
name_not_found.push_back(it->second); |
continue; |
} |
if (!it->second.was_found()) |
continue; // Still being processed. |
- if (TimeDelta() != it->second.benefits_remaining()) { |
- network_hits.push_back(it->second); // With no benefit yet. |
- continue; |
- } |
- if (UrlInfo::kMaxNonNetworkDnsLookupDuration > |
- it->second.resolve_duration()) { |
- already_cached.push_back(it->second); |
- continue; |
- } |
- // Remaining case is where prefetch benefit was significant, and was used. |
- // Since we shot those cases as historical hits, we won't bother here. |
+ name_preresolved.push_back(it->second); |
} |
bool brief = false; |
@@ -389,16 +323,10 @@ |
#endif // NDEBUG |
// Call for display of each table, along with title. |
- UrlInfo::GetHtmlTable(cache_hits, |
- "Prefetching DNS records produced benefits for ", false, output); |
- UrlInfo::GetHtmlTable(cache_evictions, |
- "Cache evictions negated DNS prefetching benefits for ", brief, output); |
- UrlInfo::GetHtmlTable(network_hits, |
- "Prefetching DNS records was not yet beneficial for ", brief, output); |
- UrlInfo::GetHtmlTable(already_cached, |
- "Previously cached resolutions were found for ", brief, output); |
+ UrlInfo::GetHtmlTable(name_preresolved, |
+ "Preresolution DNS records performed for ", brief, output); |
UrlInfo::GetHtmlTable(name_not_found, |
- "Prefetching DNS records revealed non-existance for ", brief, output); |
+ "Preresolving DNS records revealed non-existance for ", brief, output); |
} |
UrlInfo* Predictor::AppendToResolutionQueue( |
@@ -507,8 +435,6 @@ |
void Predictor::DiscardAllResults() { |
DCHECK(ChromeThread::CurrentlyOn(ChromeThread::IO)); |
// Delete anything listed so far in this session that shows in about:dns. |
- cache_eviction_map_.clear(); |
- dns_cache_hits_.clear(); |
referrers_.clear(); |
@@ -559,7 +485,7 @@ |
void Predictor::SerializeReferrers(ListValue* referral_list) { |
DCHECK(ChromeThread::CurrentlyOn(ChromeThread::IO)); |
referral_list->Clear(); |
- referral_list->Append(new FundamentalValue(DNS_REFERRER_VERSION)); |
+ referral_list->Append(new FundamentalValue(PREDICTOR_REFERRER_VERSION)); |
for (Referrers::const_iterator it = referrers_.begin(); |
it != referrers_.end(); ++it) { |
// Serialize the list of subresource names. |
@@ -579,7 +505,7 @@ |
int format_version = -1; |
if (referral_list.GetSize() > 0 && |
referral_list.GetInteger(0, &format_version) && |
- format_version == DNS_REFERRER_VERSION) { |
+ format_version == PREDICTOR_REFERRER_VERSION) { |
for (size_t i = 1; i < referral_list.GetSize(); ++i) { |
ListValue* motivator; |
if (!referral_list.GetList(i, &motivator)) { |