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

Side by Side Diff: chrome/browser/history/history_backend.cc

Issue 235863023: Eliminate the archived history database and clean up related code. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 6 years, 8 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
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/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 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
46 #include "url/gurl.h" 46 #include "url/gurl.h"
47 47
48 #if defined(OS_ANDROID) 48 #if defined(OS_ANDROID)
49 #include "chrome/browser/history/android/android_provider_backend.h" 49 #include "chrome/browser/history/android/android_provider_backend.h"
50 #endif 50 #endif
51 51
52 using base::Time; 52 using base::Time;
53 using base::TimeDelta; 53 using base::TimeDelta;
54 using base::TimeTicks; 54 using base::TimeTicks;
55 55
56 /* The HistoryBackend consists of a number of components: 56 /* The HistoryBackend consists of two components:
57 57
58 HistoryDatabase (stores past 3 months of history) 58 HistoryDatabase (stores past 3 months of history)
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 ArchivedDatabase (stores history older than 3 months)
65 URLDatabase (stores a list of URLs)
66 DownloadDatabase (stores a list of downloads)
67 VisitDatabase (stores a list of visits for the URLs)
68
69 (this does not store visit segments as they expire after 3 mos.)
70
71 ExpireHistoryBackend (manages moving things from HistoryDatabase to 64 ExpireHistoryBackend (manages moving things from HistoryDatabase to
72 the ArchivedDatabase and deleting) 65 the ArchivedDatabase and deleting)
73 */ 66 */
74 67
75 namespace history { 68 namespace history {
76 69
77 // How long we keep segment data for in days. Currently 3 months. 70 // How long we keep segment data for in days. Currently 3 months.
78 // This value needs to be greater or equal to 71 // This value needs to be greater or equal to
79 // MostVisitedModel::kMostVisitedScope but we don't want to introduce a direct 72 // MostVisitedModel::kMostVisitedScope but we don't want to introduce a direct
80 // dependency between MostVisitedModel and the history backend. 73 // dependency between MostVisitedModel and the history backend.
81 const int kSegmentDataRetention = 90; 74 const int kSegmentDataRetention = 90;
82 75
83 // How long we'll wait to do a commit, so that things are batched together. 76 // How long we'll wait to do a commit, so that things are batched together.
84 const int kCommitIntervalSeconds = 10; 77 const int kCommitIntervalSeconds = 10;
85 78
86 // The amount of time before we re-fetch the favicon. 79 // The amount of time before we re-fetch the favicon.
87 const int kFaviconRefetchDays = 7; 80 const int kFaviconRefetchDays = 7;
88 81
89 // The maximum number of items we'll allow in the redirect list before 82 // The maximum number of items we'll allow in the redirect list before
90 // deleting some. 83 // deleting some.
91 const int kMaxRedirectCount = 32; 84 const int kMaxRedirectCount = 32;
92 85
93 // The number of days old a history entry can be before it is considered "old" 86 // The number of days old a history entry can be before it is considered "old"
94 // and is archived. 87 // and is deleted.
95 const int kArchiveDaysThreshold = 90; 88 const int kArchiveDaysThreshold = 90;
96 89
97 #if defined(OS_ANDROID) 90 #if defined(OS_ANDROID)
98 // The maximum number of top sites to track when recording top page visit stats. 91 // The maximum number of top sites to track when recording top page visit stats.
99 const size_t kPageVisitStatsMaxTopSites = 50; 92 const size_t kPageVisitStatsMaxTopSites = 50;
100 #endif 93 #endif
101 94
102 // Converts from PageUsageData to MostVisitedURL. |redirects| is a 95 // Converts from PageUsageData to MostVisitedURL. |redirects| is a
103 // list of redirects for this URL. Empty list means no redirects. 96 // list of redirects for this URL. Empty list means no redirects.
104 MostVisitedURL MakeMostVisitedURL(const PageUsageData& page_data, 97 MostVisitedURL MakeMostVisitedURL(const PageUsageData& page_data,
(...skipping 505 matching lines...) Expand 10 before | Expand all | Expand 10 after
610 if (thumbnail_db_->Init(thumbnail_name) != sql::INIT_OK) { 603 if (thumbnail_db_->Init(thumbnail_name) != sql::INIT_OK) {
611 // Unlike the main database, we don't error out when the database is too 604 // Unlike the main database, we don't error out when the database is too
612 // new because this error is much less severe. Generally, this shouldn't 605 // new because this error is much less severe. Generally, this shouldn't
613 // happen since the thumbnail and main database versions should be in sync. 606 // happen since the thumbnail and main database versions should be in sync.
614 // We'll just continue without thumbnails & favicons in this case or any 607 // We'll just continue without thumbnails & favicons in this case or any
615 // other error. 608 // other error.
616 LOG(WARNING) << "Could not initialize the thumbnail database."; 609 LOG(WARNING) << "Could not initialize the thumbnail database.";
617 thumbnail_db_.reset(); 610 thumbnail_db_.reset();
618 } 611 }
619 612
620 // Archived database. 613 // Nuke the remnants of the legacy Archived Database. This used to retain
621 if (db_->needs_version_17_migration()) { 614 // expired (> 3 months old) history entries, but in the end, these were not
622 // See needs_version_17_migration() decl for more. In this case, we want 615 // really used for much, therefore the feature has been removed as of M36.
623 // to delete the archived database and need to do so before we try to 616 sql::Connection::Delete(archived_name);
624 // open the file. We can ignore any error (maybe the file doesn't exist).
625 sql::Connection::Delete(archived_name);
626 }
627 archived_db_.reset(new ArchivedDatabase());
628 if (!archived_db_->Init(archived_name)) {
629 LOG(WARNING) << "Could not initialize the archived database.";
630 archived_db_.reset();
631 }
632 617
633 // Generate the history and thumbnail database metrics only after performing 618 // Generate the history and thumbnail database metrics only after performing
634 // any migration work. 619 // any migration work.
635 if (base::RandInt(1, 100) == 50) { 620 if (base::RandInt(1, 100) == 50) {
636 // Only do this computation sometimes since it can be expensive. 621 // Only do this computation sometimes since it can be expensive.
637 db_->ComputeDatabaseMetrics(history_name); 622 db_->ComputeDatabaseMetrics(history_name);
638 if (thumbnail_db_) 623 if (thumbnail_db_)
639 thumbnail_db_->ComputeDatabaseMetrics(); 624 thumbnail_db_->ComputeDatabaseMetrics();
640 } 625 }
641 626
642 // Tell the expiration module about all the nice databases we made. This must 627 // Tell the expiration module about all the nice databases we made. This must
643 // happen before db_->Init() is called since the callback ForceArchiveHistory 628 // happen before db_->Init() is called since the callback ForceArchiveHistory
644 // may need to expire stuff. 629 // may need to expire stuff.
645 // 630 //
646 // *sigh*, this can all be cleaned up when that migration code is removed. 631 // *sigh*, this can all be cleaned up when that migration code is removed.
647 // The main DB initialization should intuitively be first (not that it 632 // The main DB initialization should intuitively be first (not that it
648 // actually matters) and the expirer should be set last. 633 // actually matters) and the expirer should be set last.
649 expirer_.SetDatabases(db_.get(), archived_db_.get(), thumbnail_db_.get()); 634 expirer_.SetDatabases(db_.get(), thumbnail_db_.get());
650 635
651 // Open the long-running transaction. 636 // Open the long-running transaction.
652 db_->BeginTransaction(); 637 db_->BeginTransaction();
653 if (thumbnail_db_) 638 if (thumbnail_db_)
654 thumbnail_db_->BeginTransaction(); 639 thumbnail_db_->BeginTransaction();
655 if (archived_db_)
656 archived_db_->BeginTransaction();
657 640
658 // Get the first item in our database. 641 // Get the first item in our database.
659 db_->GetStartDate(&first_recorded_time_); 642 db_->GetStartDate(&first_recorded_time_);
660 643
661 // Start expiring old stuff. 644 // Start expiring old stuff.
662 expirer_.StartArchivingOldStuff(TimeDelta::FromDays(kArchiveDaysThreshold)); 645 expirer_.StartExpiringOldStuff(TimeDelta::FromDays(kArchiveDaysThreshold));
663 646
664 #if defined(OS_ANDROID) 647 #if defined(OS_ANDROID)
665 if (thumbnail_db_) { 648 if (thumbnail_db_) {
666 android_provider_backend_.reset(new AndroidProviderBackend( 649 android_provider_backend_.reset(new AndroidProviderBackend(
667 GetAndroidCacheFileName(), db_.get(), thumbnail_db_.get(), 650 GetAndroidCacheFileName(), db_.get(), thumbnail_db_.get(),
668 bookmark_service_, delegate_.get())); 651 bookmark_service_, delegate_.get()));
669 } 652 }
670 #endif 653 #endif
671 654
672 HISTOGRAM_TIMES("History.InitTime", 655 HISTOGRAM_TIMES("History.InitTime",
673 TimeTicks::Now() - beginning_time); 656 TimeTicks::Now() - beginning_time);
674 } 657 }
675 658
676 void HistoryBackend::OnMemoryPressure( 659 void HistoryBackend::OnMemoryPressure(
677 base::MemoryPressureListener::MemoryPressureLevel memory_pressure_level) { 660 base::MemoryPressureListener::MemoryPressureLevel memory_pressure_level) {
678 bool trim_aggressively = memory_pressure_level == 661 bool trim_aggressively = memory_pressure_level ==
679 base::MemoryPressureListener::MEMORY_PRESSURE_CRITICAL; 662 base::MemoryPressureListener::MEMORY_PRESSURE_CRITICAL;
680 if (db_) 663 if (db_)
681 db_->TrimMemory(trim_aggressively); 664 db_->TrimMemory(trim_aggressively);
682 if (thumbnail_db_) 665 if (thumbnail_db_)
683 thumbnail_db_->TrimMemory(trim_aggressively); 666 thumbnail_db_->TrimMemory(trim_aggressively);
684 if (archived_db_)
685 archived_db_->TrimMemory(trim_aggressively);
686 } 667 }
687 668
688 void HistoryBackend::CloseAllDatabases() { 669 void HistoryBackend::CloseAllDatabases() {
689 if (db_) { 670 if (db_) {
690 // Commit the long-running transaction. 671 // Commit the long-running transaction.
691 db_->CommitTransaction(); 672 db_->CommitTransaction();
692 db_.reset(); 673 db_.reset();
693 // Forget the first recorded time since the database is closed. 674 // Forget the first recorded time since the database is closed.
694 first_recorded_time_ = base::Time(); 675 first_recorded_time_ = base::Time();
695 } 676 }
696 if (thumbnail_db_) { 677 if (thumbnail_db_) {
697 thumbnail_db_->CommitTransaction(); 678 thumbnail_db_->CommitTransaction();
698 thumbnail_db_.reset(); 679 thumbnail_db_.reset();
699 } 680 }
700 if (archived_db_) {
701 archived_db_->CommitTransaction();
702 archived_db_.reset();
703 }
704 } 681 }
705 682
706 std::pair<URLID, VisitID> HistoryBackend::AddPageVisit( 683 std::pair<URLID, VisitID> HistoryBackend::AddPageVisit(
707 const GURL& url, 684 const GURL& url,
708 Time time, 685 Time time,
709 VisitID referring_visit, 686 VisitID referring_visit,
710 content::PageTransition transition, 687 content::PageTransition transition,
711 VisitSource visit_source) { 688 VisitSource visit_source) {
712 // Top-level frame navigations are visible, everything else is hidden 689 // Top-level frame navigations are visible, everything else is hidden
713 bool new_hidden = !content::PageTransitionIsMainFrame(transition); 690 bool new_hidden = !content::PageTransitionIsMainFrame(transition);
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
794 771
795 return std::make_pair(url_id, visit_id); 772 return std::make_pair(url_id, visit_id);
796 } 773 }
797 774
798 void HistoryBackend::AddPagesWithDetails(const URLRows& urls, 775 void HistoryBackend::AddPagesWithDetails(const URLRows& urls,
799 VisitSource visit_source) { 776 VisitSource visit_source) {
800 if (!db_) 777 if (!db_)
801 return; 778 return;
802 779
803 scoped_ptr<URLsModifiedDetails> modified(new URLsModifiedDetails); 780 scoped_ptr<URLsModifiedDetails> modified(new URLsModifiedDetails);
804 scoped_ptr<URLsModifiedDetails> modified_in_archive(new URLsModifiedDetails);
805 for (URLRows::const_iterator i = urls.begin(); i != urls.end(); ++i) { 781 for (URLRows::const_iterator i = urls.begin(); i != urls.end(); ++i) {
806 DCHECK(!i->last_visit().is_null()); 782 DCHECK(!i->last_visit().is_null());
807 783
808 // We will add to either the archived database or the main one depending on 784 // As of M36, we no longer retain expired records in an archived database,
809 // the date of the added visit. 785 // so forget about old visits.
810 URLDatabase* url_database = NULL; 786 if (IsExpiredVisitTime(i->last_visit()))
811 VisitDatabase* visit_database = NULL; 787 continue;
812 if (IsExpiredVisitTime(i->last_visit())) {
813 if (!archived_db_)
814 return; // No archived database to save it to, just forget this.
815 url_database = archived_db_.get();
816 visit_database = archived_db_.get();
817 } else {
818 url_database = db_.get();
819 visit_database = db_.get();
820 }
821 788
822 URLRow existing_url; 789 URLRow existing_url;
823 URLID url_id = url_database->GetRowForURL(i->url(), &existing_url); 790 URLID url_id = db_->GetRowForURL(i->url(), &existing_url);
824 if (!url_id) { 791 if (!url_id) {
825 // Add the page if it doesn't exist. 792 // Add the page if it doesn't exist.
826 url_id = url_database->AddURL(*i); 793 url_id = db_->AddURL(*i);
827 if (!url_id) { 794 if (!url_id) {
828 NOTREACHED() << "Could not add row to DB"; 795 NOTREACHED() << "Could not add row to DB";
829 return; 796 return;
830 } 797 }
831 798
832 if (i->typed_count() > 0) { 799 if (i->typed_count() > 0) {
833 // Collect expired URLs that belong to |archived_db_| separately; we 800 modified->changed_urls.push_back(*i);
834 // want to fire NOTIFICATION_HISTORY_URLS_MODIFIED only for changes that 801 modified->changed_urls.back().set_id(url_id); // i->id_ is likely 0.
835 // take place in the main |db_|.
836 if (url_database == db_.get()) {
837 modified->changed_urls.push_back(*i);
838 modified->changed_urls.back().set_id(url_id); // i->id_ is likely 0.
839 } else {
840 modified_in_archive->changed_urls.push_back(*i);
841 modified_in_archive->changed_urls.back().set_id(url_id);
842 }
843 } 802 }
844 } 803 }
845 804
846 // Sync code manages the visits itself. 805 // Sync code manages the visits itself.
847 if (visit_source != SOURCE_SYNCED) { 806 if (visit_source != SOURCE_SYNCED) {
848 // Make up a visit to correspond to the last visit to the page. 807 // Make up a visit to correspond to the last visit to the page.
849 VisitRow visit_info(url_id, i->last_visit(), 0, 808 VisitRow visit_info(url_id, i->last_visit(), 0,
850 content::PageTransitionFromInt( 809 content::PageTransitionFromInt(
851 content::PAGE_TRANSITION_LINK | 810 content::PAGE_TRANSITION_LINK |
852 content::PAGE_TRANSITION_CHAIN_START | 811 content::PAGE_TRANSITION_CHAIN_START |
853 content::PAGE_TRANSITION_CHAIN_END), 0); 812 content::PAGE_TRANSITION_CHAIN_END), 0);
854 if (!visit_database->AddVisit(&visit_info, visit_source)) { 813 if (!db_->AddVisit(&visit_info, visit_source)) {
855 NOTREACHED() << "Adding visit failed."; 814 NOTREACHED() << "Adding visit failed.";
856 return; 815 return;
857 } 816 }
858 NotifyVisitObservers(visit_info); 817 NotifyVisitObservers(visit_info);
859 818
860 if (visit_info.visit_time < first_recorded_time_) 819 if (visit_info.visit_time < first_recorded_time_)
861 first_recorded_time_ = visit_info.visit_time; 820 first_recorded_time_ = visit_info.visit_time;
862 } 821 }
863 } 822 }
864 823
865 if (typed_url_syncable_service_.get()) { 824 if (typed_url_syncable_service_.get())
866 typed_url_syncable_service_->OnUrlsModified(
867 &modified_in_archive->changed_urls);
868 typed_url_syncable_service_->OnUrlsModified(&modified->changed_urls); 825 typed_url_syncable_service_->OnUrlsModified(&modified->changed_urls);
869 }
870 826
871 // Broadcast a notification for typed URLs that have been modified. This 827 // Broadcast a notification for typed URLs that have been modified. This
872 // will be picked up by the in-memory URL database on the main thread. 828 // will be picked up by the in-memory URL database on the main thread.
873 // 829 //
874 // TODO(brettw) bug 1140015: Add an "add page" notification so the history 830 // TODO(brettw) bug 1140015: Add an "add page" notification so the history
875 // views can keep in sync. 831 // views can keep in sync.
876 BroadcastNotifications(chrome::NOTIFICATION_HISTORY_URLS_MODIFIED, 832 BroadcastNotifications(chrome::NOTIFICATION_HISTORY_URLS_MODIFIED,
877 modified.PassAs<HistoryDetails>()); 833 modified.PassAs<HistoryDetails>());
878 834
879 ScheduleCommit(); 835 ScheduleCommit();
880 } 836 }
881 837
882 bool HistoryBackend::IsExpiredVisitTime(const base::Time& time) { 838 bool HistoryBackend::IsExpiredVisitTime(const base::Time& time) {
883 return time < expirer_.GetCurrentArchiveTime(); 839 return time < expirer_.GetCurrentExpirationTime();
884 } 840 }
885 841
886 void HistoryBackend::SetPageTitle(const GURL& url, 842 void HistoryBackend::SetPageTitle(const GURL& url,
887 const base::string16& title) { 843 const base::string16& title) {
888 if (!db_) 844 if (!db_)
889 return; 845 return;
890 846
891 // Search for recent redirects which should get the same title. We make a 847 // Search for recent redirects which should get the same title. We make a
892 // dummy list containing the exact URL visited if there are no redirects so 848 // dummy list containing the exact URL visited if there are no redirects so
893 // the processing below can be the same. 849 // the processing below can be the same.
(...skipping 225 matching lines...) Expand 10 before | Expand all | Expand 10 after
1119 new KeywordSearchUpdatedDetails(url, keyword_id, term))); 1075 new KeywordSearchUpdatedDetails(url, keyword_id, term)));
1120 ScheduleCommit(); 1076 ScheduleCommit();
1121 } 1077 }
1122 1078
1123 void HistoryBackend::DeleteAllSearchTermsForKeyword( 1079 void HistoryBackend::DeleteAllSearchTermsForKeyword(
1124 TemplateURLID keyword_id) { 1080 TemplateURLID keyword_id) {
1125 if (!db_) 1081 if (!db_)
1126 return; 1082 return;
1127 1083
1128 db_->DeleteAllSearchTermsForKeyword(keyword_id); 1084 db_->DeleteAllSearchTermsForKeyword(keyword_id);
1129 // TODO(sky): bug 1168470. Need to move from archive dbs too.
1130 ScheduleCommit(); 1085 ScheduleCommit();
1131 } 1086 }
1132 1087
1133 void HistoryBackend::GetMostRecentKeywordSearchTerms( 1088 void HistoryBackend::GetMostRecentKeywordSearchTerms(
1134 scoped_refptr<GetMostRecentKeywordSearchTermsRequest> request, 1089 scoped_refptr<GetMostRecentKeywordSearchTermsRequest> request,
1135 TemplateURLID keyword_id, 1090 TemplateURLID keyword_id,
1136 const base::string16& prefix, 1091 const base::string16& prefix,
1137 int max_count) { 1092 int max_count) {
1138 if (request->canceled()) 1093 if (request->canceled())
1139 return; 1094 return;
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after
1244 const base::string16& text_query, 1199 const base::string16& text_query,
1245 const QueryOptions& options) { 1200 const QueryOptions& options) {
1246 if (request->canceled()) 1201 if (request->canceled())
1247 return; 1202 return;
1248 1203
1249 TimeTicks beginning_time = TimeTicks::Now(); 1204 TimeTicks beginning_time = TimeTicks::Now();
1250 1205
1251 if (db_) { 1206 if (db_) {
1252 if (text_query.empty()) { 1207 if (text_query.empty()) {
1253 // Basic history query for the main database. 1208 // Basic history query for the main database.
1254 QueryHistoryBasic(db_.get(), db_.get(), options, &request->value); 1209 QueryHistoryBasic(options, &request->value);
1255
1256 // Now query the archived database. This is a bit tricky because we don't
1257 // want to query it if the queried time range isn't going to find anything
1258 // in it.
1259 // TODO(brettw) bug 1171036: do blimpie querying for the archived database
1260 // as well.
1261 // if (archived_db_.get() &&
1262 // expirer_.GetCurrentArchiveTime() - TimeDelta::FromDays(7)) {
1263 } else { 1210 } else {
1264 // Text history query. 1211 // Text history query.
1265 QueryHistoryText(db_.get(), db_.get(), text_query, options, 1212 QueryHistoryText(text_query, options, &request->value);
1266 &request->value);
1267 if (archived_db_.get() &&
1268 expirer_.GetCurrentArchiveTime() >= options.begin_time) {
1269 QueryHistoryText(archived_db_.get(), archived_db_.get(), text_query,
1270 options, &request->value);
1271 }
1272 } 1213 }
1273 } 1214 }
1274 1215
1275 request->ForwardResult(request->handle(), &request->value); 1216 request->ForwardResult(request->handle(), &request->value);
1276 1217
1277 UMA_HISTOGRAM_TIMES("History.QueryHistory", 1218 UMA_HISTOGRAM_TIMES("History.QueryHistory",
1278 TimeTicks::Now() - beginning_time); 1219 TimeTicks::Now() - beginning_time);
1279 } 1220 }
1280 1221
1281 // Basic time-based querying of history. 1222 // Basic time-based querying of history.
1282 void HistoryBackend::QueryHistoryBasic(URLDatabase* url_db, 1223 void HistoryBackend::QueryHistoryBasic(const QueryOptions& options,
1283 VisitDatabase* visit_db,
1284 const QueryOptions& options,
1285 QueryResults* result) { 1224 QueryResults* result) {
1286 // First get all visits. 1225 // First get all visits.
1287 VisitVector visits; 1226 VisitVector visits;
1288 bool has_more_results = visit_db->GetVisibleVisitsInRange(options, &visits); 1227 bool has_more_results = db_->GetVisibleVisitsInRange(options, &visits);
1289 DCHECK(static_cast<int>(visits.size()) <= options.EffectiveMaxCount()); 1228 DCHECK(static_cast<int>(visits.size()) <= options.EffectiveMaxCount());
1290 1229
1291 // Now add them and the URL rows to the results. 1230 // Now add them and the URL rows to the results.
1292 URLResult url_result; 1231 URLResult url_result;
1293 for (size_t i = 0; i < visits.size(); i++) { 1232 for (size_t i = 0; i < visits.size(); i++) {
1294 const VisitRow visit = visits[i]; 1233 const VisitRow visit = visits[i];
1295 1234
1296 // Add a result row for this visit, get the URL info from the DB. 1235 // Add a result row for this visit, get the URL info from the DB.
1297 if (!url_db->GetURLRow(visit.url_id, &url_result)) { 1236 if (!db_->GetURLRow(visit.url_id, &url_result)) {
1298 VLOG(0) << "Failed to get id " << visit.url_id 1237 VLOG(0) << "Failed to get id " << visit.url_id
1299 << " from history.urls."; 1238 << " from history.urls.";
1300 continue; // DB out of sync and URL doesn't exist, try to recover. 1239 continue; // DB out of sync and URL doesn't exist, try to recover.
1301 } 1240 }
1302 1241
1303 if (!url_result.url().is_valid()) { 1242 if (!url_result.url().is_valid()) {
1304 VLOG(0) << "Got invalid URL from history.urls with id " 1243 VLOG(0) << "Got invalid URL from history.urls with id "
1305 << visit.url_id << ": " 1244 << visit.url_id << ": "
1306 << url_result.url().possibly_invalid_spec(); 1245 << url_result.url().possibly_invalid_spec();
1307 continue; // Don't report invalid URLs in case of corruption. 1246 continue; // Don't report invalid URLs in case of corruption.
1308 } 1247 }
1309 1248
1310 // The archived database may be out of sync with respect to starring,
1311 // titles, last visit date, etc. Therefore, we query the main DB if the
1312 // current URL database is not the main one.
1313 if (url_db == db_.get()) {
engedy 2014/04/16 18:08:10 Note: I think this should have been a non-equality
1314 // Currently querying the archived DB, update with the main database to
1315 // catch any interesting stuff. This will update it if it exists in the
1316 // main DB, and do nothing otherwise.
1317 db_->GetRowForURL(url_result.url(), &url_result);
1318 }
1319
1320 url_result.set_visit_time(visit.visit_time); 1249 url_result.set_visit_time(visit.visit_time);
1321 1250
1322 // Set whether the visit was blocked for a managed user by looking at the 1251 // Set whether the visit was blocked for a managed user by looking at the
1323 // transition type. 1252 // transition type.
1324 url_result.set_blocked_visit( 1253 url_result.set_blocked_visit(
1325 (visit.transition & content::PAGE_TRANSITION_BLOCKED) != 0); 1254 (visit.transition & content::PAGE_TRANSITION_BLOCKED) != 0);
1326 1255
1327 // We don't set any of the query-specific parts of the URLResult, since 1256 // We don't set any of the query-specific parts of the URLResult, since
1328 // snippets and stuff don't apply to basic querying. 1257 // snippets and stuff don't apply to basic querying.
1329 result->AppendURLBySwapping(&url_result); 1258 result->AppendURLBySwapping(&url_result);
1330 } 1259 }
1331 1260
1332 if (!has_more_results && options.begin_time <= first_recorded_time_) 1261 if (!has_more_results && options.begin_time <= first_recorded_time_)
1333 result->set_reached_beginning(true); 1262 result->set_reached_beginning(true);
1334 } 1263 }
1335 1264
1336 // Text-based querying of history. 1265 // Text-based querying of history.
1337 void HistoryBackend::QueryHistoryText(URLDatabase* url_db, 1266 void HistoryBackend::QueryHistoryText(const base::string16& text_query,
1338 VisitDatabase* visit_db,
1339 const base::string16& text_query,
1340 const QueryOptions& options, 1267 const QueryOptions& options,
1341 QueryResults* result) { 1268 QueryResults* result) {
1342 URLRows text_matches; 1269 URLRows text_matches;
1343 url_db->GetTextMatches(text_query, &text_matches); 1270 db_->GetTextMatches(text_query, &text_matches);
1344 1271
1345 std::vector<URLResult> matching_visits; 1272 std::vector<URLResult> matching_visits;
1346 VisitVector visits; // Declare outside loop to prevent re-construction. 1273 VisitVector visits; // Declare outside loop to prevent re-construction.
1347 for (size_t i = 0; i < text_matches.size(); i++) { 1274 for (size_t i = 0; i < text_matches.size(); i++) {
1348 const URLRow& text_match = text_matches[i]; 1275 const URLRow& text_match = text_matches[i];
1349 // Get all visits for given URL match. 1276 // Get all visits for given URL match.
1350 visit_db->GetVisibleVisitsForURL(text_match.id(), options, &visits); 1277 db_->GetVisibleVisitsForURL(text_match.id(), options, &visits);
1351 for (size_t j = 0; j < visits.size(); j++) { 1278 for (size_t j = 0; j < visits.size(); j++) {
1352 URLResult url_result(text_match); 1279 URLResult url_result(text_match);
1353 url_result.set_visit_time(visits[j].visit_time); 1280 url_result.set_visit_time(visits[j].visit_time);
1354 matching_visits.push_back(url_result); 1281 matching_visits.push_back(url_result);
1355 } 1282 }
1356 } 1283 }
1357 1284
1358 std::sort(matching_visits.begin(), matching_visits.end(), 1285 std::sort(matching_visits.begin(), matching_visits.end(),
1359 URLResult::CompareVisitTime); 1286 URLResult::CompareVisitTime);
1360 1287
(...skipping 1103 matching lines...) Expand 10 before | Expand all | Expand 10 after
2464 db_->CommitTransaction(); 2391 db_->CommitTransaction();
2465 DCHECK(db_->transaction_nesting() == 0) << "Somebody left a transaction open"; 2392 DCHECK(db_->transaction_nesting() == 0) << "Somebody left a transaction open";
2466 db_->BeginTransaction(); 2393 db_->BeginTransaction();
2467 2394
2468 if (thumbnail_db_) { 2395 if (thumbnail_db_) {
2469 thumbnail_db_->CommitTransaction(); 2396 thumbnail_db_->CommitTransaction();
2470 DCHECK(thumbnail_db_->transaction_nesting() == 0) << 2397 DCHECK(thumbnail_db_->transaction_nesting() == 0) <<
2471 "Somebody left a transaction open"; 2398 "Somebody left a transaction open";
2472 thumbnail_db_->BeginTransaction(); 2399 thumbnail_db_->BeginTransaction();
2473 } 2400 }
2474
2475 if (archived_db_) {
2476 archived_db_->CommitTransaction();
2477 archived_db_->BeginTransaction();
2478 }
2479 } 2401 }
2480 2402
2481 void HistoryBackend::ScheduleCommit() { 2403 void HistoryBackend::ScheduleCommit() {
2482 if (scheduled_commit_.get()) 2404 if (scheduled_commit_.get())
2483 return; 2405 return;
2484 scheduled_commit_ = new CommitLaterTask(this); 2406 scheduled_commit_ = new CommitLaterTask(this);
2485 base::MessageLoop::current()->PostDelayedTask( 2407 base::MessageLoop::current()->PostDelayedTask(
2486 FROM_HERE, 2408 FROM_HERE,
2487 base::Bind(&CommitLaterTask::RunCommit, scheduled_commit_.get()), 2409 base::Bind(&CommitLaterTask::RunCommit, scheduled_commit_.get()),
2488 base::TimeDelta::FromSeconds(kCommitIntervalSeconds)); 2410 base::TimeDelta::FromSeconds(kCommitIntervalSeconds));
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after
2595 << times.begin()->ToJsTime() << " v.s. " << begin_time.ToJsTime(); 2517 << times.begin()->ToJsTime() << " v.s. " << begin_time.ToJsTime();
2596 DCHECK(*times.rbegin() < end_time) 2518 DCHECK(*times.rbegin() < end_time)
2597 << "Max time is after end time: " 2519 << "Max time is after end time: "
2598 << times.rbegin()->ToJsTime() << " v.s. " << end_time.ToJsTime(); 2520 << times.rbegin()->ToJsTime() << " v.s. " << end_time.ToJsTime();
2599 2521
2600 history::QueryOptions options; 2522 history::QueryOptions options;
2601 options.begin_time = begin_time; 2523 options.begin_time = begin_time;
2602 options.end_time = end_time; 2524 options.end_time = end_time;
2603 options.duplicate_policy = QueryOptions::KEEP_ALL_DUPLICATES; 2525 options.duplicate_policy = QueryOptions::KEEP_ALL_DUPLICATES;
2604 QueryResults results; 2526 QueryResults results;
2605 QueryHistoryBasic(db_.get(), db_.get(), options, &results); 2527 QueryHistoryBasic(options, &results);
2606 2528
2607 // 1st pass: find URLs that are visited at one of |times|. 2529 // 1st pass: find URLs that are visited at one of |times|.
2608 std::set<GURL> urls; 2530 std::set<GURL> urls;
2609 for (size_t i = 0; i < results.size(); ++i) { 2531 for (size_t i = 0; i < results.size(); ++i) {
2610 if (times.count(results[i].visit_time()) > 0) 2532 if (times.count(results[i].visit_time()) > 0)
2611 urls.insert(results[i].url()); 2533 urls.insert(results[i].url());
2612 } 2534 }
2613 if (urls.empty()) 2535 if (urls.empty())
2614 return; 2536 return;
2615 2537
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after
2700 bool success = db_->Raze(); 2622 bool success = db_->Raze();
2701 UMA_HISTOGRAM_BOOLEAN("History.KillHistoryDatabaseResult", success); 2623 UMA_HISTOGRAM_BOOLEAN("History.KillHistoryDatabaseResult", success);
2702 2624
2703 #if defined(OS_ANDROID) 2625 #if defined(OS_ANDROID)
2704 // Release AndroidProviderBackend before other objects. 2626 // Release AndroidProviderBackend before other objects.
2705 android_provider_backend_.reset(); 2627 android_provider_backend_.reset();
2706 #endif 2628 #endif
2707 2629
2708 // The expirer keeps tabs on the active databases. Tell it about the 2630 // The expirer keeps tabs on the active databases. Tell it about the
2709 // databases which will be closed. 2631 // databases which will be closed.
2710 expirer_.SetDatabases(NULL, NULL, NULL); 2632 expirer_.SetDatabases(NULL, NULL);
2711 2633
2712 // Reopen a new transaction for |db_| for the sake of CloseAllDatabases(). 2634 // Reopen a new transaction for |db_| for the sake of CloseAllDatabases().
2713 db_->BeginTransaction(); 2635 db_->BeginTransaction();
2714 CloseAllDatabases(); 2636 CloseAllDatabases();
2715 } 2637 }
2716 2638
2717 void HistoryBackend::ProcessDBTask( 2639 void HistoryBackend::ProcessDBTask(
2718 scoped_refptr<HistoryDBTaskRequest> request) { 2640 scoped_refptr<HistoryDBTaskRequest> request) {
2719 DCHECK(request.get()); 2641 DCHECK(request.get());
2720 if (request->canceled()) 2642 if (request->canceled())
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
2789 // history, we should delete as much as we can. 2711 // history, we should delete as much as we can.
2790 } 2712 }
2791 2713
2792 // ClearAllMainHistory will change the IDs of the URLs in kept_urls. 2714 // ClearAllMainHistory will change the IDs of the URLs in kept_urls.
2793 // Therefore, we clear the list afterwards to make sure nobody uses this 2715 // Therefore, we clear the list afterwards to make sure nobody uses this
2794 // invalid data. 2716 // invalid data.
2795 if (!ClearAllMainHistory(kept_urls)) 2717 if (!ClearAllMainHistory(kept_urls))
2796 LOG(ERROR) << "Main history could not be cleared"; 2718 LOG(ERROR) << "Main history could not be cleared";
2797 kept_urls.clear(); 2719 kept_urls.clear();
2798 2720
2799 // Delete archived history.
2800 if (archived_db_) {
2801 // Close the database and delete the file.
2802 archived_db_.reset();
2803 base::FilePath archived_file_name = GetArchivedFileName();
2804 sql::Connection::Delete(archived_file_name);
2805
2806 // Now re-initialize the database (which may fail).
2807 archived_db_.reset(new ArchivedDatabase());
2808 if (!archived_db_->Init(archived_file_name)) {
2809 LOG(WARNING) << "Could not initialize the archived database.";
2810 archived_db_.reset();
2811 } else {
2812 // Open our long-running transaction on this database.
2813 archived_db_->BeginTransaction();
2814 }
2815 }
2816
2817 db_->GetStartDate(&first_recorded_time_); 2721 db_->GetStartDate(&first_recorded_time_);
2818 2722
2819 // Send out the notification that history is cleared. The in-memory database 2723 // Send out the notification that history is cleared. The in-memory database
2820 // will pick this up and clear itself. 2724 // will pick this up and clear itself.
2821 scoped_ptr<URLsDeletedDetails> details(new URLsDeletedDetails); 2725 scoped_ptr<URLsDeletedDetails> details(new URLsDeletedDetails);
2822 details->all_history = true; 2726 details->all_history = true;
2823 NotifySyncURLsDeleted(true, false, NULL); 2727 NotifySyncURLsDeleted(true, false, NULL);
2824 BroadcastNotifications(chrome::NOTIFICATION_HISTORY_URLS_DELETED, 2728 BroadcastNotifications(chrome::NOTIFICATION_HISTORY_URLS_DELETED,
2825 details.PassAs<HistoryDetails>()); 2729 details.PassAs<HistoryDetails>());
2826 } 2730 }
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after
2937 int rank = kPageVisitStatsMaxTopSites; 2841 int rank = kPageVisitStatsMaxTopSites;
2938 std::map<GURL, int>::const_iterator it = most_visited_urls_map_.find(url); 2842 std::map<GURL, int>::const_iterator it = most_visited_urls_map_.find(url);
2939 if (it != most_visited_urls_map_.end()) 2843 if (it != most_visited_urls_map_.end())
2940 rank = (*it).second; 2844 rank = (*it).second;
2941 UMA_HISTOGRAM_ENUMERATION("History.TopSitesVisitsByRank", 2845 UMA_HISTOGRAM_ENUMERATION("History.TopSitesVisitsByRank",
2942 rank, kPageVisitStatsMaxTopSites + 1); 2846 rank, kPageVisitStatsMaxTopSites + 1);
2943 } 2847 }
2944 #endif 2848 #endif
2945 2849
2946 } // namespace history 2850 } // namespace history
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698