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

Side by Side Diff: content/browser/leveldb_wrapper_impl.cc

Issue 2201763002: Switch on use_new_wrapper_types mode for content/common. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Address comments from Lei and Michael Created 4 years, 4 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 "content/browser/leveldb_wrapper_impl.h" 5 #include "content/browser/leveldb_wrapper_impl.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/threading/thread_task_runner_handle.h" 8 #include "base/threading/thread_task_runner_handle.h"
9 #include "content/public/browser/browser_thread.h" 9 #include "content/public/browser/browser_thread.h"
10 #include "mojo/common/common_type_converters.h" 10 #include "mojo/common/common_type_converters.h"
(...skipping 22 matching lines...) Expand all
33 33
34 LevelDBWrapperImpl::CommitBatch::CommitBatch() : clear_all_first(false) {} 34 LevelDBWrapperImpl::CommitBatch::CommitBatch() : clear_all_first(false) {}
35 LevelDBWrapperImpl::CommitBatch::~CommitBatch() {} 35 LevelDBWrapperImpl::CommitBatch::~CommitBatch() {}
36 36
37 size_t LevelDBWrapperImpl::CommitBatch::GetDataSize() const { 37 size_t LevelDBWrapperImpl::CommitBatch::GetDataSize() const {
38 if (changed_values.empty()) 38 if (changed_values.empty())
39 return 0; 39 return 0;
40 40
41 size_t count = 0; 41 size_t count = 0;
42 for (const auto& pair : changed_values) 42 for (const auto& pair : changed_values)
43 count += (pair.first.size(), pair.second.size()); 43 count += (pair.first.size(), pair.second.value().size());
yzshen1 2016/08/02 16:20:09 pair.second may be null, right? (e.g., see line 16
michaeln 2016/08/02 20:31:54 also, this line looks weird, can you fix this to c
leonhsl(Using Gerrit) 2016/08/03 03:38:48 Done. And also confirmed there has no similar prob
44 return count; 44 return count;
45 } 45 }
46 46
47 LevelDBWrapperImpl::LevelDBWrapperImpl( 47 LevelDBWrapperImpl::LevelDBWrapperImpl(
48 leveldb::mojom::LevelDBDatabase* database, 48 leveldb::mojom::LevelDBDatabase* database,
49 const std::string& prefix, 49 const std::string& prefix,
50 size_t max_size, 50 size_t max_size,
51 base::TimeDelta default_commit_delay, 51 base::TimeDelta default_commit_delay,
52 int max_bytes_per_hour, 52 int max_bytes_per_hour,
53 int max_commits_per_hour, 53 int max_commits_per_hour,
(...skipping 22 matching lines...) Expand all
76 } 76 }
77 77
78 void LevelDBWrapperImpl::AddObserver(mojom::LevelDBObserverPtr observer) { 78 void LevelDBWrapperImpl::AddObserver(mojom::LevelDBObserverPtr observer) {
79 observers_.AddPtr(std::move(observer)); 79 observers_.AddPtr(std::move(observer));
80 } 80 }
81 81
82 void LevelDBWrapperImpl::EnableAggressiveCommitDelay() { 82 void LevelDBWrapperImpl::EnableAggressiveCommitDelay() {
83 s_aggressive_flushing_enabled_ = true; 83 s_aggressive_flushing_enabled_ = true;
84 } 84 }
85 85
86 void LevelDBWrapperImpl::Put(mojo::Array<uint8_t> key, 86 void LevelDBWrapperImpl::Put(const std::vector<uint8_t>& key,
87 mojo::Array<uint8_t> value, 87 const std::vector<uint8_t>& value,
88 const mojo::String& source, 88 const std::string& source,
89 const PutCallback& callback) { 89 const PutCallback& callback) {
90 if (!map_) { 90 if (!map_) {
91 LoadMap( 91 LoadMap(base::Bind(&LevelDBWrapperImpl::Put, base::Unretained(this), key,
92 base::Bind(&LevelDBWrapperImpl::Put, base::Unretained(this), 92 value, source, callback));
93 base::Passed(&key), base::Passed(&value), source, callback));
94 return; 93 return;
95 } 94 }
96 95
97 bool has_old_item = false; 96 bool has_old_item = false;
98 mojo::Array<uint8_t> old_value;
99 size_t old_item_size = 0; 97 size_t old_item_size = 0;
100 auto found = map_->find(key); 98 auto found = map_->find(key);
101 if (found != map_->end()) { 99 if (found != map_->end()) {
102 if (found->second.Equals(value)) { 100 if (*(found->second) == value) {
yzshen1 2016/08/02 16:20:09 It seems here we also assume that found->second is
michaeln 2016/08/02 20:31:54 Values in this map_ may not be null, it might be g
leonhsl(Using Gerrit) 2016/08/03 03:38:48 Yeah I think DCHECK() is proper here, as map_ is s
yzshen1 2016/08/03 17:23:05 If map_ is not supposed to have null value, it wou
leonhsl(Using Gerrit) 2016/08/09 07:56:51 Sorry for late response. Agree and addressed this
103 callback.Run(true); // Key already has this value. 101 callback.Run(true); // Key already has this value.
104 return; 102 return;
105 } 103 }
106 old_value = std::move(found->second); 104 old_item_size = key.size() + found->second->size();
yzshen1 2016/08/02 16:20:09 Previously the old value was removed from the map,
michaeln 2016/08/02 20:31:54 yes, this fixes a bug
107 old_item_size = key.size() + old_value.size();
108 has_old_item = true; 105 has_old_item = true;
109 } 106 }
110 size_t new_item_size = key.size() + value.size(); 107 size_t new_item_size = key.size() + value.size();
111 size_t new_bytes_used = bytes_used_ - old_item_size + new_item_size; 108 size_t new_bytes_used = bytes_used_ - old_item_size + new_item_size;
112 109
113 // Only check quota if the size is increasing, this allows 110 // Only check quota if the size is increasing, this allows
114 // shrinking changes to pre-existing maps that are over budget. 111 // shrinking changes to pre-existing maps that are over budget.
115 if (new_item_size > old_item_size && new_bytes_used > max_size_) { 112 if (new_item_size > old_item_size && new_bytes_used > max_size_) {
116 callback.Run(false); 113 callback.Run(false);
117 return; 114 return;
118 } 115 }
119 116
120 if (database_) { 117 if (database_) {
121 CreateCommitBatchIfNeeded(); 118 CreateCommitBatchIfNeeded();
122 commit_batch_->changed_values[key.Clone()] = value.Clone(); 119 commit_batch_->changed_values[key] = value;
123 } 120 }
124 121
125 (*map_)[key.Clone()] = value.Clone(); 122 std::vector<uint8_t> old_value;
123 if (has_old_item) {
124 old_value.swap(*((*map_)[key]));
125 }
126 (*map_)[key] = value;
126 bytes_used_ = new_bytes_used; 127 bytes_used_ = new_bytes_used;
127 if (!has_old_item) { 128 if (!has_old_item) {
128 // We added a new key/value pair. 129 // We added a new key/value pair.
129 observers_.ForAllPtrs( 130 observers_.ForAllPtrs(
130 [&key, &value, &source](mojom::LevelDBObserver* observer) { 131 [&key, &value, &source](mojom::LevelDBObserver* observer) {
131 observer->KeyAdded(key.Clone(), value.Clone(), source); 132 observer->KeyAdded(key, value, source);
132 }); 133 });
133 } else { 134 } else {
134 // We changed the value for an existing key. 135 // We changed the value for an existing key.
135 observers_.ForAllPtrs( 136 observers_.ForAllPtrs(
136 [&key, &value, &source, &old_value](mojom::LevelDBObserver* observer) { 137 [&key, &value, &source, &old_value](mojom::LevelDBObserver* observer) {
137 observer->KeyChanged( 138 observer->KeyChanged(key, value, old_value, source);
138 key.Clone(), value.Clone(), old_value.Clone(), source);
139 }); 139 });
140 } 140 }
141 callback.Run(true); 141 callback.Run(true);
142 } 142 }
143 143
144 void LevelDBWrapperImpl::Delete(mojo::Array<uint8_t> key, 144 void LevelDBWrapperImpl::Delete(const std::vector<uint8_t>& key,
145 const mojo::String& source, 145 const std::string& source,
146 const DeleteCallback& callback) { 146 const DeleteCallback& callback) {
147 if (!map_) { 147 if (!map_) {
148 LoadMap( 148 LoadMap(base::Bind(&LevelDBWrapperImpl::Delete, base::Unretained(this), key,
149 base::Bind(&LevelDBWrapperImpl::Delete, base::Unretained(this), 149 source, callback));
150 base::Passed(&key), source, callback));
151 return; 150 return;
152 } 151 }
153 152
154 auto found = map_->find(key); 153 auto found = map_->find(key);
155 if (found == map_->end()) { 154 if (found == map_->end()) {
156 callback.Run(true); 155 callback.Run(true);
157 return; 156 return;
158 } 157 }
159 158
160 if (database_) { 159 if (database_) {
161 CreateCommitBatchIfNeeded(); 160 CreateCommitBatchIfNeeded();
162 commit_batch_->changed_values[key.Clone()] = mojo::Array<uint8_t>(nullptr); 161 commit_batch_->changed_values[key] = base::nullopt;
163 } 162 }
164 163
165 mojo::Array<uint8_t> old_value = std::move(found->second); 164 std::vector<uint8_t> old_value(std::move(*(found->second)));
166 map_->erase(found); 165 map_->erase(found);
167 bytes_used_ -= key.size() + old_value.size(); 166 bytes_used_ -= key.size() + old_value.size();
168 observers_.ForAllPtrs( 167 observers_.ForAllPtrs(
169 [&key, &source, &old_value](mojom::LevelDBObserver* observer) { 168 [&key, &source, &old_value](mojom::LevelDBObserver* observer) {
170 observer->KeyDeleted( 169 observer->KeyDeleted(key, old_value, source);
171 key.Clone(), old_value.Clone(), source);
172 }); 170 });
173 callback.Run(true); 171 callback.Run(true);
174 } 172 }
175 173
176 void LevelDBWrapperImpl::DeleteAll(const mojo::String& source, 174 void LevelDBWrapperImpl::DeleteAll(const std::string& source,
177 const DeleteAllCallback& callback) { 175 const DeleteAllCallback& callback) {
178 if (!map_) { 176 if (!map_) {
179 LoadMap( 177 LoadMap(
180 base::Bind(&LevelDBWrapperImpl::DeleteAll, base::Unretained(this), 178 base::Bind(&LevelDBWrapperImpl::DeleteAll, base::Unretained(this),
181 source, callback)); 179 source, callback));
182 return; 180 return;
183 } 181 }
184 182
185 if (database_ && !map_->empty()) { 183 if (database_ && !map_->empty()) {
186 CreateCommitBatchIfNeeded(); 184 CreateCommitBatchIfNeeded();
187 commit_batch_->clear_all_first = true; 185 commit_batch_->clear_all_first = true;
188 commit_batch_->changed_values.clear(); 186 commit_batch_->changed_values.clear();
189 } 187 }
190 map_->clear(); 188 map_->clear();
191 bytes_used_ = 0; 189 bytes_used_ = 0;
192 observers_.ForAllPtrs( 190 observers_.ForAllPtrs(
193 [&source](mojom::LevelDBObserver* observer) { 191 [&source](mojom::LevelDBObserver* observer) {
194 observer->AllDeleted(source); 192 observer->AllDeleted(source);
195 }); 193 });
196 callback.Run(true); 194 callback.Run(true);
197 } 195 }
198 196
199 void LevelDBWrapperImpl::Get(mojo::Array<uint8_t> key, 197 void LevelDBWrapperImpl::Get(const std::vector<uint8_t>& key,
200 const GetCallback& callback) { 198 const GetCallback& callback) {
201 if (!map_) { 199 if (!map_) {
202 LoadMap( 200 LoadMap(base::Bind(&LevelDBWrapperImpl::Get, base::Unretained(this), key,
203 base::Bind(&LevelDBWrapperImpl::Get, base::Unretained(this), 201 callback));
204 base::Passed(&key), callback));
205 return; 202 return;
206 } 203 }
207 204
208 auto found = map_->find(key); 205 auto found = map_->find(key);
209 if (found == map_->end()) { 206 if (found == map_->end()) {
210 callback.Run(false, mojo::Array<uint8_t>()); 207 callback.Run(false, std::vector<uint8_t>());
211 return; 208 return;
212 } 209 }
213 callback.Run(true, found->second.Clone()); 210 callback.Run(true, *(found->second));
214 } 211 }
215 212
216 void LevelDBWrapperImpl::GetAll(const mojo::String& source, 213 void LevelDBWrapperImpl::GetAll(const std::string& source,
217 const GetAllCallback& callback) { 214 const GetAllCallback& callback) {
218 if (!map_) { 215 if (!map_) {
219 LoadMap( 216 LoadMap(
220 base::Bind(&LevelDBWrapperImpl::GetAll, base::Unretained(this), 217 base::Bind(&LevelDBWrapperImpl::GetAll, base::Unretained(this),
221 source, callback)); 218 source, callback));
222 return; 219 return;
223 } 220 }
224 221
225 mojo::Array<mojom::KeyValuePtr> all; 222 std::vector<mojom::KeyValuePtr> all;
226 for (const auto& it : (*map_)) { 223 for (const auto& it : (*map_)) {
227 mojom::KeyValuePtr kv = mojom::KeyValue::New(); 224 mojom::KeyValuePtr kv = mojom::KeyValue::New();
228 kv->key = it.first.Clone(); 225 kv->key = it.first;
229 kv->value = it.second.Clone(); 226 kv->value = *(it.second);
230 all.push_back(std::move(kv)); 227 all.push_back(std::move(kv));
231 } 228 }
232 callback.Run(leveldb::mojom::DatabaseError::OK, std::move(all)); 229 callback.Run(leveldb::mojom::DatabaseError::OK, std::move(all));
233 observers_.ForAllPtrs( 230 observers_.ForAllPtrs(
234 [source](mojom::LevelDBObserver* observer) { 231 [source](mojom::LevelDBObserver* observer) {
235 observer->GetAllComplete(source); 232 observer->GetAllComplete(source);
236 }); 233 });
237 } 234 }
238 235
239 void LevelDBWrapperImpl::OnConnectionError() { 236 void LevelDBWrapperImpl::OnConnectionError() {
(...skipping 13 matching lines...) Expand all
253 base::Bind(&LevelDBWrapperImpl::OnLoadComplete, 250 base::Bind(&LevelDBWrapperImpl::OnLoadComplete,
254 weak_ptr_factory_.GetWeakPtr())); 251 weak_ptr_factory_.GetWeakPtr()));
255 } 252 }
256 253
257 void LevelDBWrapperImpl::OnLoadComplete( 254 void LevelDBWrapperImpl::OnLoadComplete(
258 leveldb::mojom::DatabaseError status, 255 leveldb::mojom::DatabaseError status,
259 mojo::Array<leveldb::mojom::KeyValuePtr> data) { 256 mojo::Array<leveldb::mojom::KeyValuePtr> data) {
260 DCHECK(!map_); 257 DCHECK(!map_);
261 map_.reset(new ValueMap); 258 map_.reset(new ValueMap);
262 for (auto& it : data) 259 for (auto& it : data)
263 (*map_)[std::move(it->key)] = std::move(it->value); 260 (*map_)[it->key.PassStorage()] = it->value.PassStorage();
264 261
265 // We proceed without using a backing store, nothing will be persisted but the 262 // We proceed without using a backing store, nothing will be persisted but the
266 // class is functional for the lifetime of the object. 263 // class is functional for the lifetime of the object.
267 // TODO(michaeln): Uma here or in the DB file? 264 // TODO(michaeln): Uma here or in the DB file?
268 if (status != leveldb::mojom::DatabaseError::OK) 265 if (status != leveldb::mojom::DatabaseError::OK)
269 database_ = nullptr; 266 database_ = nullptr;
270 267
271 std::vector<base::Closure> tasks; 268 std::vector<base::Closure> tasks;
272 on_load_complete_tasks_.swap(tasks); 269 on_load_complete_tasks_.swap(tasks);
273 for (auto& task : tasks) 270 for (auto& task : tasks)
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
327 if (commit_batch_->clear_all_first) { 324 if (commit_batch_->clear_all_first) {
328 leveldb::mojom::BatchedOperationPtr item = 325 leveldb::mojom::BatchedOperationPtr item =
329 leveldb::mojom::BatchedOperation::New(); 326 leveldb::mojom::BatchedOperation::New();
330 item->type = leveldb::mojom::BatchOperationType::DELETE_PREFIXED_KEY; 327 item->type = leveldb::mojom::BatchOperationType::DELETE_PREFIXED_KEY;
331 item->key = mojo::Array<uint8_t>::From(std::string(prefix_)); 328 item->key = mojo::Array<uint8_t>::From(std::string(prefix_));
332 operations.push_back(std::move(item)); 329 operations.push_back(std::move(item));
333 } 330 }
334 for (auto& it : commit_batch_->changed_values) { 331 for (auto& it : commit_batch_->changed_values) {
335 leveldb::mojom::BatchedOperationPtr item = 332 leveldb::mojom::BatchedOperationPtr item =
336 leveldb::mojom::BatchedOperation::New(); 333 leveldb::mojom::BatchedOperation::New();
337 item->key = it.first.Clone(); 334 item->key = std::vector<uint8_t>(it.first);
338 if (it.second.is_null()) { 335 if (!it.second) {
339 item->type = leveldb::mojom::BatchOperationType::DELETE_KEY; 336 item->type = leveldb::mojom::BatchOperationType::DELETE_KEY;
340 } else { 337 } else {
341 item->type = leveldb::mojom::BatchOperationType::PUT_KEY; 338 item->type = leveldb::mojom::BatchOperationType::PUT_KEY;
342 item->value = std::move(it.second); 339 item->value = std::move(*(it.second));
343 } 340 }
344 operations.push_back(std::move(item)); 341 operations.push_back(std::move(item));
345 } 342 }
346 commit_batch_.reset(); 343 commit_batch_.reset();
347 344
348 ++commit_batches_in_flight_; 345 ++commit_batches_in_flight_;
349 346
350 // TODO(michaeln): Currently there is no guarantee LevelDBDatabaseImp::Write 347 // TODO(michaeln): Currently there is no guarantee LevelDBDatabaseImp::Write
351 // will run during a clean shutdown. We need that to avoid dataloss. 348 // will run during a clean shutdown. We need that to avoid dataloss.
352 database_->Write(std::move(operations), 349 database_->Write(std::move(operations),
353 base::Bind(&LevelDBWrapperImpl::OnCommitComplete, 350 base::Bind(&LevelDBWrapperImpl::OnCommitComplete,
354 weak_ptr_factory_.GetWeakPtr())); 351 weak_ptr_factory_.GetWeakPtr()));
355 } 352 }
356 353
357 void LevelDBWrapperImpl::OnCommitComplete(leveldb::mojom::DatabaseError error) { 354 void LevelDBWrapperImpl::OnCommitComplete(leveldb::mojom::DatabaseError error) {
358 // TODO(michaeln): What if it fails, uma here or in the DB class? 355 // TODO(michaeln): What if it fails, uma here or in the DB class?
359 --commit_batches_in_flight_; 356 --commit_batches_in_flight_;
360 StartCommitTimer(); 357 StartCommitTimer();
361 } 358 }
362 359
363 } // namespace content 360 } // namespace content
OLDNEW
« no previous file with comments | « content/browser/leveldb_wrapper_impl.h ('k') | content/browser/web_contents/web_contents_impl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698