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

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

Issue 2604273002: Migrate data from old localstorage format to new format. (Closed)
Patch Set: nit Created 3 years, 11 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 "components/leveldb/public/cpp/util.h" 9 #include "components/leveldb/public/cpp/util.h"
10 #include "content/public/browser/browser_thread.h" 10 #include "content/public/browser/browser_thread.h"
11 11
12 namespace content { 12 namespace content {
13 13
14 void LevelDBWrapperImpl::Delegate::MigrateData(
15 base::OnceCallback<void(std::unique_ptr<ValueMap>)> callback) {
16 std::move(callback).Run(nullptr);
17 }
18
14 bool LevelDBWrapperImpl::s_aggressive_flushing_enabled_ = false; 19 bool LevelDBWrapperImpl::s_aggressive_flushing_enabled_ = false;
15 20
16 LevelDBWrapperImpl::RateLimiter::RateLimiter(size_t desired_rate, 21 LevelDBWrapperImpl::RateLimiter::RateLimiter(size_t desired_rate,
17 base::TimeDelta time_quantum) 22 base::TimeDelta time_quantum)
18 : rate_(desired_rate), samples_(0), time_quantum_(time_quantum) { 23 : rate_(desired_rate), samples_(0), time_quantum_(time_quantum) {
19 DCHECK_GT(desired_rate, 0ul); 24 DCHECK_GT(desired_rate, 0ul);
20 } 25 }
21 26
22 base::TimeDelta LevelDBWrapperImpl::RateLimiter::ComputeTimeNeeded() const { 27 base::TimeDelta LevelDBWrapperImpl::RateLimiter::ComputeTimeNeeded() const {
23 return time_quantum_ * (samples_ / rate_); 28 return time_quantum_ * (samples_ / rate_);
(...skipping 10 matching lines...) Expand all
34 LevelDBWrapperImpl::CommitBatch::CommitBatch() : clear_all_first(false) {} 39 LevelDBWrapperImpl::CommitBatch::CommitBatch() : clear_all_first(false) {}
35 LevelDBWrapperImpl::CommitBatch::~CommitBatch() {} 40 LevelDBWrapperImpl::CommitBatch::~CommitBatch() {}
36 41
37 LevelDBWrapperImpl::LevelDBWrapperImpl( 42 LevelDBWrapperImpl::LevelDBWrapperImpl(
38 leveldb::mojom::LevelDBDatabase* database, 43 leveldb::mojom::LevelDBDatabase* database,
39 const std::string& prefix, 44 const std::string& prefix,
40 size_t max_size, 45 size_t max_size,
41 base::TimeDelta default_commit_delay, 46 base::TimeDelta default_commit_delay,
42 int max_bytes_per_hour, 47 int max_bytes_per_hour,
43 int max_commits_per_hour, 48 int max_commits_per_hour,
44 const base::Closure& no_bindings_callback, 49 Delegate* delegate)
45 const PrepareToCommitCallback& prepare_to_commit_callback)
46 : prefix_(leveldb::StdStringToUint8Vector(prefix)), 50 : prefix_(leveldb::StdStringToUint8Vector(prefix)),
47 no_bindings_callback_(no_bindings_callback), 51 delegate_(delegate),
48 prepare_to_commit_callback_(prepare_to_commit_callback),
49 database_(database), 52 database_(database),
50 bytes_used_(0), 53 bytes_used_(0),
51 max_size_(max_size), 54 max_size_(max_size),
52 start_time_(base::TimeTicks::Now()), 55 start_time_(base::TimeTicks::Now()),
53 default_commit_delay_(default_commit_delay), 56 default_commit_delay_(default_commit_delay),
54 data_rate_limiter_(max_bytes_per_hour, base::TimeDelta::FromHours(1)), 57 data_rate_limiter_(max_bytes_per_hour, base::TimeDelta::FromHours(1)),
55 commit_rate_limiter_(max_commits_per_hour, base::TimeDelta::FromHours(1)), 58 commit_rate_limiter_(max_commits_per_hour, base::TimeDelta::FromHours(1)),
56 weak_ptr_factory_(this) { 59 weak_ptr_factory_(this) {
57 bindings_.set_connection_error_handler(base::Bind( 60 bindings_.set_connection_error_handler(base::Bind(
58 &LevelDBWrapperImpl::OnConnectionError, base::Unretained(this))); 61 &LevelDBWrapperImpl::OnConnectionError, base::Unretained(this)));
(...skipping 185 matching lines...) Expand 10 before | Expand all | Expand 10 after
244 } 247 }
245 } 248 }
246 249
247 void LevelDBWrapperImpl::OnConnectionError() { 250 void LevelDBWrapperImpl::OnConnectionError() {
248 if (!bindings_.empty()) 251 if (!bindings_.empty())
249 return; 252 return;
250 // If any tasks are waiting for load to complete, delay calling the 253 // If any tasks are waiting for load to complete, delay calling the
251 // no_bindings_callback_ until all those tasks have completed. 254 // no_bindings_callback_ until all those tasks have completed.
252 if (!on_load_complete_tasks_.empty()) 255 if (!on_load_complete_tasks_.empty())
253 return; 256 return;
254 no_bindings_callback_.Run(); 257 delegate_->OnNoBindings();
255 } 258 }
256 259
257 void LevelDBWrapperImpl::LoadMap(const base::Closure& completion_callback) { 260 void LevelDBWrapperImpl::LoadMap(const base::Closure& completion_callback) {
258 DCHECK(!map_); 261 DCHECK(!map_);
259 on_load_complete_tasks_.push_back(completion_callback); 262 on_load_complete_tasks_.push_back(completion_callback);
260 if (on_load_complete_tasks_.size() > 1) 263 if (on_load_complete_tasks_.size() > 1)
261 return; 264 return;
262 265
263 if (!database_) { 266 if (!database_) {
264 OnLoadComplete(leveldb::mojom::DatabaseError::IO_ERROR, 267 OnMapLoaded(leveldb::mojom::DatabaseError::IO_ERROR,
265 std::vector<leveldb::mojom::KeyValuePtr>()); 268 std::vector<leveldb::mojom::KeyValuePtr>());
266 return; 269 return;
267 } 270 }
268 271
269 // TODO(michaeln): Import from sqlite localstorage db. 272 // TODO(michaeln): Import from sqlite localstorage db.
270 database_->GetPrefixed(prefix_, 273 database_->GetPrefixed(prefix_, base::Bind(&LevelDBWrapperImpl::OnMapLoaded,
271 base::Bind(&LevelDBWrapperImpl::OnLoadComplete, 274 weak_ptr_factory_.GetWeakPtr()));
272 weak_ptr_factory_.GetWeakPtr()));
273 } 275 }
274 276
275 void LevelDBWrapperImpl::OnLoadComplete( 277 void LevelDBWrapperImpl::OnMapLoaded(
276 leveldb::mojom::DatabaseError status, 278 leveldb::mojom::DatabaseError status,
277 std::vector<leveldb::mojom::KeyValuePtr> data) { 279 std::vector<leveldb::mojom::KeyValuePtr> data) {
278 DCHECK(!map_); 280 DCHECK(!map_);
281
282 if (data.empty() && status == leveldb::mojom::DatabaseError::OK) {
283 delegate_->MigrateData(
284 base::BindOnce(&LevelDBWrapperImpl::OnGotMigrationData,
285 weak_ptr_factory_.GetWeakPtr()));
286 return;
287 }
288
279 map_.reset(new ValueMap); 289 map_.reset(new ValueMap);
280 bytes_used_ = 0; 290 bytes_used_ = 0;
281 for (auto& it : data) { 291 for (auto& it : data) {
282 DCHECK_GE(it->key.size(), prefix_.size()); 292 DCHECK_GE(it->key.size(), prefix_.size());
283 (*map_)[std::vector<uint8_t>(it->key.begin() + prefix_.size(), 293 (*map_)[std::vector<uint8_t>(it->key.begin() + prefix_.size(),
284 it->key.end())] = it->value; 294 it->key.end())] = it->value;
285 bytes_used_ += it->key.size() - prefix_.size() + it->value.size(); 295 bytes_used_ += it->key.size() - prefix_.size() + it->value.size();
286 } 296 }
287 297
288 // We proceed without using a backing store, nothing will be persisted but the 298 // We proceed without using a backing store, nothing will be persisted but the
289 // class is functional for the lifetime of the object. 299 // class is functional for the lifetime of the object.
290 // TODO(michaeln): Uma here or in the DB file? 300 // TODO(michaeln): Uma here or in the DB file?
291 if (status != leveldb::mojom::DatabaseError::OK) 301 if (status != leveldb::mojom::DatabaseError::OK)
292 database_ = nullptr; 302 database_ = nullptr;
293 303
304 OnLoadComplete();
305 }
306
307 void LevelDBWrapperImpl::OnGotMigrationData(std::unique_ptr<ValueMap> data) {
308 map_ = data ? std::move(data) : base::MakeUnique<ValueMap>();
309 bytes_used_ = 0;
310 for (const auto& it : *map_)
311 bytes_used_ += it.first.size() + it.second.size();
312
313 if (database_ && !empty()) {
314 CreateCommitBatchIfNeeded();
315 for (const auto& it : *map_)
316 commit_batch_->changed_keys.insert(it.first);
317 CommitChanges();
318 }
319
320 OnLoadComplete();
321 }
322
323 void LevelDBWrapperImpl::OnLoadComplete() {
294 std::vector<base::Closure> tasks; 324 std::vector<base::Closure> tasks;
295 on_load_complete_tasks_.swap(tasks); 325 on_load_complete_tasks_.swap(tasks);
296 for (auto& task : tasks) 326 for (auto& task : tasks)
297 task.Run(); 327 task.Run();
298 328
299 // We might need to call the no_bindings_callback_ here if bindings became 329 // We might need to call the no_bindings_callback_ here if bindings became
300 // empty while waiting for load to complete. 330 // empty while waiting for load to complete.
301 if (bindings_.empty()) 331 if (bindings_.empty())
302 no_bindings_callback_.Run(); 332 delegate_->OnNoBindings();
303 } 333 }
304 334
305 void LevelDBWrapperImpl::CreateCommitBatchIfNeeded() { 335 void LevelDBWrapperImpl::CreateCommitBatchIfNeeded() {
306 if (commit_batch_) 336 if (commit_batch_)
307 return; 337 return;
308 338
309 commit_batch_.reset(new CommitBatch()); 339 commit_batch_.reset(new CommitBatch());
310 BrowserThread::PostAfterStartupTask( 340 BrowserThread::PostAfterStartupTask(
311 FROM_HERE, base::ThreadTaskRunnerHandle::Get(), 341 FROM_HERE, base::ThreadTaskRunnerHandle::Get(),
312 base::Bind(&LevelDBWrapperImpl::StartCommitTimer, 342 base::Bind(&LevelDBWrapperImpl::StartCommitTimer,
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
345 void LevelDBWrapperImpl::CommitChanges() { 375 void LevelDBWrapperImpl::CommitChanges() {
346 DCHECK(database_); 376 DCHECK(database_);
347 DCHECK(map_); 377 DCHECK(map_);
348 if (!commit_batch_) 378 if (!commit_batch_)
349 return; 379 return;
350 380
351 commit_rate_limiter_.add_samples(1); 381 commit_rate_limiter_.add_samples(1);
352 382
353 // Commit all our changes in a single batch. 383 // Commit all our changes in a single batch.
354 std::vector<leveldb::mojom::BatchedOperationPtr> operations = 384 std::vector<leveldb::mojom::BatchedOperationPtr> operations =
355 prepare_to_commit_callback_.Run(*this); 385 delegate_->PrepareToCommit();
356 if (commit_batch_->clear_all_first) { 386 if (commit_batch_->clear_all_first) {
357 leveldb::mojom::BatchedOperationPtr item = 387 leveldb::mojom::BatchedOperationPtr item =
358 leveldb::mojom::BatchedOperation::New(); 388 leveldb::mojom::BatchedOperation::New();
359 item->type = leveldb::mojom::BatchOperationType::DELETE_PREFIXED_KEY; 389 item->type = leveldb::mojom::BatchOperationType::DELETE_PREFIXED_KEY;
360 item->key = prefix_; 390 item->key = prefix_;
361 operations.push_back(std::move(item)); 391 operations.push_back(std::move(item));
362 } 392 }
363 size_t data_size = 0; 393 size_t data_size = 0;
364 for (const auto& key: commit_batch_->changed_keys) { 394 for (const auto& key: commit_batch_->changed_keys) {
365 data_size += key.size(); 395 data_size += key.size();
(...skipping 22 matching lines...) Expand all
388 // will run during a clean shutdown. We need that to avoid dataloss. 418 // will run during a clean shutdown. We need that to avoid dataloss.
389 database_->Write(std::move(operations), 419 database_->Write(std::move(operations),
390 base::Bind(&LevelDBWrapperImpl::OnCommitComplete, 420 base::Bind(&LevelDBWrapperImpl::OnCommitComplete,
391 weak_ptr_factory_.GetWeakPtr())); 421 weak_ptr_factory_.GetWeakPtr()));
392 } 422 }
393 423
394 void LevelDBWrapperImpl::OnCommitComplete(leveldb::mojom::DatabaseError error) { 424 void LevelDBWrapperImpl::OnCommitComplete(leveldb::mojom::DatabaseError error) {
395 // TODO(michaeln): What if it fails, uma here or in the DB class? 425 // TODO(michaeln): What if it fails, uma here or in the DB class?
396 --commit_batches_in_flight_; 426 --commit_batches_in_flight_;
397 StartCommitTimer(); 427 StartCommitTimer();
428 delegate_->DidCommit(error);
398 } 429 }
399 430
400 } // namespace content 431 } // namespace content
OLDNEW
« no previous file with comments | « content/browser/leveldb_wrapper_impl.h ('k') | content/browser/leveldb_wrapper_impl_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698