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/history_backend.h" | 5 #include "chrome/browser/history/history_backend.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 #include <functional> | 8 #include <functional> |
9 #include <list> | 9 #include <list> |
10 #include <map> | 10 #include <map> |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
59 URLDatabase (stores a list of URLs) | 59 URLDatabase (stores a list of URLs) |
60 DownloadDatabase (stores a list of downloads) | 60 DownloadDatabase (stores a list of downloads) |
61 VisitDatabase (stores a list of visits for the URLs) | 61 VisitDatabase (stores a list of visits for the URLs) |
62 VisitSegmentDatabase (stores groups of URLs for the most visited view). | 62 VisitSegmentDatabase (stores groups of URLs for the most visited view). |
63 | 63 |
64 ExpireHistoryBackend (manages deleting things older than 3 months) | 64 ExpireHistoryBackend (manages deleting things older than 3 months) |
65 */ | 65 */ |
66 | 66 |
67 namespace history { | 67 namespace history { |
68 | 68 |
69 namespace { | |
70 void RunUnlessCanceled( | |
71 const base::Closure& closure, | |
72 const base::CancelableTaskTracker::IsCanceledCallback& is_canceled) { | |
73 if (!is_canceled.Run()) | |
74 closure.Run(); | |
75 } | |
76 } // namespace | |
77 | |
69 #if defined(OS_ANDROID) | 78 #if defined(OS_ANDROID) |
70 // How long we keep segment data for in days. Currently 3 months. | 79 // How long we keep segment data for in days. Currently 3 months. |
71 // This value needs to be greater or equal to | 80 // This value needs to be greater or equal to |
72 // MostVisitedModel::kMostVisitedScope but we don't want to introduce a direct | 81 // MostVisitedModel::kMostVisitedScope but we don't want to introduce a direct |
73 // dependency between MostVisitedModel and the history backend. | 82 // dependency between MostVisitedModel and the history backend. |
74 const int kSegmentDataRetention = 90; | 83 const int kSegmentDataRetention = 90; |
75 #endif | 84 #endif |
76 | 85 |
77 // How long we'll wait to do a commit, so that things are batched together. | 86 // How long we'll wait to do a commit, so that things are batched together. |
78 const int kCommitIntervalSeconds = 10; | 87 const int kCommitIntervalSeconds = 10; |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
147 } | 156 } |
148 | 157 |
149 private: | 158 private: |
150 friend class base::RefCounted<CommitLaterTask>; | 159 friend class base::RefCounted<CommitLaterTask>; |
151 | 160 |
152 ~CommitLaterTask() {} | 161 ~CommitLaterTask() {} |
153 | 162 |
154 scoped_refptr<HistoryBackend> history_backend_; | 163 scoped_refptr<HistoryBackend> history_backend_; |
155 }; | 164 }; |
156 | 165 |
166 // QueuedHistoryDBTask --------------------------------------------------------- | |
167 | |
168 QueuedHistoryDBTask::QueuedHistoryDBTask( | |
169 scoped_refptr<HistoryDBTask> task, | |
170 scoped_refptr<base::SingleThreadTaskRunner> origin_loop, | |
171 const base::CancelableTaskTracker::IsCanceledCallback& is_canceled) | |
172 : task_(task), origin_loop_(origin_loop), is_canceled_(is_canceled) { | |
173 DCHECK(task_); | |
174 DCHECK(origin_loop_); | |
175 DCHECK(!is_canceled_.is_null()); | |
176 } | |
177 | |
178 QueuedHistoryDBTask::~QueuedHistoryDBTask() { | |
179 } | |
180 | |
181 bool QueuedHistoryDBTask::is_canceled() { | |
182 return is_canceled_.Run(); | |
183 } | |
184 | |
185 bool QueuedHistoryDBTask::RunOnDBThread(HistoryBackend* backend, | |
186 HistoryDatabase* db) { | |
187 return task_->RunOnDBThread(backend, db); | |
188 } | |
189 | |
190 void QueuedHistoryDBTask::DoneRunOnMainThread() { | |
191 origin_loop_->PostTask( | |
192 FROM_HERE, | |
193 base::Bind(&RunUnlessCanceled, | |
194 base::Bind(&HistoryDBTask::DoneRunOnMainThread, task_), | |
195 is_canceled_)); | |
196 } | |
197 | |
157 // HistoryBackend -------------------------------------------------------------- | 198 // HistoryBackend -------------------------------------------------------------- |
158 | 199 |
159 HistoryBackend::HistoryBackend(const base::FilePath& history_dir, | 200 HistoryBackend::HistoryBackend(const base::FilePath& history_dir, |
160 Delegate* delegate, | 201 Delegate* delegate, |
161 HistoryClient* history_client) | 202 HistoryClient* history_client) |
162 : delegate_(delegate), | 203 : delegate_(delegate), |
163 history_dir_(history_dir), | 204 history_dir_(history_dir), |
164 scheduled_kill_db_(false), | 205 scheduled_kill_db_(false), |
165 expirer_(this, history_client), | 206 expirer_(this, history_client), |
166 recent_redirects_(kMaxRedirectCount), | 207 recent_redirects_(kMaxRedirectCount), |
167 backend_destroy_message_loop_(NULL), | 208 backend_destroy_message_loop_(NULL), |
168 segment_queried_(false), | 209 segment_queried_(false), |
169 history_client_(history_client) { | 210 history_client_(history_client) { |
170 } | 211 } |
171 | 212 |
172 HistoryBackend::~HistoryBackend() { | 213 HistoryBackend::~HistoryBackend() { |
173 DCHECK(!scheduled_commit_.get()) << "Deleting without cleanup"; | 214 DCHECK(!scheduled_commit_.get()) << "Deleting without cleanup"; |
174 ReleaseDBTasks(); | 215 queued_history_db_tasks_.clear(); |
175 | 216 |
176 #if defined(OS_ANDROID) | 217 #if defined(OS_ANDROID) |
177 // Release AndroidProviderBackend before other objects. | 218 // Release AndroidProviderBackend before other objects. |
178 android_provider_backend_.reset(); | 219 android_provider_backend_.reset(); |
179 #endif | 220 #endif |
180 | 221 |
181 // First close the databases before optionally running the "destroy" task. | 222 // First close the databases before optionally running the "destroy" task. |
182 CloseAllDatabases(); | 223 CloseAllDatabases(); |
183 | 224 |
184 if (!backend_destroy_task_.is_null()) { | 225 if (!backend_destroy_task_.is_null()) { |
(...skipping 2094 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2279 void HistoryBackend::CancelScheduledCommit() { | 2320 void HistoryBackend::CancelScheduledCommit() { |
2280 if (scheduled_commit_.get()) { | 2321 if (scheduled_commit_.get()) { |
2281 scheduled_commit_->Cancel(); | 2322 scheduled_commit_->Cancel(); |
2282 scheduled_commit_ = NULL; | 2323 scheduled_commit_ = NULL; |
2283 } | 2324 } |
2284 } | 2325 } |
2285 | 2326 |
2286 void HistoryBackend::ProcessDBTaskImpl() { | 2327 void HistoryBackend::ProcessDBTaskImpl() { |
2287 if (!db_) { | 2328 if (!db_) { |
2288 // db went away, release all the refs. | 2329 // db went away, release all the refs. |
2289 ReleaseDBTasks(); | 2330 queued_history_db_tasks_.clear(); |
2290 return; | 2331 return; |
2291 } | 2332 } |
2292 | 2333 |
2293 // Remove any canceled tasks. | 2334 // Remove any canceled tasks. |
2294 while (!db_task_requests_.empty() && db_task_requests_.front()->canceled()) { | 2335 while (!queued_history_db_tasks_.empty()) { |
2295 db_task_requests_.front()->Release(); | 2336 QueuedHistoryDBTask& task = queued_history_db_tasks_.front(); |
2296 db_task_requests_.pop_front(); | 2337 if (!task.is_canceled()) { |
2338 break; | |
2339 } | |
2340 queued_history_db_tasks_.pop_front(); | |
blundell
2014/06/26 09:55:39
this will cause the task's destructor to run?
sdefresne
2014/06/28 08:14:25
Yes, this queued_history_db_tasks is of type std::
| |
2297 } | 2341 } |
2298 if (db_task_requests_.empty()) | 2342 if (queued_history_db_tasks_.empty()) |
2299 return; | 2343 return; |
2300 | 2344 |
2301 // Run the first task. | 2345 // Run the first task. |
2302 HistoryDBTaskRequest* request = db_task_requests_.front(); | 2346 QueuedHistoryDBTask task = queued_history_db_tasks_.front(); |
2303 db_task_requests_.pop_front(); | 2347 queued_history_db_tasks_.pop_front(); |
2304 if (request->value->RunOnDBThread(this, db_.get())) { | 2348 if (task.RunOnDBThread(this, db_.get())) { |
2305 // The task is done. Notify the callback. | 2349 // The task is done, notify the callback. |
2306 request->ForwardResult(); | 2350 task.DoneRunOnMainThread(); |
2307 // We AddRef'd the request before adding, need to release it now. | |
2308 request->Release(); | |
2309 } else { | 2351 } else { |
2310 // Tasks wants to run some more. Schedule it at the end of current tasks. | 2352 // The task wants to run some more. Schedule it at the end of the current |
2311 db_task_requests_.push_back(request); | 2353 // tasks, and process it after an invoke later. |
2312 // And process it after an invoke later. | 2354 queued_history_db_tasks_.insert(queued_history_db_tasks_.end(), task); |
2313 base::MessageLoop::current()->PostTask( | 2355 base::MessageLoop::current()->PostTask( |
2314 FROM_HERE, base::Bind(&HistoryBackend::ProcessDBTaskImpl, this)); | 2356 FROM_HERE, base::Bind(&HistoryBackend::ProcessDBTaskImpl, this)); |
2315 } | 2357 } |
2316 } | 2358 } |
2317 | 2359 |
2318 void HistoryBackend::ReleaseDBTasks() { | |
2319 for (std::list<HistoryDBTaskRequest*>::iterator i = | |
2320 db_task_requests_.begin(); i != db_task_requests_.end(); ++i) { | |
2321 (*i)->Release(); | |
2322 } | |
2323 db_task_requests_.clear(); | |
2324 } | |
2325 | |
2326 //////////////////////////////////////////////////////////////////////////////// | 2360 //////////////////////////////////////////////////////////////////////////////// |
2327 // | 2361 // |
2328 // Generic operations | 2362 // Generic operations |
2329 // | 2363 // |
2330 //////////////////////////////////////////////////////////////////////////////// | 2364 //////////////////////////////////////////////////////////////////////////////// |
2331 | 2365 |
2332 void HistoryBackend::DeleteURLs(const std::vector<GURL>& urls) { | 2366 void HistoryBackend::DeleteURLs(const std::vector<GURL>& urls) { |
2333 expirer_.DeleteURLs(urls); | 2367 expirer_.DeleteURLs(urls); |
2334 | 2368 |
2335 db_->GetStartDate(&first_recorded_time_); | 2369 db_->GetStartDate(&first_recorded_time_); |
(...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2496 // The expirer keeps tabs on the active databases. Tell it about the | 2530 // The expirer keeps tabs on the active databases. Tell it about the |
2497 // databases which will be closed. | 2531 // databases which will be closed. |
2498 expirer_.SetDatabases(NULL, NULL); | 2532 expirer_.SetDatabases(NULL, NULL); |
2499 | 2533 |
2500 // Reopen a new transaction for |db_| for the sake of CloseAllDatabases(). | 2534 // Reopen a new transaction for |db_| for the sake of CloseAllDatabases(). |
2501 db_->BeginTransaction(); | 2535 db_->BeginTransaction(); |
2502 CloseAllDatabases(); | 2536 CloseAllDatabases(); |
2503 } | 2537 } |
2504 | 2538 |
2505 void HistoryBackend::ProcessDBTask( | 2539 void HistoryBackend::ProcessDBTask( |
2506 scoped_refptr<HistoryDBTaskRequest> request) { | 2540 scoped_refptr<HistoryDBTask> task, |
2507 DCHECK(request.get()); | 2541 scoped_refptr<base::SingleThreadTaskRunner> origin_loop, |
2508 if (request->canceled()) | 2542 const base::CancelableTaskTracker::IsCanceledCallback& is_canceled) { |
2509 return; | 2543 bool scheduled = !queued_history_db_tasks_.empty(); |
2510 | 2544 queued_history_db_tasks_.insert( |
2511 bool task_scheduled = !db_task_requests_.empty(); | 2545 queued_history_db_tasks_.end(), |
2512 // Make sure we up the refcount of the request. ProcessDBTaskImpl will | 2546 QueuedHistoryDBTask(task, origin_loop, is_canceled)); |
2513 // release when done with the task. | 2547 if (!scheduled) |
2514 request->AddRef(); | |
2515 db_task_requests_.push_back(request.get()); | |
2516 if (!task_scheduled) { | |
2517 // No other tasks are scheduled. Process request now. | |
2518 ProcessDBTaskImpl(); | 2548 ProcessDBTaskImpl(); |
2519 } | |
2520 } | 2549 } |
2521 | 2550 |
2522 void HistoryBackend::BroadcastNotifications( | 2551 void HistoryBackend::BroadcastNotifications( |
2523 int type, | 2552 int type, |
2524 scoped_ptr<HistoryDetails> details) { | 2553 scoped_ptr<HistoryDetails> details) { |
2525 // |delegate_| may be NULL if |this| is in the process of closing (closed by | 2554 // |delegate_| may be NULL if |this| is in the process of closing (closed by |
2526 // HistoryService -> HistoryBackend::Closing(). | 2555 // HistoryService -> HistoryBackend::Closing(). |
2527 if (delegate_) | 2556 if (delegate_) |
2528 delegate_->BroadcastNotifications(type, details.Pass()); | 2557 delegate_->BroadcastNotifications(type, details.Pass()); |
2529 } | 2558 } |
(...skipping 183 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2713 int rank = kPageVisitStatsMaxTopSites; | 2742 int rank = kPageVisitStatsMaxTopSites; |
2714 std::map<GURL, int>::const_iterator it = most_visited_urls_map_.find(url); | 2743 std::map<GURL, int>::const_iterator it = most_visited_urls_map_.find(url); |
2715 if (it != most_visited_urls_map_.end()) | 2744 if (it != most_visited_urls_map_.end()) |
2716 rank = (*it).second; | 2745 rank = (*it).second; |
2717 UMA_HISTOGRAM_ENUMERATION("History.TopSitesVisitsByRank", | 2746 UMA_HISTOGRAM_ENUMERATION("History.TopSitesVisitsByRank", |
2718 rank, kPageVisitStatsMaxTopSites + 1); | 2747 rank, kPageVisitStatsMaxTopSites + 1); |
2719 } | 2748 } |
2720 #endif | 2749 #endif |
2721 | 2750 |
2722 } // namespace history | 2751 } // namespace history |
OLD | NEW |