OLD | NEW |
---|---|
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/history/visit_database.h" | 5 #include "chrome/browser/history/visit_database.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 #include <limits> | 8 #include <limits> |
9 #include <map> | 9 #include <map> |
10 #include <set> | 10 #include <set> |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
68 &VisitDatabase::VisitAnalysis::FetchHistory); | 68 &VisitDatabase::VisitAnalysis::FetchHistory); |
69 } | 69 } |
70 } | 70 } |
71 void AddVisit(VisitRow* visit) { | 71 void AddVisit(VisitRow* visit) { |
72 visits_to_process_.push_back(*visit); | 72 visits_to_process_.push_back(*visit); |
73 MaybeProcessVisits(); | 73 MaybeProcessVisits(); |
74 } | 74 } |
75 | 75 |
76 private: | 76 private: |
77 enum VA_EVENTS { | 77 enum VA_EVENTS { |
78 VA_VISIT = 0, | 78 VA_VISIT = 10, |
79 VA_PRERENDER_STARTED_1 = 1, | 79 VA_VISIT_EXCLUDE_BACK_FORWARD = 11, |
80 VA_PRERENDER_USED_1 = 2, | 80 VA_VISIT_EXCLUDE_HOME_PAGE = 12, |
81 VA_PRERENDER_STARTED_3 = 3, | 81 VA_VISIT_EXCLUDE_REDIRECT_CHAIN = 13, |
82 VA_PRERENDER_USED_3 = 4, | 82 VA_PRERENDER_STARTED_1 = 14, |
83 VA_PRERENDER_STARTED_5 = 5, | 83 VA_PRERENDER_USED_1 = 15, |
84 VA_PRERENDER_USED_5 = 6, | 84 VA_PRERENDER_STARTED_3 = 16, |
85 VA_EVENT_MAX = 7 | 85 VA_PRERENDER_USED_3 = 17, |
86 VA_PRERENDER_STARTED_5 = 18, | |
87 VA_PRERENDER_USED_5 = 19, | |
88 VA_EVENT_MAX = 20 | |
86 }; | 89 }; |
90 bool IsBackForward(content::PageTransition transition) { | |
dominich
2012/03/02 22:09:01
if this becomes production code, these should all
| |
91 return (transition & content::PAGE_TRANSITION_FORWARD_BACK) != 0; | |
92 } | |
93 bool IsHomePage(content::PageTransition transition) { | |
94 return (transition & content::PAGE_TRANSITION_HOME_PAGE) != 0; | |
95 } | |
96 bool IsIntermediateRedirect(content::PageTransition transition) { | |
97 return (transition & content::PAGE_TRANSITION_CHAIN_END) == 0; | |
dominich
2012/03/02 22:09:01
do navigations that are not part of a redirect cha
| |
98 } | |
99 bool ShouldExcludeTransitionForPrediction( | |
100 content::PageTransition transition) { | |
101 return IsBackForward(transition) || IsHomePage(transition) || | |
102 IsIntermediateRedirect(transition); | |
103 } | |
87 void RecordEvent(VA_EVENTS event, base::Time timestamp) { | 104 void RecordEvent(VA_EVENTS event, base::Time timestamp) { |
88 int64 ts = timestamp.ToInternalValue(); | 105 int64 ts = timestamp.ToInternalValue(); |
89 if (time_event_bitmaps_.count(ts) < 1) | 106 if (time_event_bitmaps_.count(ts) < 1) |
90 time_event_bitmaps_[ts] = 0; | 107 time_event_bitmaps_[ts] = 0; |
91 int mask = (1 << event); | 108 int mask = (1 << event); |
92 VLOG(1) << "event " << ts << " " << event; | 109 VLOG(1) << "event " << ts << " " << event; |
93 if (time_event_bitmaps_[ts] & mask) { | 110 if (time_event_bitmaps_[ts] & mask) { |
94 VLOG(1) << "duplicate event"; | 111 VLOG(1) << "duplicate event"; |
95 return; | 112 return; |
96 } | 113 } |
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
176 return false; | 193 return false; |
177 } | 194 } |
178 VisitAnalysis* visit_analysis_; | 195 VisitAnalysis* visit_analysis_; |
179 int num_prerenders_; | 196 int num_prerenders_; |
180 std::vector<PrerenderData> prerenders_; | 197 std::vector<PrerenderData> prerenders_; |
181 VA_EVENTS prerender_event_; | 198 VA_EVENTS prerender_event_; |
182 VA_EVENTS prerender_used_event_; | 199 VA_EVENTS prerender_used_event_; |
183 }; | 200 }; |
184 void ProcessVisit(const VisitRow& visit) { | 201 void ProcessVisit(const VisitRow& visit) { |
185 VLOG(1) << "processing visit to " << visit.url_id; | 202 VLOG(1) << "processing visit to " << visit.url_id; |
203 if (IsBackForward(visit.transition)) { | |
204 RecordEvent(VA_VISIT_EXCLUDE_BACK_FORWARD, visit.visit_time); | |
205 return; | |
206 } | |
207 if (IsHomePage(visit.transition)) { | |
208 RecordEvent(VA_VISIT_EXCLUDE_HOME_PAGE, visit.visit_time); | |
209 return; | |
210 } | |
211 if (IsIntermediateRedirect(visit.transition)) { | |
212 RecordEvent(VA_VISIT_EXCLUDE_REDIRECT_CHAIN, visit.visit_time); | |
213 return; | |
214 } | |
186 RecordEvent(VA_VISIT, visit.visit_time); | 215 RecordEvent(VA_VISIT, visit.visit_time); |
216 UMA_HISTOGRAM_ENUMERATION( | |
217 "Prerender.LocalVisitCoreTransition", | |
218 visit.transition & content::PAGE_TRANSITION_CORE_MASK, | |
219 content::PAGE_TRANSITION_LAST_CORE + 1); | |
187 for (int i = 0; i < static_cast<int>(emulated_prerender_managers_.size()); | 220 for (int i = 0; i < static_cast<int>(emulated_prerender_managers_.size()); |
188 i++) { | 221 i++) { |
189 emulated_prerender_managers_[i]->MaybeRecordPrerenderUsed(visit); | 222 emulated_prerender_managers_[i]->MaybeRecordPrerenderUsed(visit); |
190 } | 223 } |
191 base::TimeDelta max_age = | 224 base::TimeDelta max_age = |
192 base::TimeDelta::FromSeconds(kPrerenderExpirationSeconds); | 225 base::TimeDelta::FromSeconds(kPrerenderExpirationSeconds); |
193 base::TimeDelta min_age = | 226 base::TimeDelta min_age = |
194 base::TimeDelta::FromMilliseconds(kMinSpacingMilliseconds); | 227 base::TimeDelta::FromMilliseconds(kMinSpacingMilliseconds); |
195 std::set<URLID> currently_found; | 228 std::set<URLID> currently_found; |
196 std::map<URLID, int> found; | 229 std::map<URLID, int> found; |
197 int num_occurrences = 0; | 230 int num_occurrences = 0; |
198 base::Time last_started; | 231 base::Time last_started; |
199 URLID best_prerender = 0; | 232 URLID best_prerender = 0; |
200 int best_count = 0; | 233 int best_count = 0; |
201 for (int i = 0; i < static_cast<int>(visits_.size()); i++) { | 234 for (int i = 0; i < static_cast<int>(visits_.size()); i++) { |
202 VLOG(1) << visits_[i].visit_time.ToInternalValue()/1000000 << " " | 235 if (!ShouldExcludeTransitionForPrediction(visits_[i].transition)) { |
203 << visits_[i].url_id; | 236 VLOG(1) << visits_[i].visit_time.ToInternalValue()/1000000 << " " |
204 if (visits_[i].url_id == visit.url_id) { | 237 << visits_[i].url_id; |
205 VLOG(1) << "****"; | 238 if (visits_[i].url_id == visit.url_id) { |
206 last_started = visits_[i].visit_time; | 239 VLOG(1) << "****"; |
207 num_occurrences++; | 240 last_started = visits_[i].visit_time; |
208 currently_found.clear(); | 241 num_occurrences++; |
209 continue; | 242 currently_found.clear(); |
210 } | 243 continue; |
211 if (last_started > visits_[i].visit_time - max_age && | 244 } |
212 last_started < visits_[i].visit_time - min_age) { | 245 if (last_started > visits_[i].visit_time - max_age && |
213 currently_found.insert(visits_[i].url_id); | 246 last_started < visits_[i].visit_time - min_age) { |
214 VLOG(1) << "OK"; | 247 currently_found.insert(visits_[i].url_id); |
248 VLOG(1) << "OK"; | |
249 } | |
250 } else { | |
251 VLOG(1) << i << " (skipping)"; | |
215 } | 252 } |
216 if (i == static_cast<int>(visits_.size()) - 1 || | 253 if (i == static_cast<int>(visits_.size()) - 1 || |
217 visits_[i+1].url_id == visit.url_id) { | 254 visits_[i+1].url_id == visit.url_id) { |
218 VLOG(1) << "#########"; | 255 VLOG(1) << "#########"; |
219 // output last window | 256 // output last window |
220 for (std::set<URLID>::iterator it = currently_found.begin(); | 257 for (std::set<URLID>::iterator it = currently_found.begin(); |
221 it != currently_found.end(); | 258 it != currently_found.end(); |
222 ++it) { | 259 ++it) { |
223 if (found.count(*it) < 1) | 260 if (found.count(*it) < 1) |
224 found[*it] = 0; | 261 found[*it] = 0; |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
256 VisitRow visit = visits_to_process_[i]; | 293 VisitRow visit = visits_to_process_[i]; |
257 ProcessVisit(visit); | 294 ProcessVisit(visit); |
258 visits_.push_back(visit); | 295 visits_.push_back(visit); |
259 } | 296 } |
260 visits_to_process_.clear(); | 297 visits_to_process_.clear(); |
261 VLOG(1) << "done processing new visit. new visit size = " | 298 VLOG(1) << "done processing new visit. new visit size = " |
262 << visits_.size(); | 299 << visits_.size(); |
263 } | 300 } |
264 void FetchHistory() { | 301 void FetchHistory() { |
265 VLOG(1) << "VDB: fetching history"; | 302 VLOG(1) << "VDB: fetching history"; |
266 visit_database_->GetAllVisitsInRange(base::Time(), base::Time(), 0, | 303 visit_database_->GetAllVisitsInRange(base::Time(), base::Time(), |
267 &visits_); | 304 kMaxVisitRecords, &visits_); |
268 VLOG(1) << "READ visits " << visits_.size(); | 305 VLOG(1) << "READ visits " << visits_.size(); |
269 if (logging::GetVlogVerbosity() >= 1) { | 306 if (logging::GetVlogVerbosity() >= 1) { |
270 for (int i = 0; i < static_cast<int>(visits_.size()); i++) { | 307 for (int i = 0; i < static_cast<int>(visits_.size()); i++) { |
271 VLOG(1) << " Read visit: " << visits_[i].url_id; | 308 VLOG(1) << " Read visit: " << visits_[i].url_id; |
272 } | 309 } |
273 } | 310 } |
274 UMA_HISTOGRAM_COUNTS("Prerender.LocalVisitDatabaseSize", visits_.size()); | 311 UMA_HISTOGRAM_COUNTS("Prerender.LocalVisitDatabaseSize", visits_.size()); |
275 | 312 |
276 VLOG(1) << "--- all visits read."; | 313 VLOG(1) << "--- all visits read."; |
277 visits_fetched_ = true; | 314 visits_fetched_ = true; |
278 MaybeProcessVisits(); | 315 MaybeProcessVisits(); |
279 } | 316 } |
317 static const int kMaxVisitRecords = 100 * 1000; | |
dominich
2012/03/02 22:09:01
is there a chance that this will still cause OOM f
| |
280 static const int kFetchDelayMs = 30 * 1000; | 318 static const int kFetchDelayMs = 30 * 1000; |
281 static const int kPrerenderExpirationSeconds = 300; | 319 static const int kPrerenderExpirationSeconds = 300; |
282 static const int kMinSpacingMilliseconds = 1000; | 320 static const int kMinSpacingMilliseconds = 500; |
283 VisitDatabase* visit_database_; | 321 VisitDatabase* visit_database_; |
284 base::OneShotTimer<VisitAnalysis> timer_; | 322 base::OneShotTimer<VisitAnalysis> timer_; |
285 VisitVector visits_; | 323 VisitVector visits_; |
286 VisitVector visits_to_process_; | 324 VisitVector visits_to_process_; |
287 bool visits_fetched_; | 325 bool visits_fetched_; |
288 std::map<int64, int> time_event_bitmaps_; | 326 std::map<int64, int> time_event_bitmaps_; |
289 std::vector<EmulatedPrerenderManager *> emulated_prerender_managers_; | 327 std::vector<EmulatedPrerenderManager *> emulated_prerender_managers_; |
290 }; | 328 }; |
291 | 329 |
292 VisitDatabase::VisitDatabase() : visit_analysis_(new VisitAnalysis(this)) { | 330 VisitDatabase::VisitDatabase() : visit_analysis_(new VisitAnalysis(this)) { |
(...skipping 482 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
775 // Get the source entries out of the query result. | 813 // Get the source entries out of the query result. |
776 while (statement.Step()) { | 814 while (statement.Step()) { |
777 std::pair<VisitID, VisitSource> source_entry(statement.ColumnInt64(0), | 815 std::pair<VisitID, VisitSource> source_entry(statement.ColumnInt64(0), |
778 static_cast<VisitSource>(statement.ColumnInt(1))); | 816 static_cast<VisitSource>(statement.ColumnInt(1))); |
779 sources->insert(source_entry); | 817 sources->insert(source_entry); |
780 } | 818 } |
781 } | 819 } |
782 } | 820 } |
783 | 821 |
784 } // namespace history | 822 } // namespace history |
OLD | NEW |