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/url_index_private_data.h" | 5 #include "chrome/browser/history/url_index_private_data.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 #include <functional> | 8 #include <functional> |
9 #include <iterator> | 9 #include <iterator> |
10 #include <limits> | 10 #include <limits> |
11 #include <numeric> | 11 #include <numeric> |
12 | 12 |
13 #include "base/file_util.h" | 13 #include "base/file_util.h" |
14 #include "base/i18n/case_conversion.h" | 14 #include "base/i18n/case_conversion.h" |
15 #include "base/metrics/histogram.h" | 15 #include "base/metrics/histogram.h" |
16 #include "base/string_util.h" | 16 #include "base/string_util.h" |
17 #include "base/threading/thread_restrictions.h" | 17 #include "base/time.h" |
18 #include "base/utf_string_conversions.h" | 18 #include "base/utf_string_conversions.h" |
19 #include "chrome/browser/autocomplete/autocomplete.h" | 19 #include "chrome/browser/autocomplete/autocomplete.h" |
20 #include "chrome/browser/history/history_database.h" | 20 #include "chrome/browser/history/history_database.h" |
| 21 #include "chrome/browser/history/in_memory_url_index.h" |
21 #include "chrome/common/url_constants.h" | 22 #include "chrome/common/url_constants.h" |
| 23 #include "content/public/browser/notification_details.h" |
| 24 #include "content/public/browser/notification_service.h" |
| 25 #include "content/public/browser/notification_source.h" |
22 #include "net/base/net_util.h" | 26 #include "net/base/net_util.h" |
23 #include "third_party/protobuf/src/google/protobuf/repeated_field.h" | 27 #include "third_party/protobuf/src/google/protobuf/repeated_field.h" |
24 | 28 |
25 using google::protobuf::RepeatedField; | 29 using google::protobuf::RepeatedField; |
26 using google::protobuf::RepeatedPtrField; | 30 using google::protobuf::RepeatedPtrField; |
27 using in_memory_url_index::InMemoryURLIndexCacheItem; | 31 using in_memory_url_index::InMemoryURLIndexCacheItem; |
28 | 32 |
29 namespace history { | 33 namespace history { |
30 | 34 |
31 typedef imui::InMemoryURLIndexCacheItem_WordListItem WordListItem; | 35 typedef imui::InMemoryURLIndexCacheItem_WordListItem WordListItem; |
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
126 void URLIndexPrivateData::Clear() { | 130 void URLIndexPrivateData::Clear() { |
127 word_list_.clear(); | 131 word_list_.clear(); |
128 available_words_.clear(); | 132 available_words_.clear(); |
129 word_map_.clear(); | 133 word_map_.clear(); |
130 char_word_map_.clear(); | 134 char_word_map_.clear(); |
131 word_id_history_map_.clear(); | 135 word_id_history_map_.clear(); |
132 history_id_word_map_.clear(); | 136 history_id_word_map_.clear(); |
133 history_info_map_.clear(); | 137 history_info_map_.clear(); |
134 } | 138 } |
135 | 139 |
| 140 bool URLIndexPrivateData::Empty() const { |
| 141 return history_info_map_.empty(); |
| 142 } |
| 143 |
136 // Cache Updating -------------------------------------------------------------- | 144 // Cache Updating -------------------------------------------------------------- |
137 | 145 |
138 bool URLIndexPrivateData::IndexRow(const URLRow& row) { | 146 bool URLIndexPrivateData::IndexRow(const URLRow& row) { |
139 const GURL& gurl(row.url()); | 147 const GURL& gurl(row.url()); |
140 | 148 |
141 // Index only URLs with a whitelisted scheme. | 149 // Index only URLs with a whitelisted scheme. |
142 if (!URLIndexPrivateData::URLSchemeIsWhitelisted(gurl)) | 150 if (!URLIndexPrivateData::URLSchemeIsWhitelisted(gurl)) |
143 return false; | 151 return false; |
144 | 152 |
145 URLID row_id = row.id(); | 153 URLID row_id = row.id(); |
(...skipping 749 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
895 whitelist->insert(std::string(chrome::kChromeUIScheme)); | 903 whitelist->insert(std::string(chrome::kChromeUIScheme)); |
896 whitelist->insert(std::string(chrome::kFileScheme)); | 904 whitelist->insert(std::string(chrome::kFileScheme)); |
897 whitelist->insert(std::string(chrome::kFtpScheme)); | 905 whitelist->insert(std::string(chrome::kFtpScheme)); |
898 whitelist->insert(std::string(chrome::kHttpScheme)); | 906 whitelist->insert(std::string(chrome::kHttpScheme)); |
899 whitelist->insert(std::string(chrome::kHttpsScheme)); | 907 whitelist->insert(std::string(chrome::kHttpsScheme)); |
900 whitelist->insert(std::string(chrome::kMailToScheme)); | 908 whitelist->insert(std::string(chrome::kMailToScheme)); |
901 } | 909 } |
902 | 910 |
903 // Cache Saving ---------------------------------------------------------------- | 911 // Cache Saving ---------------------------------------------------------------- |
904 | 912 |
| 913 // static |
| 914 void URLIndexPrivateData::WritePrivateDataToCacheFileTask( |
| 915 URLIndexPrivateData* private_data, |
| 916 const FilePath& file_path, |
| 917 bool* succeeded) { |
| 918 DCHECK(private_data); |
| 919 DCHECK(!file_path.empty()); |
| 920 DCHECK(succeeded); |
| 921 *succeeded = private_data->SaveToFile(file_path); |
| 922 } |
| 923 |
905 bool URLIndexPrivateData::SaveToFile(const FilePath& file_path) { | 924 bool URLIndexPrivateData::SaveToFile(const FilePath& file_path) { |
906 // TODO(mrossetti): Move File IO to another thread. | |
907 base::ThreadRestrictions::ScopedAllowIO allow_io; | |
908 base::TimeTicks beginning_time = base::TimeTicks::Now(); | 925 base::TimeTicks beginning_time = base::TimeTicks::Now(); |
909 InMemoryURLIndexCacheItem index_cache; | 926 InMemoryURLIndexCacheItem index_cache; |
910 SavePrivateData(&index_cache); | 927 SavePrivateData(&index_cache); |
911 std::string data; | 928 std::string data; |
912 if (!index_cache.SerializeToString(&data)) { | 929 if (!index_cache.SerializeToString(&data)) { |
913 LOG(WARNING) << "Failed to serialize the InMemoryURLIndex cache."; | 930 LOG(WARNING) << "Failed to serialize the InMemoryURLIndex cache."; |
914 return false; | 931 return false; |
915 } | 932 } |
916 | 933 |
917 int size = data.size(); | 934 int size = data.size(); |
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1015 map_entry->set_visit_count(url_row.visit_count()); | 1032 map_entry->set_visit_count(url_row.visit_count()); |
1016 map_entry->set_typed_count(url_row.typed_count()); | 1033 map_entry->set_typed_count(url_row.typed_count()); |
1017 map_entry->set_last_visit(url_row.last_visit().ToInternalValue()); | 1034 map_entry->set_last_visit(url_row.last_visit().ToInternalValue()); |
1018 map_entry->set_url(url_row.url().spec()); | 1035 map_entry->set_url(url_row.url().spec()); |
1019 map_entry->set_title(UTF16ToUTF8(url_row.title())); | 1036 map_entry->set_title(UTF16ToUTF8(url_row.title())); |
1020 } | 1037 } |
1021 } | 1038 } |
1022 | 1039 |
1023 // Cache Restoring ------------------------------------------------------------- | 1040 // Cache Restoring ------------------------------------------------------------- |
1024 | 1041 |
1025 bool URLIndexPrivateData::RestoreFromFile(const FilePath& file_path) { | 1042 // static |
1026 // TODO(mrossetti): Figure out how to determine if the cache is up-to-date. | 1043 void URLIndexPrivateData::RestoreFromFileTask(const FilePath& file_path, |
1027 // That is: ensure that the database has not been modified since the cache | 1044 URLIndexPrivateData* data) { |
1028 // was last saved. DB file modification date is inadequate. There are no | 1045 data = URLIndexPrivateData::RestoreFromFile(file_path); |
1029 // SQLite table checksums automatically stored. | 1046 } |
1030 Clear(); // Start with a clean slate. | |
1031 | 1047 |
1032 // FIXME(mrossetti): Move File IO to another thread. | 1048 // static |
1033 base::ThreadRestrictions::ScopedAllowIO allow_io; | 1049 URLIndexPrivateData* URLIndexPrivateData::RestoreFromFile( |
| 1050 const FilePath& file_path) { |
1034 base::TimeTicks beginning_time = base::TimeTicks::Now(); | 1051 base::TimeTicks beginning_time = base::TimeTicks::Now(); |
1035 if (!file_util::PathExists(file_path)) | 1052 if (!file_util::PathExists(file_path)) |
1036 return false; | 1053 return NULL; |
1037 std::string data; | 1054 std::string data; |
1038 // If there is no cache file then simply give up. This will cause us to | 1055 // If there is no cache file then simply give up. This will cause us to |
1039 // attempt to rebuild from the history database. | 1056 // attempt to rebuild from the history database. |
1040 if (!file_util::ReadFileToString(file_path, &data)) | 1057 if (!file_util::ReadFileToString(file_path, &data)) |
1041 return false; | 1058 return NULL; |
1042 | 1059 |
| 1060 scoped_ptr<URLIndexPrivateData> restored_data(new URLIndexPrivateData); |
1043 InMemoryURLIndexCacheItem index_cache; | 1061 InMemoryURLIndexCacheItem index_cache; |
1044 if (!index_cache.ParseFromArray(data.c_str(), data.size())) { | 1062 if (!index_cache.ParseFromArray(data.c_str(), data.size())) { |
1045 LOG(WARNING) << "Failed to parse InMemoryURLIndex cache data read from " | 1063 LOG(WARNING) << "Failed to parse URLIndexPrivateData cache data read from " |
1046 << file_path.value(); | 1064 << file_path.value(); |
1047 return false; | 1065 return restored_data.release(); |
1048 } | 1066 } |
1049 | 1067 |
1050 if (!RestorePrivateData(index_cache)) { | 1068 if (!restored_data->RestorePrivateData(index_cache)) { |
1051 Clear(); // Back to square one -- must build from scratch. | 1069 restored_data.reset(); // Back to square one -- must build from history DB. |
1052 return false; | 1070 return NULL; |
1053 } | 1071 } |
1054 | 1072 |
1055 UMA_HISTOGRAM_TIMES("History.InMemoryURLIndexRestoreCacheTime", | 1073 UMA_HISTOGRAM_TIMES("History.InMemoryURLIndexRestoreCacheTime", |
1056 base::TimeTicks::Now() - beginning_time); | 1074 base::TimeTicks::Now() - beginning_time); |
1057 UMA_HISTOGRAM_COUNTS("History.InMemoryURLHistoryItems", | 1075 UMA_HISTOGRAM_COUNTS("History.InMemoryURLHistoryItems", |
1058 history_id_word_map_.size()); | 1076 restored_data->history_id_word_map_.size()); |
1059 UMA_HISTOGRAM_COUNTS("History.InMemoryURLCacheSize", data.size()); | 1077 UMA_HISTOGRAM_COUNTS("History.InMemoryURLCacheSize", data.size()); |
1060 UMA_HISTOGRAM_COUNTS_10000("History.InMemoryURLWords", word_map_.size()); | 1078 UMA_HISTOGRAM_COUNTS_10000("History.InMemoryURLWords", |
1061 UMA_HISTOGRAM_COUNTS_10000("History.InMemoryURLChars", char_word_map_.size()); | 1079 restored_data->word_map_.size()); |
1062 return true; | 1080 UMA_HISTOGRAM_COUNTS_10000("History.InMemoryURLChars", |
| 1081 restored_data->char_word_map_.size()); |
| 1082 if (restored_data->Empty()) |
| 1083 restored_data.reset(); // 'No data' is the same as a failed reload. |
| 1084 return restored_data.release(); |
1063 } | 1085 } |
1064 | 1086 |
1065 // static | 1087 // static |
1066 URLIndexPrivateData* URLIndexPrivateData::RebuildFromHistory( | 1088 URLIndexPrivateData* URLIndexPrivateData::RebuildFromHistory( |
1067 HistoryDatabase* history_db) { | 1089 HistoryDatabase* history_db) { |
1068 if (!history_db) | 1090 if (!history_db) |
1069 return NULL; | 1091 return NULL; |
1070 | 1092 |
1071 base::TimeTicks beginning_time = base::TimeTicks::Now(); | 1093 base::TimeTicks beginning_time = base::TimeTicks::Now(); |
1072 | 1094 |
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1207 if (iter->has_title()) { | 1229 if (iter->has_title()) { |
1208 string16 title(UTF8ToUTF16(iter->title())); | 1230 string16 title(UTF8ToUTF16(iter->title())); |
1209 url_row.set_title(title); | 1231 url_row.set_title(title); |
1210 } | 1232 } |
1211 history_info_map_[history_id] = url_row; | 1233 history_info_map_[history_id] = url_row; |
1212 } | 1234 } |
1213 return true; | 1235 return true; |
1214 } | 1236 } |
1215 | 1237 |
1216 } // namespace history | 1238 } // namespace history |
OLD | NEW |