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

Side by Side Diff: chrome/browser/net/url_info.cc

Issue 9635018: Remove static initializer in url_info.cc. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Remove const Created 8 years, 9 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 | « chrome/browser/net/url_info.h ('k') | no next file » | 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) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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/net/url_info.h" 5 #include "chrome/browser/net/url_info.h"
6 6
7 #include <ctype.h> 7 #include <ctype.h>
8 #include <math.h> 8 #include <math.h>
9 9
10 #include <algorithm> 10 #include <algorithm>
11 #include <string> 11 #include <string>
12 12
13 #include "base/format_macros.h" 13 #include "base/format_macros.h"
14 #include "base/lazy_instance.h"
14 #include "base/logging.h" 15 #include "base/logging.h"
15 #include "base/metrics/histogram.h" 16 #include "base/metrics/histogram.h"
16 #include "base/stringprintf.h" 17 #include "base/stringprintf.h"
17 18
18 using base::Time; 19 using base::Time;
19 using base::TimeDelta; 20 using base::TimeDelta;
20 using base::TimeTicks; 21 using base::TimeTicks;
21 22
22 namespace chrome_browser_net { 23 namespace chrome_browser_net {
23 24
24 static bool detailed_logging_enabled = false; 25 namespace {
26
27 // The number of OS cache entries we can guarantee(?) before cache eviction
28 // might likely take place.
29 const int kMaxGuaranteedDnsCacheSize = 50;
30
31 // Common low end TTL for sites is 5 minutes. However, DNS servers give us the
32 // remaining time, not the original 5 minutes. Hence it doesn't much matter
33 // whether we found something in the local cache, or an ISP cache, it will on
34 // average be 2.5 minutes before it expires. We could try to model this with
35 // 180 seconds, but simpler is just to do the lookups all the time (wasting OS
36 // calls(?)), and let that OS cache decide what to do (with TTL in hand). We
37 // use a small time to help get some duplicate suppression, in case a page has
38 // a TON of copies of the same domain name, so that we don't thrash the OS to
39 // death. Hopefully it is small enough that we're not hurting our cache hit
40 // rate (i.e., we could always ask the OS).
41 const int kDefaultCacheExpirationDuration = 5;
42
43 TimeDelta MaxNonNetworkDnsLookupDuration() {
44 return TimeDelta::FromMilliseconds(15);
45 }
46
47 bool detailed_logging_enabled = false;
48
49 struct GlobalState {
50 GlobalState() {
51 cache_expiration_duration =
52 TimeDelta::FromSeconds(kDefaultCacheExpirationDuration);
53 }
54 TimeDelta cache_expiration_duration;
55 };
56
57 base::LazyInstance<GlobalState>::Leaky global_state;
58
59 } // anonymous namespace
25 60
26 // Use command line switch to enable detailed logging. 61 // Use command line switch to enable detailed logging.
27 void EnablePredictorDetailedLog(bool enable) { 62 void EnablePredictorDetailedLog(bool enable) {
28 detailed_logging_enabled = enable; 63 detailed_logging_enabled = enable;
29 } 64 }
30 65
31 // static 66 // static
32 int UrlInfo::sequence_counter = 1; 67 int UrlInfo::sequence_counter = 1;
33 68
34 UrlInfo::UrlInfo() 69 UrlInfo::UrlInfo()
35 : state_(PENDING), 70 : state_(PENDING),
36 old_prequeue_state_(state_), 71 old_prequeue_state_(state_),
37 resolve_duration_(kNullDuration), 72 resolve_duration_(NullDuration()),
38 queue_duration_(kNullDuration), 73 queue_duration_(NullDuration()),
39 sequence_number_(0), 74 sequence_number_(0),
40 motivation_(NO_PREFETCH_MOTIVATION), 75 motivation_(NO_PREFETCH_MOTIVATION),
41 was_linked_(false) { 76 was_linked_(false) {
42 } 77 }
43 78
44 UrlInfo::~UrlInfo() {} 79 UrlInfo::~UrlInfo() {}
45 80
46 bool UrlInfo::NeedsDnsUpdate() { 81 bool UrlInfo::NeedsDnsUpdate() {
47 switch (state_) { 82 switch (state_) {
48 case PENDING: // Just now created info. 83 case PENDING: // Just now created info.
49 return true; 84 return true;
50 85
51 case QUEUED: // In queue. 86 case QUEUED: // In queue.
52 case ASSIGNED: // It's being resolved. 87 case ASSIGNED: // It's being resolved.
53 case ASSIGNED_BUT_MARKED: // It's being resolved. 88 case ASSIGNED_BUT_MARKED: // It's being resolved.
54 return false; // We're already working on it 89 return false; // We're already working on it
55 90
56 case NO_SUCH_NAME: // Lookup failed. 91 case NO_SUCH_NAME: // Lookup failed.
57 case FOUND: // Lookup succeeded. 92 case FOUND: // Lookup succeeded.
58 return !IsStillCached(); // See if DNS cache expired. 93 return !IsStillCached(); // See if DNS cache expired.
59 94
60 default: 95 default:
61 NOTREACHED(); 96 NOTREACHED();
62 return false; 97 return false;
63 } 98 }
64 } 99 }
65 100
66 const TimeDelta UrlInfo::kNullDuration(TimeDelta::FromMilliseconds(-1)); 101 // Used by test ONLY. The value is otherwise constant.
67
68 // Common low end TTL for sites is 5 minutes. However, DNS servers give us
69 // the remaining time, not the original 5 minutes. Hence it doesn't much matter
70 // whether we found something in the local cache, or an ISP cache, it will
71 // on average be 2.5 minutes before it expires. We could try to model this with
72 // 180 seconds, but simpler is just to do the lookups all the time (wasting
73 // OS calls(?)), and let that OS cache decide what to do (with TTL in hand).
74 // We use a small time to help get some duplicate suppression, in case a page
75 // has a TON of copies of the same domain name, so that we don't thrash the OS
76 // to death. Hopefully it is small enough that we're not hurting our cache hit
77 // rate (i.e., we could always ask the OS).
78 TimeDelta UrlInfo::cache_expiration_duration_(TimeDelta::FromSeconds(5));
79
80 const TimeDelta UrlInfo::kMaxNonNetworkDnsLookupDuration(
81 TimeDelta::FromMilliseconds(15));
82
83 // Used by test ONLY. The value is otherwise constant.
84 // static 102 // static
85 void UrlInfo::set_cache_expiration(TimeDelta time) { 103 void UrlInfo::set_cache_expiration(TimeDelta time) {
86 cache_expiration_duration_ = time; 104 global_state.Pointer()->cache_expiration_duration = time;
87 } 105 }
88 106
89 // static 107 // static
90 TimeDelta UrlInfo::get_cache_expiration() { 108 TimeDelta UrlInfo::get_cache_expiration() {
91 return cache_expiration_duration_; 109 return global_state.Get().cache_expiration_duration;
92 } 110 }
93 111
94 void UrlInfo::SetQueuedState(ResolutionMotivation motivation) { 112 void UrlInfo::SetQueuedState(ResolutionMotivation motivation) {
95 DCHECK(PENDING == state_ || FOUND == state_ || NO_SUCH_NAME == state_); 113 DCHECK(PENDING == state_ || FOUND == state_ || NO_SUCH_NAME == state_);
96 old_prequeue_state_ = state_; 114 old_prequeue_state_ = state_;
97 state_ = QUEUED; 115 state_ = QUEUED;
98 queue_duration_ = resolve_duration_ = kNullDuration; 116 queue_duration_ = resolve_duration_ = NullDuration();
99 SetMotivation(motivation); 117 SetMotivation(motivation);
100 GetDuration(); // Set time_ 118 GetDuration(); // Set time_
101 DLogResultsStats("DNS Prefetch in queue"); 119 DLogResultsStats("DNS Prefetch in queue");
102 } 120 }
103 121
104 void UrlInfo::SetAssignedState() { 122 void UrlInfo::SetAssignedState() {
105 DCHECK(QUEUED == state_); 123 DCHECK(QUEUED == state_);
106 state_ = ASSIGNED; 124 state_ = ASSIGNED;
107 queue_duration_ = GetDuration(); 125 queue_duration_ = GetDuration();
108 DLogResultsStats("DNS Prefetch assigned"); 126 DLogResultsStats("DNS Prefetch assigned");
109 UMA_HISTOGRAM_TIMES("DNS.PrefetchQueue", queue_duration_); 127 UMA_HISTOGRAM_TIMES("DNS.PrefetchQueue", queue_duration_);
110 } 128 }
111 129
112 void UrlInfo::RemoveFromQueue() { 130 void UrlInfo::RemoveFromQueue() {
113 DCHECK(ASSIGNED == state_); 131 DCHECK(ASSIGNED == state_);
114 state_ = old_prequeue_state_; 132 state_ = old_prequeue_state_;
115 DLogResultsStats("DNS Prefetch reset to prequeue"); 133 DLogResultsStats("DNS Prefetch reset to prequeue");
116 static const TimeDelta kBoundary = TimeDelta::FromSeconds(2); 134 const TimeDelta kBoundary = TimeDelta::FromSeconds(2);
117 if (queue_duration_ > kBoundary) { 135 if (queue_duration_ > kBoundary) {
118 UMA_HISTOGRAM_MEDIUM_TIMES("DNS.QueueRecycledDeltaOver2", 136 UMA_HISTOGRAM_MEDIUM_TIMES("DNS.QueueRecycledDeltaOver2",
119 queue_duration_ - kBoundary); 137 queue_duration_ - kBoundary);
120 return; 138 return;
121 } 139 }
122 // Make a custom linear histogram for the region from 0 to boundary. 140 // Make a custom linear histogram for the region from 0 to boundary.
123 const size_t kBucketCount = 52; 141 static const size_t kBucketCount = 52;
124 static base::Histogram* histogram(NULL); 142 static base::Histogram* histogram(NULL);
125 if (!histogram) 143 if (!histogram)
126 histogram = base::LinearHistogram::FactoryTimeGet( 144 histogram = base::LinearHistogram::FactoryTimeGet(
127 "DNS.QueueRecycledUnder2", TimeDelta(), kBoundary, kBucketCount, 145 "DNS.QueueRecycledUnder2", TimeDelta(), kBoundary, kBucketCount,
128 base::Histogram::kUmaTargetedHistogramFlag); 146 base::Histogram::kUmaTargetedHistogramFlag);
129 histogram->AddTime(queue_duration_); 147 histogram->AddTime(queue_duration_);
130 } 148 }
131 149
132 void UrlInfo::SetPendingDeleteState() { 150 void UrlInfo::SetPendingDeleteState() {
133 DCHECK(ASSIGNED == state_ || ASSIGNED_BUT_MARKED == state_); 151 DCHECK(ASSIGNED == state_ || ASSIGNED_BUT_MARKED == state_);
134 state_ = ASSIGNED_BUT_MARKED; 152 state_ = ASSIGNED_BUT_MARKED;
135 } 153 }
136 154
137 void UrlInfo::SetFoundState() { 155 void UrlInfo::SetFoundState() {
138 DCHECK(ASSIGNED == state_); 156 DCHECK(ASSIGNED == state_);
139 state_ = FOUND; 157 state_ = FOUND;
140 resolve_duration_ = GetDuration(); 158 resolve_duration_ = GetDuration();
141 if (kMaxNonNetworkDnsLookupDuration <= resolve_duration_) { 159 const TimeDelta max_duration = MaxNonNetworkDnsLookupDuration();
160 if (max_duration <= resolve_duration_) {
142 UMA_HISTOGRAM_CUSTOM_TIMES("DNS.PrefetchResolution", resolve_duration_, 161 UMA_HISTOGRAM_CUSTOM_TIMES("DNS.PrefetchResolution", resolve_duration_,
143 kMaxNonNetworkDnsLookupDuration, TimeDelta::FromMinutes(15), 100); 162 max_duration, TimeDelta::FromMinutes(15), 100);
144 } 163 }
145 sequence_number_ = sequence_counter++; 164 sequence_number_ = sequence_counter++;
146 DLogResultsStats("DNS PrefetchFound"); 165 DLogResultsStats("DNS PrefetchFound");
147 } 166 }
148 167
149 void UrlInfo::SetNoSuchNameState() { 168 void UrlInfo::SetNoSuchNameState() {
150 DCHECK(ASSIGNED == state_); 169 DCHECK(ASSIGNED == state_);
151 state_ = NO_SUCH_NAME; 170 state_ = NO_SUCH_NAME;
152 resolve_duration_ = GetDuration(); 171 resolve_duration_ = GetDuration();
153 if (kMaxNonNetworkDnsLookupDuration <= resolve_duration_) { 172 if (MaxNonNetworkDnsLookupDuration() <= resolve_duration_) {
154 DHISTOGRAM_TIMES("DNS.PrefetchNotFoundName", resolve_duration_); 173 DHISTOGRAM_TIMES("DNS.PrefetchNotFoundName", resolve_duration_);
155 } 174 }
156 sequence_number_ = sequence_counter++; 175 sequence_number_ = sequence_counter++;
157 DLogResultsStats("DNS PrefetchNotFound"); 176 DLogResultsStats("DNS PrefetchNotFound");
158 } 177 }
159 178
160 void UrlInfo::SetUrl(const GURL& url) { 179 void UrlInfo::SetUrl(const GURL& url) {
161 if (url_.is_empty()) // Not yet initialized. 180 if (url_.is_empty()) // Not yet initialized.
162 url_ = url; 181 url_ = url;
163 else 182 else
164 DCHECK_EQ(url_, url); 183 DCHECK_EQ(url_, url);
165 } 184 }
166 185
167 // IsStillCached() guesses if the DNS cache still has IP data, 186 // IsStillCached() guesses if the DNS cache still has IP data,
168 // or at least remembers results about "not finding host." 187 // or at least remembers results about "not finding host."
169 bool UrlInfo::IsStillCached() const { 188 bool UrlInfo::IsStillCached() const {
170 DCHECK(FOUND == state_ || NO_SUCH_NAME == state_); 189 DCHECK(FOUND == state_ || NO_SUCH_NAME == state_);
171 190
172 // Default MS OS does not cache failures. Hence we could return false almost 191 // Default MS OS does not cache failures. Hence we could return false almost
173 // all the time for that case. However, we'd never try again to prefetch 192 // all the time for that case. However, we'd never try again to prefetch
174 // the value if we returned false that way. Hence we'll just let the lookup 193 // the value if we returned false that way. Hence we'll just let the lookup
175 // time out the same way as FOUND case. 194 // time out the same way as FOUND case.
176 195
177 if (sequence_counter - sequence_number_ > kMaxGuaranteedDnsCacheSize) 196 if (sequence_counter - sequence_number_ > kMaxGuaranteedDnsCacheSize)
178 return false; 197 return false;
179 198
180 TimeDelta time_since_resolution = TimeTicks::Now() - time_; 199 TimeDelta time_since_resolution = TimeTicks::Now() - time_;
181 200 return time_since_resolution < global_state.Get().cache_expiration_duration;
182 return time_since_resolution < cache_expiration_duration_;
183 } 201 }
184 202
185 void UrlInfo::DLogResultsStats(const char* message) const { 203 void UrlInfo::DLogResultsStats(const char* message) const {
186 if (!detailed_logging_enabled) 204 if (!detailed_logging_enabled)
187 return; 205 return;
188 DVLOG(1) << "\t" << message << "\tq=" << queue_duration().InMilliseconds() 206 DVLOG(1) << "\t" << message << "\tq=" << queue_duration().InMilliseconds()
189 << "ms,\tr=" << resolve_duration().InMilliseconds() 207 << "ms,\tr=" << resolve_duration().InMilliseconds()
190 << "ms,\tp=" << sequence_number_ << "\t" << url_.spec(); 208 << "ms,\tp=" << sequence_number_ << "\t" << url_.spec();
191 } 209 }
192 210
(...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after
341 359
342 case LEARNED_REFERAL_MOTIVATED: 360 case LEARNED_REFERAL_MOTIVATED:
343 return RemoveJs(referring_url_.spec()); 361 return RemoveJs(referring_url_.spec());
344 362
345 default: 363 default:
346 return ""; 364 return "";
347 } 365 }
348 } 366 }
349 367
350 } // namespace chrome_browser_net 368 } // namespace chrome_browser_net
OLDNEW
« no previous file with comments | « chrome/browser/net/url_info.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698