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

Side by Side Diff: components/offline_pages/offline_page_metadata_store_impl.cc

Issue 1694863003: Refactor the offline page storage to include client namespace and id. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: address comments Created 4 years, 9 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
OLDNEW
1 // Copyright 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 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 "components/offline_pages/offline_page_metadata_store_impl.h" 5 #include "components/offline_pages/offline_page_metadata_store_impl.h"
6 6
7 #include <string> 7 #include <string>
8 #include <utility> 8 #include <utility>
9 #include <vector> 9 #include <vector>
10 10
11 #include "base/bind.h" 11 #include "base/bind.h"
12 #include "base/files/file_path.h" 12 #include "base/files/file_path.h"
13 #include "base/location.h" 13 #include "base/location.h"
14 #include "base/metrics/histogram_macros.h" 14 #include "base/metrics/histogram_macros.h"
15 #include "base/sequenced_task_runner.h" 15 #include "base/sequenced_task_runner.h"
16 #include "base/strings/string_number_conversions.h" 16 #include "base/strings/string_number_conversions.h"
17 #include "base/strings/utf_string_conversions.h" 17 #include "base/strings/utf_string_conversions.h"
18 #include "base/thread_task_runner_handle.h" 18 #include "base/thread_task_runner_handle.h"
19 #include "build/build_config.h" 19 #include "build/build_config.h"
20 #include "components/leveldb_proto/proto_database_impl.h" 20 #include "components/leveldb_proto/proto_database_impl.h"
21 #include "components/offline_pages/offline_page_item.h" 21 #include "components/offline_pages/offline_page_item.h"
22 #include "components/offline_pages/offline_page_model.h"
22 #include "components/offline_pages/proto/offline_pages.pb.h" 23 #include "components/offline_pages/proto/offline_pages.pb.h"
23 #include "third_party/leveldatabase/env_chromium.h" 24 #include "third_party/leveldatabase/env_chromium.h"
24 #include "third_party/leveldatabase/src/include/leveldb/db.h" 25 #include "third_party/leveldatabase/src/include/leveldb/db.h"
25 #include "url/gurl.h" 26 #include "url/gurl.h"
26 27
27 using leveldb_proto::ProtoDatabase; 28 using leveldb_proto::ProtoDatabase;
28 29
29 namespace { 30 namespace {
30 // Statistics are logged to UMA with this string as part of histogram name. They 31 // Statistics are logged to UMA with this string as part of histogram name. They
31 // can all be found under LevelDB.*.OfflinePageMetadataStore. Changing this 32 // can all be found under LevelDB.*.OfflinePageMetadataStore. Changing this
32 // needs to synchronize with histograms.xml, AND will also become incompatible 33 // needs to synchronize with histograms.xml, AND will also become incompatible
33 // with older browsers still reporting the previous values. 34 // with older browsers still reporting the previous values.
34 const char kDatabaseUMAClientName[] = "OfflinePageMetadataStore"; 35 const char kDatabaseUMAClientName[] = "OfflinePageMetadataStore";
35 } 36 }
36 37
37 namespace offline_pages { 38 namespace offline_pages {
38 namespace { 39 namespace {
39 40
40 void OfflinePageItemToEntry(const OfflinePageItem& item, 41 void OfflinePageItemToEntry(const OfflinePageItem& item,
41 offline_pages::OfflinePageEntry* item_proto) { 42 offline_pages::OfflinePageEntry* item_proto) {
42 DCHECK(item_proto); 43 DCHECK(item_proto);
43 item_proto->set_url(item.url.spec()); 44 item_proto->set_url(item.url.spec());
44 item_proto->set_bookmark_id(item.bookmark_id); 45 item_proto->set_offline_id(item.offline_id);
45 item_proto->set_version(item.version); 46 item_proto->set_version(item.version);
46 std::string path_string; 47 std::string path_string;
47 #if defined(OS_POSIX) 48 #if defined(OS_POSIX)
48 path_string = item.file_path.value(); 49 path_string = item.file_path.value();
49 #elif defined(OS_WIN) 50 #elif defined(OS_WIN)
50 path_string = base::WideToUTF8(item.file_path.value()); 51 path_string = base::WideToUTF8(item.file_path.value());
51 #endif 52 #endif
52 item_proto->set_file_path(path_string); 53 item_proto->set_file_path(path_string);
53 item_proto->set_file_size(item.file_size); 54 item_proto->set_file_size(item.file_size);
54 item_proto->set_creation_time(item.creation_time.ToInternalValue()); 55 item_proto->set_creation_time(item.creation_time.ToInternalValue());
55 item_proto->set_last_access_time(item.last_access_time.ToInternalValue()); 56 item_proto->set_last_access_time(item.last_access_time.ToInternalValue());
56 item_proto->set_access_count(item.access_count); 57 item_proto->set_access_count(item.access_count);
57 item_proto->set_flags( 58 item_proto->set_flags(
58 static_cast<::offline_pages::OfflinePageEntry_Flags>(item.flags)); 59 static_cast<::offline_pages::OfflinePageEntry_Flags>(item.flags));
60 item_proto->set_client_id_name_space(item.client_id.name_space);
61 item_proto->set_client_id(item.client_id.id);
59 } 62 }
60 63
61 bool OfflinePageItemFromEntry(const offline_pages::OfflinePageEntry& item_proto, 64 bool OfflinePageItemFromEntry(const offline_pages::OfflinePageEntry& item_proto,
62 OfflinePageItem* item) { 65 OfflinePageItem* item) {
63 DCHECK(item); 66 DCHECK(item);
64 if (!item_proto.has_url() || !item_proto.has_bookmark_id() || 67 bool has_offline_id =
65 !item_proto.has_version() || !item_proto.has_file_path()) { 68 item_proto.has_offline_id() || item_proto.has_deprecated_bookmark_id();
69 if (!item_proto.has_url() || !has_offline_id || !item_proto.has_version() ||
70 !item_proto.has_file_path()) {
66 return false; 71 return false;
67 } 72 }
68 item->url = GURL(item_proto.url()); 73 item->url = GURL(item_proto.url());
69 item->bookmark_id = item_proto.bookmark_id(); 74 item->offline_id = item_proto.offline_id();
70 item->version = item_proto.version(); 75 item->version = item_proto.version();
71 #if defined(OS_POSIX) 76 #if defined(OS_POSIX)
72 item->file_path = base::FilePath(item_proto.file_path()); 77 item->file_path = base::FilePath(item_proto.file_path());
73 #elif defined(OS_WIN) 78 #elif defined(OS_WIN)
74 item->file_path = base::FilePath(base::UTF8ToWide(item_proto.file_path())); 79 item->file_path = base::FilePath(base::UTF8ToWide(item_proto.file_path()));
75 #endif 80 #endif
76 if (item_proto.has_file_size()) { 81 if (item_proto.has_file_size()) {
77 item->file_size = item_proto.file_size(); 82 item->file_size = item_proto.file_size();
78 } 83 }
79 if (item_proto.has_creation_time()) { 84 if (item_proto.has_creation_time()) {
80 item->creation_time = 85 item->creation_time =
81 base::Time::FromInternalValue(item_proto.creation_time()); 86 base::Time::FromInternalValue(item_proto.creation_time());
82 } 87 }
83 if (item_proto.has_last_access_time()) { 88 if (item_proto.has_last_access_time()) {
84 item->last_access_time = 89 item->last_access_time =
85 base::Time::FromInternalValue(item_proto.last_access_time()); 90 base::Time::FromInternalValue(item_proto.last_access_time());
86 } 91 }
87 if (item_proto.has_access_count()) { 92 if (item_proto.has_access_count()) {
88 item->access_count = item_proto.access_count(); 93 item->access_count = item_proto.access_count();
89 } 94 }
90 if (item_proto.has_flags()) { 95 if (item_proto.has_flags()) {
91 item->flags = static_cast<OfflinePageItem::Flags>(item_proto.flags()); 96 item->flags = static_cast<OfflinePageItem::Flags>(item_proto.flags());
92 } 97 }
98 item->client_id.name_space = item_proto.client_id_name_space();
99 item->client_id.id = item_proto.client_id();
100
93 return true; 101 return true;
94 } 102 }
95 103
96 } // namespace 104 } // namespace
97 105
98 OfflinePageMetadataStoreImpl::OfflinePageMetadataStoreImpl( 106 OfflinePageMetadataStoreImpl::OfflinePageMetadataStoreImpl(
99 scoped_refptr<base::SequencedTaskRunner> background_task_runner, 107 scoped_refptr<base::SequencedTaskRunner> background_task_runner,
100 const base::FilePath& database_dir) 108 const base::FilePath& database_dir)
101 : background_task_runner_(background_task_runner), 109 : background_task_runner_(background_task_runner),
102 database_dir_(database_dir), 110 database_dir_(database_dir),
(...skipping 30 matching lines...) Expand all
133 callback)); 141 callback));
134 } 142 }
135 143
136 void OfflinePageMetadataStoreImpl::LoadDone( 144 void OfflinePageMetadataStoreImpl::LoadDone(
137 const LoadCallback& callback, 145 const LoadCallback& callback,
138 bool success, 146 bool success,
139 scoped_ptr<std::vector<OfflinePageEntry>> entries) { 147 scoped_ptr<std::vector<OfflinePageEntry>> entries) {
140 DCHECK(entries); 148 DCHECK(entries);
141 149
142 std::vector<OfflinePageItem> result; 150 std::vector<OfflinePageItem> result;
151 scoped_ptr<ProtoDatabase<OfflinePageEntry>::KeyEntryVector> entries_to_update(
152 new ProtoDatabase<OfflinePageEntry>::KeyEntryVector());
153 scoped_ptr<std::vector<std::string>> keys_to_remove(
154 new std::vector<std::string>());
155
143 LoadStatus status = LOAD_SUCCEEDED; 156 LoadStatus status = LOAD_SUCCEEDED;
144 157
145 if (success) { 158 if (success) {
146 for (const auto& entry : *entries) { 159 for (auto& entry : *entries) {
147 OfflinePageItem item; 160 OfflinePageItem item;
148 // We don't want to fail the entire database if one item is corrupt, 161 // We don't want to fail the entire database if one item is corrupt,
149 // so log error and keep going. 162 // so log error and keep going.
150 if (!OfflinePageItemFromEntry(entry, &item)) { 163 if (!OfflinePageItemFromEntry(entry, &item)) {
151 LOG(ERROR) << "failed to parse entry: " << entry.url() << " skipping."; 164 LOG(ERROR) << "failed to parse entry: " << entry.url() << " skipping.";
152 continue; 165 continue;
153 } 166 }
167 // Legacy storage. We upgrade them to the new offline_id keyed storage.
168 // TODO(bburns): Remove this eventually when we are sure everyone is
169 // upgraded.
170 if (!entry.has_offline_id()) {
171 entry.set_offline_id(OfflinePageModel::GenerateOfflineId());
172 item.offline_id = entry.offline_id();
173
174 if (entry.has_deprecated_bookmark_id()) {
175 item.client_id.name_space = offline_pages::BOOKMARK_NAMESPACE;
176 item.client_id.id =
177 base::Int64ToString(entry.deprecated_bookmark_id());
dewittj 2016/02/26 18:42:56 I don't think this should be mandatory to land thi
bburns 2016/02/27 00:48:19 hrm, I'm not sure that belongs in bookmark code, g
178 }
179
180 entries_to_update->push_back(
181 std::make_pair(base::Int64ToString(entry.offline_id()), entry));
182 keys_to_remove->push_back(
183 base::Int64ToString(entry.deprecated_bookmark_id()));
184 }
154 result.push_back(item); 185 result.push_back(item);
155 } 186 }
156 } else { 187 } else {
157 status = STORE_LOAD_FAILED; 188 status = STORE_LOAD_FAILED;
158 } 189 }
159 190
160 // If we couldn't load _anything_ report a parse failure. 191 // If we couldn't load _anything_ report a parse failure.
161 if (entries->size() > 0 && result.size() == 0) { 192 if (entries->size() > 0 && result.size() == 0) {
162 status = DATA_PARSING_FAILED; 193 status = DATA_PARSING_FAILED;
163 } 194 }
164 195
165 NotifyLoadResult(callback, status, result); 196 if (status == LOAD_SUCCEEDED && entries_to_update->size() > 0) {
197 UpdateEntries(std::move(entries_to_update), std::move(keys_to_remove),
198 base::Bind(&OfflinePageMetadataStoreImpl::DatabaseUpdateDone,
199 weak_ptr_factory_.GetWeakPtr(), callback, status,
200 std::move(result)));
201 } else {
202 NotifyLoadResult(callback, status, result);
203 }
166 } 204 }
167 205
168 void OfflinePageMetadataStoreImpl::NotifyLoadResult( 206 void OfflinePageMetadataStoreImpl::NotifyLoadResult(
169 const LoadCallback& callback, 207 const LoadCallback& callback,
170 LoadStatus status, 208 LoadStatus status,
171 const std::vector<OfflinePageItem>& result) { 209 const std::vector<OfflinePageItem>& result) {
172 UMA_HISTOGRAM_ENUMERATION("OfflinePages.LoadStatus", 210 UMA_HISTOGRAM_ENUMERATION("OfflinePages.LoadStatus",
173 status, 211 status,
174 OfflinePageMetadataStore::LOAD_STATUS_COUNT); 212 OfflinePageMetadataStore::LOAD_STATUS_COUNT);
175 if (status == LOAD_SUCCEEDED) { 213 if (status == LOAD_SUCCEEDED) {
176 UMA_HISTOGRAM_COUNTS("OfflinePages.SavedPageCount", result.size()); 214 UMA_HISTOGRAM_COUNTS("OfflinePages.SavedPageCount", result.size());
177 } else { 215 } else {
178 DVLOG(1) << "Offline pages database loading failed: " << status; 216 DVLOG(1) << "Offline pages database loading failed: " << status;
179 database_.reset(); 217 database_.reset();
180 } 218 }
181 callback.Run(status, result); 219 callback.Run(status, result);
182 } 220 }
183 221
184 void OfflinePageMetadataStoreImpl::AddOrUpdateOfflinePage( 222 void OfflinePageMetadataStoreImpl::AddOrUpdateOfflinePage(
185 const OfflinePageItem& offline_page_item, 223 const OfflinePageItem& offline_page_item,
186 const UpdateCallback& callback) { 224 const UpdateCallback& callback) {
187 scoped_ptr<ProtoDatabase<OfflinePageEntry>::KeyEntryVector> entries_to_save( 225 scoped_ptr<ProtoDatabase<OfflinePageEntry>::KeyEntryVector> entries_to_save(
188 new ProtoDatabase<OfflinePageEntry>::KeyEntryVector()); 226 new ProtoDatabase<OfflinePageEntry>::KeyEntryVector());
189 scoped_ptr<std::vector<std::string>> keys_to_remove( 227 scoped_ptr<std::vector<std::string>> keys_to_remove(
190 new std::vector<std::string>()); 228 new std::vector<std::string>());
191 229
192 OfflinePageEntry offline_page_proto; 230 OfflinePageEntry offline_page_proto;
193 OfflinePageItemToEntry(offline_page_item, &offline_page_proto); 231 OfflinePageItemToEntry(offline_page_item, &offline_page_proto);
194 entries_to_save->push_back( 232
195 std::make_pair(base::Int64ToString(offline_page_item.bookmark_id), 233 entries_to_save->push_back(std::make_pair(
196 offline_page_proto)); 234 base::Int64ToString(offline_page_item.offline_id), offline_page_proto));
197 235
198 UpdateEntries(std::move(entries_to_save), std::move(keys_to_remove), 236 UpdateEntries(std::move(entries_to_save), std::move(keys_to_remove),
199 callback); 237 callback);
200 } 238 }
201 239
202 void OfflinePageMetadataStoreImpl::RemoveOfflinePages( 240 void OfflinePageMetadataStoreImpl::RemoveOfflinePages(
203 const std::vector<int64_t>& bookmark_ids, 241 const std::vector<int64_t>& offline_ids,
204 const UpdateCallback& callback) { 242 const UpdateCallback& callback) {
205 scoped_ptr<ProtoDatabase<OfflinePageEntry>::KeyEntryVector> entries_to_save( 243 scoped_ptr<ProtoDatabase<OfflinePageEntry>::KeyEntryVector> entries_to_save(
206 new ProtoDatabase<OfflinePageEntry>::KeyEntryVector()); 244 new ProtoDatabase<OfflinePageEntry>::KeyEntryVector());
207 scoped_ptr<std::vector<std::string>> keys_to_remove( 245 scoped_ptr<std::vector<std::string>> keys_to_remove(
208 new std::vector<std::string>()); 246 new std::vector<std::string>());
209 247
210 for (int64_t id : bookmark_ids) 248 for (int64_t id : offline_ids)
211 keys_to_remove->push_back(base::Int64ToString(id)); 249 keys_to_remove->push_back(base::Int64ToString(id));
212 250
213 UpdateEntries(std::move(entries_to_save), std::move(keys_to_remove), 251 UpdateEntries(std::move(entries_to_save), std::move(keys_to_remove),
214 callback); 252 callback);
215 } 253 }
216 254
217 void OfflinePageMetadataStoreImpl::UpdateEntries( 255 void OfflinePageMetadataStoreImpl::UpdateEntries(
218 scoped_ptr<ProtoDatabase<OfflinePageEntry>::KeyEntryVector> entries_to_save, 256 scoped_ptr<ProtoDatabase<OfflinePageEntry>::KeyEntryVector> entries_to_save,
219 scoped_ptr<std::vector<std::string>> keys_to_remove, 257 scoped_ptr<std::vector<std::string>> keys_to_remove,
220 const UpdateCallback& callback) { 258 const UpdateCallback& callback) {
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
254 } 292 }
255 293
256 void OfflinePageMetadataStoreImpl::ResetDone( 294 void OfflinePageMetadataStoreImpl::ResetDone(
257 const ResetCallback& callback, 295 const ResetCallback& callback,
258 bool success) { 296 bool success) {
259 database_.reset(); 297 database_.reset();
260 weak_ptr_factory_.InvalidateWeakPtrs(); 298 weak_ptr_factory_.InvalidateWeakPtrs();
261 callback.Run(success); 299 callback.Run(success);
262 } 300 }
263 301
302 void OfflinePageMetadataStoreImpl::DatabaseUpdateDone(
303 const OfflinePageMetadataStore::LoadCallback& cb,
304 LoadStatus status,
305 const std::vector<OfflinePageItem>& result,
306 bool success) {
307 // If the update failed, log and keep going. We'll try to
308 // update next time.
309 if (!success) {
310 LOG(ERROR) << "Failed to update database";
311 }
312 NotifyLoadResult(cb, status, result);
313 }
314
264 } // namespace offline_pages 315 } // namespace offline_pages
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698