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