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

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: 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 TimeDelta cache_expiration_duration;
51 };
52
53 struct InitializeGlobalState {
54 static const bool kRegisterOnExit = false;
55 static const bool kAllowedToAccessOnNonjoinableThread = true;
56
57 static GlobalState* New(void* instance) {
battre 2012/03/08 18:48:43 Is this necessary? Could you not just use a constr
Philippe 2012/03/09 08:48:09 Indeed. I don't know how I managed to come up with
58 GlobalState* const global = new(instance) GlobalState();
59 global->cache_expiration_duration =
60 TimeDelta::FromSeconds(kDefaultCacheExpirationDuration);
61 return global;
62 }
63
64 static void Delete(GlobalState* /* instance */) { /* Leaky */ }
65 };
66
67 base::LazyInstance<GlobalState, InitializeGlobalState> global_state;
68
69 } // anonymous namespace
25 70
26 // Use command line switch to enable detailed logging. 71 // Use command line switch to enable detailed logging.
27 void EnablePredictorDetailedLog(bool enable) { 72 void EnablePredictorDetailedLog(bool enable) {
28 detailed_logging_enabled = enable; 73 detailed_logging_enabled = enable;
29 } 74 }
30 75
31 // static 76 // static
32 int UrlInfo::sequence_counter = 1; 77 int UrlInfo::sequence_counter = 1;
33 78
34 UrlInfo::UrlInfo() 79 UrlInfo::UrlInfo()
35 : state_(PENDING), 80 : state_(PENDING),
36 old_prequeue_state_(state_), 81 old_prequeue_state_(state_),
37 resolve_duration_(kNullDuration), 82 resolve_duration_(NullDuration()),
38 queue_duration_(kNullDuration), 83 queue_duration_(NullDuration()),
39 sequence_number_(0), 84 sequence_number_(0),
40 motivation_(NO_PREFETCH_MOTIVATION), 85 motivation_(NO_PREFETCH_MOTIVATION),
41 was_linked_(false) { 86 was_linked_(false) {
42 } 87 }
43 88
44 UrlInfo::~UrlInfo() {} 89 UrlInfo::~UrlInfo() {}
45 90
46 bool UrlInfo::NeedsDnsUpdate() { 91 bool UrlInfo::NeedsDnsUpdate() {
47 switch (state_) { 92 switch (state_) {
48 case PENDING: // Just now created info. 93 case PENDING: // Just now created info.
49 return true; 94 return true;
50 95
51 case QUEUED: // In queue. 96 case QUEUED: // In queue.
52 case ASSIGNED: // It's being resolved. 97 case ASSIGNED: // It's being resolved.
53 case ASSIGNED_BUT_MARKED: // It's being resolved. 98 case ASSIGNED_BUT_MARKED: // It's being resolved.
54 return false; // We're already working on it 99 return false; // We're already working on it
55 100
56 case NO_SUCH_NAME: // Lookup failed. 101 case NO_SUCH_NAME: // Lookup failed.
57 case FOUND: // Lookup succeeded. 102 case FOUND: // Lookup succeeded.
58 return !IsStillCached(); // See if DNS cache expired. 103 return !IsStillCached(); // See if DNS cache expired.
59 104
60 default: 105 default:
61 NOTREACHED(); 106 NOTREACHED();
62 return false; 107 return false;
63 } 108 }
64 } 109 }
65 110
66 const TimeDelta UrlInfo::kNullDuration(TimeDelta::FromMilliseconds(-1)); 111 // 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 112 // static
85 void UrlInfo::set_cache_expiration(TimeDelta time) { 113 void UrlInfo::set_cache_expiration(TimeDelta time) {
86 cache_expiration_duration_ = time; 114 global_state.Pointer()->cache_expiration_duration = time;
87 } 115 }
88 116
89 // static 117 // static
90 TimeDelta UrlInfo::get_cache_expiration() { 118 TimeDelta UrlInfo::get_cache_expiration() {
91 return cache_expiration_duration_; 119 return global_state.Get().cache_expiration_duration;
92 } 120 }
93 121
94 void UrlInfo::SetQueuedState(ResolutionMotivation motivation) { 122 void UrlInfo::SetQueuedState(ResolutionMotivation motivation) {
95 DCHECK(PENDING == state_ || FOUND == state_ || NO_SUCH_NAME == state_); 123 DCHECK(PENDING == state_ || FOUND == state_ || NO_SUCH_NAME == state_);
96 old_prequeue_state_ = state_; 124 old_prequeue_state_ = state_;
97 state_ = QUEUED; 125 state_ = QUEUED;
98 queue_duration_ = resolve_duration_ = kNullDuration; 126 queue_duration_ = resolve_duration_ = NullDuration();
99 SetMotivation(motivation); 127 SetMotivation(motivation);
100 GetDuration(); // Set time_ 128 GetDuration(); // Set time_
101 DLogResultsStats("DNS Prefetch in queue"); 129 DLogResultsStats("DNS Prefetch in queue");
102 } 130 }
103 131
104 void UrlInfo::SetAssignedState() { 132 void UrlInfo::SetAssignedState() {
105 DCHECK(QUEUED == state_); 133 DCHECK(QUEUED == state_);
106 state_ = ASSIGNED; 134 state_ = ASSIGNED;
107 queue_duration_ = GetDuration(); 135 queue_duration_ = GetDuration();
108 DLogResultsStats("DNS Prefetch assigned"); 136 DLogResultsStats("DNS Prefetch assigned");
109 UMA_HISTOGRAM_TIMES("DNS.PrefetchQueue", queue_duration_); 137 UMA_HISTOGRAM_TIMES("DNS.PrefetchQueue", queue_duration_);
110 } 138 }
111 139
112 void UrlInfo::RemoveFromQueue() { 140 void UrlInfo::RemoveFromQueue() {
113 DCHECK(ASSIGNED == state_); 141 DCHECK(ASSIGNED == state_);
114 state_ = old_prequeue_state_; 142 state_ = old_prequeue_state_;
115 DLogResultsStats("DNS Prefetch reset to prequeue"); 143 DLogResultsStats("DNS Prefetch reset to prequeue");
116 static const TimeDelta kBoundary = TimeDelta::FromSeconds(2); 144 const TimeDelta kBoundary = TimeDelta::FromSeconds(2);
117 if (queue_duration_ > kBoundary) { 145 if (queue_duration_ > kBoundary) {
118 UMA_HISTOGRAM_MEDIUM_TIMES("DNS.QueueRecycledDeltaOver2", 146 UMA_HISTOGRAM_MEDIUM_TIMES("DNS.QueueRecycledDeltaOver2",
119 queue_duration_ - kBoundary); 147 queue_duration_ - kBoundary);
120 return; 148 return;
121 } 149 }
122 // Make a custom linear histogram for the region from 0 to boundary. 150 // Make a custom linear histogram for the region from 0 to boundary.
123 const size_t kBucketCount = 52; 151 static const size_t kBucketCount = 52;
124 static base::Histogram* histogram(NULL); 152 static base::Histogram* histogram(NULL);
125 if (!histogram) 153 if (!histogram)
126 histogram = base::LinearHistogram::FactoryTimeGet( 154 histogram = base::LinearHistogram::FactoryTimeGet(
127 "DNS.QueueRecycledUnder2", TimeDelta(), kBoundary, kBucketCount, 155 "DNS.QueueRecycledUnder2", TimeDelta(), kBoundary, kBucketCount,
128 base::Histogram::kUmaTargetedHistogramFlag); 156 base::Histogram::kUmaTargetedHistogramFlag);
129 histogram->AddTime(queue_duration_); 157 histogram->AddTime(queue_duration_);
130 } 158 }
131 159
132 void UrlInfo::SetPendingDeleteState() { 160 void UrlInfo::SetPendingDeleteState() {
133 DCHECK(ASSIGNED == state_ || ASSIGNED_BUT_MARKED == state_); 161 DCHECK(ASSIGNED == state_ || ASSIGNED_BUT_MARKED == state_);
134 state_ = ASSIGNED_BUT_MARKED; 162 state_ = ASSIGNED_BUT_MARKED;
135 } 163 }
136 164
137 void UrlInfo::SetFoundState() { 165 void UrlInfo::SetFoundState() {
138 DCHECK(ASSIGNED == state_); 166 DCHECK(ASSIGNED == state_);
139 state_ = FOUND; 167 state_ = FOUND;
140 resolve_duration_ = GetDuration(); 168 resolve_duration_ = GetDuration();
141 if (kMaxNonNetworkDnsLookupDuration <= resolve_duration_) { 169 const TimeDelta max_duration = MaxNonNetworkDnsLookupDuration();
170 if (max_duration <= resolve_duration_) {
142 UMA_HISTOGRAM_CUSTOM_TIMES("DNS.PrefetchResolution", resolve_duration_, 171 UMA_HISTOGRAM_CUSTOM_TIMES("DNS.PrefetchResolution", resolve_duration_,
143 kMaxNonNetworkDnsLookupDuration, TimeDelta::FromMinutes(15), 100); 172 max_duration, TimeDelta::FromMinutes(15), 100);
144 } 173 }
145 sequence_number_ = sequence_counter++; 174 sequence_number_ = sequence_counter++;
146 DLogResultsStats("DNS PrefetchFound"); 175 DLogResultsStats("DNS PrefetchFound");
147 } 176 }
148 177
149 void UrlInfo::SetNoSuchNameState() { 178 void UrlInfo::SetNoSuchNameState() {
150 DCHECK(ASSIGNED == state_); 179 DCHECK(ASSIGNED == state_);
151 state_ = NO_SUCH_NAME; 180 state_ = NO_SUCH_NAME;
152 resolve_duration_ = GetDuration(); 181 resolve_duration_ = GetDuration();
153 if (kMaxNonNetworkDnsLookupDuration <= resolve_duration_) { 182 if (MaxNonNetworkDnsLookupDuration() <= resolve_duration_) {
154 DHISTOGRAM_TIMES("DNS.PrefetchNotFoundName", resolve_duration_); 183 DHISTOGRAM_TIMES("DNS.PrefetchNotFoundName", resolve_duration_);
155 } 184 }
156 sequence_number_ = sequence_counter++; 185 sequence_number_ = sequence_counter++;
157 DLogResultsStats("DNS PrefetchNotFound"); 186 DLogResultsStats("DNS PrefetchNotFound");
158 } 187 }
159 188
160 void UrlInfo::SetUrl(const GURL& url) { 189 void UrlInfo::SetUrl(const GURL& url) {
161 if (url_.is_empty()) // Not yet initialized. 190 if (url_.is_empty()) // Not yet initialized.
162 url_ = url; 191 url_ = url;
163 else 192 else
164 DCHECK_EQ(url_, url); 193 DCHECK_EQ(url_, url);
165 } 194 }
166 195
167 // IsStillCached() guesses if the DNS cache still has IP data, 196 // IsStillCached() guesses if the DNS cache still has IP data,
168 // or at least remembers results about "not finding host." 197 // or at least remembers results about "not finding host."
169 bool UrlInfo::IsStillCached() const { 198 bool UrlInfo::IsStillCached() const {
170 DCHECK(FOUND == state_ || NO_SUCH_NAME == state_); 199 DCHECK(FOUND == state_ || NO_SUCH_NAME == state_);
171 200
172 // Default MS OS does not cache failures. Hence we could return false almost 201 // 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 202 // 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 203 // the value if we returned false that way. Hence we'll just let the lookup
175 // time out the same way as FOUND case. 204 // time out the same way as FOUND case.
176 205
177 if (sequence_counter - sequence_number_ > kMaxGuaranteedDnsCacheSize) 206 if (sequence_counter - sequence_number_ > kMaxGuaranteedDnsCacheSize)
178 return false; 207 return false;
179 208
180 TimeDelta time_since_resolution = TimeTicks::Now() - time_; 209 const TimeDelta time_since_resolution = TimeTicks::Now() - time_;
181 210 return time_since_resolution < global_state.Get().cache_expiration_duration;
182 return time_since_resolution < cache_expiration_duration_;
183 } 211 }
184 212
185 void UrlInfo::DLogResultsStats(const char* message) const { 213 void UrlInfo::DLogResultsStats(const char* message) const {
186 if (!detailed_logging_enabled) 214 if (!detailed_logging_enabled)
187 return; 215 return;
188 DVLOG(1) << "\t" << message << "\tq=" << queue_duration().InMilliseconds() 216 DVLOG(1) << "\t" << message << "\tq=" << queue_duration().InMilliseconds()
189 << "ms,\tr=" << resolve_duration().InMilliseconds() 217 << "ms,\tr=" << resolve_duration().InMilliseconds()
190 << "ms,\tp=" << sequence_number_ << "\t" << url_.spec(); 218 << "ms,\tp=" << sequence_number_ << "\t" << url_.spec();
191 } 219 }
192 220
(...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after
341 369
342 case LEARNED_REFERAL_MOTIVATED: 370 case LEARNED_REFERAL_MOTIVATED:
343 return RemoveJs(referring_url_.spec()); 371 return RemoveJs(referring_url_.spec());
344 372
345 default: 373 default:
346 return ""; 374 return "";
347 } 375 }
348 } 376 }
349 377
350 } // namespace chrome_browser_net 378 } // 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