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

Side by Side Diff: components/ntp_snippets/ntp_snippets_database.cc

Issue 2047713002: [NTP Snippets] Cache images in a LevelDB (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@protodb_get
Patch Set: . Created 4 years, 6 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 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 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/ntp_snippets/ntp_snippets_database.h" 5 #include "components/ntp_snippets/ntp_snippets_database.h"
6 6
7 #include <utility> 7 #include <utility>
8 8
9 #include "base/files/file_path.h" 9 #include "base/files/file_path.h"
10 #include "components/leveldb_proto/proto_database_impl.h" 10 #include "components/leveldb_proto/proto_database_impl.h"
11 #include "components/ntp_snippets/proto/ntp_snippets.pb.h" 11 #include "components/ntp_snippets/proto/ntp_snippets.pb.h"
12 12
13 using leveldb_proto::ProtoDatabaseImpl; 13 using leveldb_proto::ProtoDatabaseImpl;
14 14
15 namespace { 15 namespace {
16 // Statistics are logged to UMA with this string as part of histogram name. They 16 // Statistics are logged to UMA with this string as part of histogram name. They
17 // can all be found under LevelDB.*.NTPSnippets. Changing this needs to 17 // can all be found under LevelDB.*.NTPSnippets. Changing this needs to
18 // synchronize with histograms.xml, AND will also become incompatible with older 18 // synchronize with histograms.xml, AND will also become incompatible with older
19 // browsers still reporting the previous values. 19 // browsers still reporting the previous values.
20 const char kDatabaseUMAClientName[] = "NTPSnippets"; 20 const char kDatabaseUMAClientName[] = "NTPSnippets";
21 const char kImageDatabaseUMAClientName[] = "NTPSnippetImages";
22
23 const char kSnippetDatabaseFolder[] = "snippets";
24 const char kImageDatabaseFolder[] = "images";
21 } 25 }
22 26
23 namespace ntp_snippets { 27 namespace ntp_snippets {
24 28
25 NTPSnippetsDatabase::NTPSnippetsDatabase( 29 NTPSnippetsDatabase::NTPSnippetsDatabase(
26 const base::FilePath& database_dir, 30 const base::FilePath& database_dir,
27 scoped_refptr<base::SequencedTaskRunner> file_task_runner) 31 scoped_refptr<base::SequencedTaskRunner> file_task_runner)
28 : database_( 32 : database_(
29 new ProtoDatabaseImpl<SnippetProto>(std::move(file_task_runner))), 33 new ProtoDatabaseImpl<SnippetProto>(file_task_runner)),
30 database_initialized_(false), 34 database_initialized_(false),
35 image_database_(
36 new ProtoDatabaseImpl<SnippetImageProto>(file_task_runner)),
37 image_database_initialized_(false),
31 weak_ptr_factory_(this) { 38 weak_ptr_factory_(this) {
32 database_->Init(kDatabaseUMAClientName, database_dir, 39 base::FilePath snippet_dir = database_dir.AppendASCII(kSnippetDatabaseFolder);
40 database_->Init(kDatabaseUMAClientName, snippet_dir,
33 base::Bind(&NTPSnippetsDatabase::OnDatabaseInited, 41 base::Bind(&NTPSnippetsDatabase::OnDatabaseInited,
34 weak_ptr_factory_.GetWeakPtr())); 42 weak_ptr_factory_.GetWeakPtr()));
43
44 base::FilePath image_dir = database_dir.AppendASCII(kImageDatabaseFolder);
45 image_database_->Init(kImageDatabaseUMAClientName, image_dir,
Marc Treib 2016/06/14 14:11:39 It's a bit sucky that we need a second LevelDB to
46 base::Bind(&NTPSnippetsDatabase::OnImageDatabaseInited,
47 weak_ptr_factory_.GetWeakPtr()));
35 } 48 }
36 49
37 NTPSnippetsDatabase::~NTPSnippetsDatabase() {} 50 NTPSnippetsDatabase::~NTPSnippetsDatabase() {}
38 51
39 void NTPSnippetsDatabase::Load(const SnippetsLoadedCallback& callback) { 52 bool NTPSnippetsDatabase::IsInitialized() const {
40 if (database_ && database_initialized_) 53 return database_ && database_initialized_ && image_database_ &&
41 LoadImpl(callback); 54 image_database_initialized_;
42 else
43 pending_load_callbacks_.emplace_back(callback);
44 } 55 }
45 56
46 void NTPSnippetsDatabase::Save(const NTPSnippet& snippet) { 57 void NTPSnippetsDatabase::LoadSnippets(const SnippetsCallback& callback) {
58 if (IsInitialized())
59 LoadSnippetsImpl(callback);
60 else
61 pending_snippets_callbacks_.emplace_back(callback);
62 }
63
64 void NTPSnippetsDatabase::SaveSnippet(const NTPSnippet& snippet) {
47 std::unique_ptr<KeyEntryVector> entries_to_save(new KeyEntryVector()); 65 std::unique_ptr<KeyEntryVector> entries_to_save(new KeyEntryVector());
48 entries_to_save->emplace_back(snippet.id(), snippet.ToProto()); 66 entries_to_save->emplace_back(snippet.id(), snippet.ToProto());
49 SaveImpl(std::move(entries_to_save)); 67 SaveSnippetsImpl(std::move(entries_to_save));
50 } 68 }
51 69
52 void NTPSnippetsDatabase::Save(const NTPSnippet::PtrVector& snippets) { 70 void NTPSnippetsDatabase::SaveSnippets(const NTPSnippet::PtrVector& snippets) {
53 std::unique_ptr<KeyEntryVector> entries_to_save(new KeyEntryVector()); 71 std::unique_ptr<KeyEntryVector> entries_to_save(new KeyEntryVector());
54 for (const std::unique_ptr<NTPSnippet>& snippet : snippets) 72 for (const std::unique_ptr<NTPSnippet>& snippet : snippets)
55 entries_to_save->emplace_back(snippet->id(), snippet->ToProto()); 73 entries_to_save->emplace_back(snippet->id(), snippet->ToProto());
56 SaveImpl(std::move(entries_to_save)); 74 SaveSnippetsImpl(std::move(entries_to_save));
57 } 75 }
58 76
59 void NTPSnippetsDatabase::Delete(const std::string& snippet_id) { 77 void NTPSnippetsDatabase::DeleteSnippet(const std::string& snippet_id) {
60 DeleteImpl(base::WrapUnique(new std::vector<std::string>(1, snippet_id))); 78 DeleteSnippetsImpl(
79 base::WrapUnique(new std::vector<std::string>(1, snippet_id)));
61 } 80 }
62 81
63 void NTPSnippetsDatabase::Delete(const NTPSnippet::PtrVector& snippets) { 82 void NTPSnippetsDatabase::DeleteSnippets(
83 const NTPSnippet::PtrVector& snippets) {
64 std::unique_ptr<std::vector<std::string>> keys_to_remove( 84 std::unique_ptr<std::vector<std::string>> keys_to_remove(
65 new std::vector<std::string>()); 85 new std::vector<std::string>());
66 for (const std::unique_ptr<NTPSnippet>& snippet : snippets) 86 for (const std::unique_ptr<NTPSnippet>& snippet : snippets)
67 keys_to_remove->emplace_back(snippet->id()); 87 keys_to_remove->emplace_back(snippet->id());
68 DeleteImpl(std::move(keys_to_remove)); 88 DeleteSnippetsImpl(std::move(keys_to_remove));
89 }
90
91 void NTPSnippetsDatabase::LoadImage(const std::string& snippet_id,
92 const SnippetImageCallback& callback) {
93 if (IsInitialized())
94 LoadImageImpl(snippet_id, callback);
95 else
96 pending_image_callbacks_.emplace_back(snippet_id, callback);
97 }
98
99 void NTPSnippetsDatabase::SaveImage(const std::string& snippet_id,
100 const std::string& image_data) {
101 if (!IsInitialized())
102 return;
103
104 SnippetImageProto image_proto;
105 image_proto.set_data(image_data);
106
107 std::unique_ptr<ImageKeyEntryVector> entries_to_save(
108 new ImageKeyEntryVector());
109 entries_to_save->emplace_back(snippet_id, std::move(image_proto));
110
111 image_database_->UpdateEntries(
112 std::move(entries_to_save),
113 base::WrapUnique(new std::vector<std::string>()),
114 base::Bind(&NTPSnippetsDatabase::OnImageDatabaseSaved,
115 weak_ptr_factory_.GetWeakPtr()));
116 }
117
118 void NTPSnippetsDatabase::DeleteImage(const std::string& snippet_id) {
119 DeleteImagesImpl(
120 base::WrapUnique(new std::vector<std::string>(1, snippet_id)));
69 } 121 }
70 122
71 void NTPSnippetsDatabase::OnDatabaseInited(bool success) { 123 void NTPSnippetsDatabase::OnDatabaseInited(bool success) {
72 DCHECK(!database_initialized_); 124 DCHECK(!database_initialized_);
73 if (!success) { 125 if (!success) {
74 DVLOG(1) << "NTPSnippetsDatabase init failed."; 126 DVLOG(1) << "NTPSnippetsDatabase init failed.";
75 database_.reset(); 127 database_.reset();
76 return; 128 return;
77 } 129 }
78 database_initialized_ = true; 130 database_initialized_ = true;
79 for (const SnippetsLoadedCallback& callback : pending_load_callbacks_) 131 if (IsInitialized())
80 LoadImpl(callback); 132 ProcessPendingLoads();
81 } 133 }
82 134
83 void NTPSnippetsDatabase::OnDatabaseLoaded( 135 void NTPSnippetsDatabase::OnDatabaseLoaded(
84 const SnippetsLoadedCallback& callback, 136 const SnippetsCallback& callback,
85 bool success, 137 bool success,
86 std::unique_ptr<std::vector<SnippetProto>> entries) { 138 std::unique_ptr<std::vector<SnippetProto>> entries) {
87 if (!success) { 139 if (!success) {
88 DVLOG(1) << "NTPSnippetsDatabase load failed."; 140 DVLOG(1) << "NTPSnippetsDatabase load failed.";
89 database_.reset(); 141 database_.reset();
90 return; 142 return;
91 } 143 }
92 144
93 std::unique_ptr<std::vector<std::string>> keys_to_remove( 145 std::unique_ptr<std::vector<std::string>> keys_to_remove(
94 new std::vector<std::string>()); 146 new std::vector<std::string>());
95 147
96 NTPSnippet::PtrVector snippets; 148 NTPSnippet::PtrVector snippets;
97 for (const SnippetProto& proto : *entries) { 149 for (const SnippetProto& proto : *entries) {
98 std::unique_ptr<NTPSnippet> snippet = NTPSnippet::CreateFromProto(proto); 150 std::unique_ptr<NTPSnippet> snippet = NTPSnippet::CreateFromProto(proto);
99 if (snippet) { 151 if (snippet) {
100 snippets.emplace_back(std::move(snippet)); 152 snippets.emplace_back(std::move(snippet));
101 } else { 153 } else {
102 LOG(WARNING) << "Invalid proto from DB " << proto.id(); 154 LOG(WARNING) << "Invalid proto from DB " << proto.id();
103 keys_to_remove->emplace_back(proto.id()); 155 keys_to_remove->emplace_back(proto.id());
104 } 156 }
105 } 157 }
106 158
107 callback.Run(std::move(snippets)); 159 callback.Run(std::move(snippets));
108 160
109 // If any of the snippet protos couldn't be converted to actual snippets, 161 // If any of the snippet protos couldn't be converted to actual snippets,
110 // clean them up now. 162 // clean them up now.
111 if (!keys_to_remove->empty()) 163 if (!keys_to_remove->empty())
112 DeleteImpl(std::move(keys_to_remove)); 164 DeleteSnippetsImpl(std::move(keys_to_remove));
113 } 165 }
114 166
115 void NTPSnippetsDatabase::OnDatabaseSaved(bool success) { 167 void NTPSnippetsDatabase::OnDatabaseSaved(bool success) {
116 if (!success) { 168 if (!success) {
117 DVLOG(1) << "NTPSnippetsDatabase save failed."; 169 DVLOG(1) << "NTPSnippetsDatabase save failed.";
118 database_.reset(); 170 database_.reset();
119 } 171 }
120 } 172 }
121 173
122 void NTPSnippetsDatabase::LoadImpl(const SnippetsLoadedCallback& callback) { 174 void NTPSnippetsDatabase::OnImageDatabaseInited(bool success) {
123 DCHECK(database_); 175 DCHECK(!image_database_initialized_);
124 DCHECK(database_initialized_); 176 if (!success) {
177 DVLOG(1) << "NTPSnippetsDatabase init failed.";
178 image_database_.reset();
179 return;
180 }
181 image_database_initialized_ = true;
182 if (IsInitialized())
183 ProcessPendingLoads();
184 }
185
186 void NTPSnippetsDatabase::OnImageDatabaseLoaded(
187 const SnippetImageCallback& callback,
188 bool success,
189 std::unique_ptr<SnippetImageProto> entry) {
190 if (!success || !entry) {
191 callback.Run(std::string());
192 return;
193 }
194
195 std::unique_ptr<std::string> data(entry->release_data());
196 callback.Run(std::move(*data));
197 }
198
199 void NTPSnippetsDatabase::OnImageDatabaseSaved(bool success) {
200 if (!success) {
201 DVLOG(1) << "NTPSnippetsDatabase save failed.";
202 image_database_.reset();
203 }
204 }
205
206 void NTPSnippetsDatabase::ProcessPendingLoads() {
207 DCHECK(IsInitialized());
208
209 for (const auto& callback : pending_snippets_callbacks_)
210 LoadSnippetsImpl(callback);
211 pending_snippets_callbacks_.clear();
212
213 for (const auto& id_callback : pending_image_callbacks_)
214 LoadImageImpl(id_callback.first, id_callback.second);
215 pending_image_callbacks_.clear();
216 }
217
218 void NTPSnippetsDatabase::LoadSnippetsImpl(const SnippetsCallback& callback) {
219 DCHECK(IsInitialized());
125 database_->LoadEntries(base::Bind(&NTPSnippetsDatabase::OnDatabaseLoaded, 220 database_->LoadEntries(base::Bind(&NTPSnippetsDatabase::OnDatabaseLoaded,
126 weak_ptr_factory_.GetWeakPtr(), 221 weak_ptr_factory_.GetWeakPtr(),
127 callback)); 222 callback));
128 } 223 }
129 224
130 void NTPSnippetsDatabase::SaveImpl( 225 void NTPSnippetsDatabase::SaveSnippetsImpl(
131 std::unique_ptr<KeyEntryVector> entries_to_save) { 226 std::unique_ptr<KeyEntryVector> entries_to_save) {
132 if (!database_ || !database_initialized_) 227 if (!IsInitialized())
133 return; 228 return;
134 229
135 std::unique_ptr<std::vector<std::string>> keys_to_remove( 230 std::unique_ptr<std::vector<std::string>> keys_to_remove(
136 new std::vector<std::string>()); 231 new std::vector<std::string>());
137 database_->UpdateEntries(std::move(entries_to_save), 232 database_->UpdateEntries(std::move(entries_to_save),
138 std::move(keys_to_remove), 233 std::move(keys_to_remove),
139 base::Bind(&NTPSnippetsDatabase::OnDatabaseSaved, 234 base::Bind(&NTPSnippetsDatabase::OnDatabaseSaved,
140 weak_ptr_factory_.GetWeakPtr())); 235 weak_ptr_factory_.GetWeakPtr()));
141 } 236 }
142 237
143 void NTPSnippetsDatabase::DeleteImpl( 238 void NTPSnippetsDatabase::DeleteSnippetsImpl(
144 std::unique_ptr<std::vector<std::string>> keys_to_remove) { 239 std::unique_ptr<std::vector<std::string>> keys_to_remove) {
145 if (!database_ || !database_initialized_) 240 if (!IsInitialized())
146 return; 241 return;
147 242
243 DeleteImagesImpl(
244 base::WrapUnique(new std::vector<std::string>(*keys_to_remove)));
245
148 std::unique_ptr<KeyEntryVector> entries_to_save(new KeyEntryVector()); 246 std::unique_ptr<KeyEntryVector> entries_to_save(new KeyEntryVector());
149 database_->UpdateEntries(std::move(entries_to_save), 247 database_->UpdateEntries(std::move(entries_to_save),
150 std::move(keys_to_remove), 248 std::move(keys_to_remove),
151 base::Bind(&NTPSnippetsDatabase::OnDatabaseSaved, 249 base::Bind(&NTPSnippetsDatabase::OnDatabaseSaved,
152 weak_ptr_factory_.GetWeakPtr())); 250 weak_ptr_factory_.GetWeakPtr()));
153 } 251 }
154 252
253 void NTPSnippetsDatabase::LoadImageImpl(const std::string& snippet_id,
254 const SnippetImageCallback& callback) {
255 DCHECK(IsInitialized());
256 image_database_->GetEntry(
257 snippet_id,
258 base::Bind(&NTPSnippetsDatabase::OnImageDatabaseLoaded,
259 weak_ptr_factory_.GetWeakPtr(), callback));
260 }
261
262 void NTPSnippetsDatabase::DeleteImagesImpl(
263 std::unique_ptr<std::vector<std::string>> keys_to_remove) {
264 if (!IsInitialized())
265 return;
266
267 image_database_->UpdateEntries(
268 base::WrapUnique(new ImageKeyEntryVector()),
269 std::move(keys_to_remove),
270 base::Bind(&NTPSnippetsDatabase::OnImageDatabaseSaved,
271 weak_ptr_factory_.GetWeakPtr()));
272 }
273
155 } // namespace ntp_snippets 274 } // namespace ntp_snippets
OLDNEW
« no previous file with comments | « components/ntp_snippets/ntp_snippets_database.h ('k') | components/ntp_snippets/ntp_snippets_database_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698