Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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/sync_file_system/drive_backend/metadata_database.h" | 5 #include "chrome/browser/sync_file_system/drive_backend/metadata_database.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <stack> | 8 #include <stack> |
| 9 | 9 |
| 10 #include "base/bind.h" | 10 #include "base/bind.h" |
| (...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 184 *app_root_tracker->mutable_synced_details() = app_root_metadata.details(); | 184 *app_root_tracker->mutable_synced_details() = app_root_metadata.details(); |
| 185 return app_root_tracker.Pass(); | 185 return app_root_tracker.Pass(); |
| 186 } | 186 } |
| 187 | 187 |
| 188 scoped_ptr<FileTracker> CloneFileTracker(const FileTracker* obj) { | 188 scoped_ptr<FileTracker> CloneFileTracker(const FileTracker* obj) { |
| 189 if (!obj) | 189 if (!obj) |
| 190 return scoped_ptr<FileTracker>(); | 190 return scoped_ptr<FileTracker>(); |
| 191 return scoped_ptr<FileTracker>(new FileTracker(*obj)); | 191 return scoped_ptr<FileTracker>(new FileTracker(*obj)); |
| 192 } | 192 } |
| 193 | 193 |
| 194 void WriteOnFileTaskRunner( | |
| 195 leveldb::DB* db, | |
| 196 scoped_ptr<leveldb::WriteBatch> batch, | |
| 197 scoped_refptr<base::SequencedTaskRunner> worker_task_runner, | |
| 198 const SyncStatusCallback& callback) { | |
| 199 DCHECK(db); | |
| 200 DCHECK(batch); | |
| 201 leveldb::Status status = db->Write(leveldb::WriteOptions(), batch.get()); | |
| 202 worker_task_runner->PostTask( | |
| 203 FROM_HERE, | |
| 204 base::Bind(callback, LevelDBStatusToSyncStatusCode(status))); | |
| 205 } | |
| 206 | |
| 207 // Returns true if |db| has no content. | 194 // Returns true if |db| has no content. |
| 208 bool IsDatabaseEmpty(leveldb::DB* db) { | 195 bool IsDatabaseEmpty(leveldb::DB* db) { |
| 209 DCHECK(db); | 196 DCHECK(db); |
| 210 scoped_ptr<leveldb::Iterator> itr(db->NewIterator(leveldb::ReadOptions())); | 197 scoped_ptr<leveldb::Iterator> itr(db->NewIterator(leveldb::ReadOptions())); |
| 211 itr->SeekToFirst(); | 198 itr->SeekToFirst(); |
| 212 return !itr->Valid(); | 199 return !itr->Valid(); |
| 213 } | 200 } |
| 214 | 201 |
| 215 SyncStatusCode OpenDatabase(const base::FilePath& path, | 202 SyncStatusCode OpenDatabase(const base::FilePath& path, |
| 216 leveldb::Env* env_override, | 203 leveldb::Env* env_override, |
| (...skipping 319 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 536 | 523 |
| 537 if (index->GetFileTrackerIDsByFileID(file_id).empty()) { | 524 if (index->GetFileTrackerIDsByFileID(file_id).empty()) { |
| 538 index->RemoveFileMetadata(file_id, batch); | 525 index->RemoveFileMetadata(file_id, batch); |
| 539 } | 526 } |
| 540 } | 527 } |
| 541 | 528 |
| 542 } // namespace | 529 } // namespace |
| 543 | 530 |
| 544 struct MetadataDatabase::CreateParam { | 531 struct MetadataDatabase::CreateParam { |
| 545 scoped_refptr<base::SequencedTaskRunner> worker_task_runner; | 532 scoped_refptr<base::SequencedTaskRunner> worker_task_runner; |
| 546 scoped_refptr<base::SequencedTaskRunner> file_task_runner; | |
| 547 base::FilePath database_path; | 533 base::FilePath database_path; |
| 548 leveldb::Env* env_override; | 534 leveldb::Env* env_override; |
| 549 | 535 |
| 550 CreateParam(base::SequencedTaskRunner* worker_task_runner, | 536 CreateParam(base::SequencedTaskRunner* worker_task_runner, |
| 551 base::SequencedTaskRunner* file_task_runner, | |
| 552 const base::FilePath& database_path, | 537 const base::FilePath& database_path, |
| 553 leveldb::Env* env_override) | 538 leveldb::Env* env_override) |
| 554 : worker_task_runner(worker_task_runner), | 539 : worker_task_runner(worker_task_runner), |
| 555 file_task_runner(file_task_runner), | |
| 556 database_path(database_path), | 540 database_path(database_path), |
| 557 env_override(env_override) { | 541 env_override(env_override) { |
| 558 } | 542 } |
| 559 }; | 543 }; |
| 560 | 544 |
| 561 // static | 545 // static |
| 562 void MetadataDatabase::Create(base::SequencedTaskRunner* worker_task_runner, | 546 void MetadataDatabase::Create(base::SequencedTaskRunner* worker_task_runner, |
| 563 base::SequencedTaskRunner* file_task_runner, | |
| 564 const base::FilePath& database_path, | 547 const base::FilePath& database_path, |
| 565 leveldb::Env* env_override, | 548 leveldb::Env* env_override, |
| 566 const CreateCallback& callback) { | 549 const CreateCallback& callback) { |
| 567 file_task_runner->PostTask(FROM_HERE, base::Bind( | 550 worker_task_runner->PostTask(FROM_HERE, base::Bind( |
| 568 &MetadataDatabase::CreateOnFileTaskRunner, | 551 &MetadataDatabase::CreateOnWorkerTaskRunner, |
| 569 base::Passed(make_scoped_ptr(new CreateParam( | 552 base::Passed(make_scoped_ptr(new CreateParam( |
| 570 worker_task_runner, | 553 worker_task_runner, |
| 571 file_task_runner, | |
| 572 database_path, | 554 database_path, |
| 573 env_override))), | 555 env_override))), |
| 574 callback)); | 556 callback)); |
| 575 } | 557 } |
| 576 | 558 |
| 577 // static | 559 // static |
| 578 SyncStatusCode MetadataDatabase::CreateForTesting( | 560 SyncStatusCode MetadataDatabase::CreateForTesting( |
| 579 scoped_ptr<leveldb::DB> db, | 561 scoped_ptr<leveldb::DB> db, |
| 580 scoped_ptr<MetadataDatabase>* metadata_database_out) { | 562 scoped_ptr<MetadataDatabase>* metadata_database_out) { |
| 581 scoped_ptr<MetadataDatabase> metadata_database( | 563 scoped_ptr<MetadataDatabase> metadata_database( |
| 582 new MetadataDatabase(base::ThreadTaskRunnerHandle::Get(), | 564 new MetadataDatabase(base::ThreadTaskRunnerHandle::Get(), |
| 583 base::ThreadTaskRunnerHandle::Get(), | |
| 584 base::FilePath(), NULL)); | 565 base::FilePath(), NULL)); |
| 585 metadata_database->db_ = db.Pass(); | 566 metadata_database->db_ = db.Pass(); |
| 586 SyncStatusCode status = | 567 SyncStatusCode status = metadata_database->Initialize(); |
| 587 metadata_database->InitializeOnFileTaskRunner(); | |
| 588 if (status == SYNC_STATUS_OK) | 568 if (status == SYNC_STATUS_OK) |
| 589 *metadata_database_out = metadata_database.Pass(); | 569 *metadata_database_out = metadata_database.Pass(); |
| 590 return status; | 570 return status; |
| 591 } | 571 } |
| 592 | 572 |
| 593 MetadataDatabase::~MetadataDatabase() { | 573 MetadataDatabase::~MetadataDatabase() { |
| 594 file_task_runner_->DeleteSoon(FROM_HERE, db_.release()); | 574 worker_task_runner_->DeleteSoon(FROM_HERE, db_.release()); |
| 595 } | 575 } |
| 596 | 576 |
| 597 // static | 577 // static |
| 598 void MetadataDatabase::ClearDatabase( | 578 void MetadataDatabase::ClearDatabase( |
| 599 scoped_ptr<MetadataDatabase> metadata_database) { | 579 scoped_ptr<MetadataDatabase> metadata_database) { |
| 600 DCHECK(metadata_database); | 580 DCHECK(metadata_database); |
| 601 scoped_refptr<base::SequencedTaskRunner> file_task_runner = | 581 scoped_refptr<base::SequencedTaskRunner> worker_task_runner = |
| 602 metadata_database->file_task_runner_; | 582 metadata_database->worker_task_runner_; |
|
nhiroki
2014/08/04 05:27:14
nit: You can just call "metadata_database->worker_
nhiroki
2014/08/04 05:28:44
Oops... sorry. I missed that |metadata_database| w
peria
2014/08/04 05:52:34
Acknowledged.
| |
| 603 base::FilePath database_path = metadata_database->database_path_; | 583 base::FilePath database_path = metadata_database->database_path_; |
| 604 DCHECK(!database_path.empty()); | 584 DCHECK(!database_path.empty()); |
| 605 metadata_database.reset(); | 585 metadata_database.reset(); |
| 606 | 586 |
| 607 file_task_runner->PostTask( | 587 worker_task_runner->PostTask( |
| 608 FROM_HERE, | 588 FROM_HERE, |
| 609 base::Bind(base::IgnoreResult(base::DeleteFile), | 589 base::Bind(base::IgnoreResult(base::DeleteFile), |
| 610 database_path, true /* recursive */)); | 590 database_path, true /* recursive */)); |
| 611 } | 591 } |
| 612 | 592 |
| 613 int64 MetadataDatabase::GetLargestFetchedChangeID() const { | 593 int64 MetadataDatabase::GetLargestFetchedChangeID() const { |
| 614 DCHECK(worker_sequence_checker_.CalledOnValidSequencedThread()); | 594 DCHECK(worker_sequence_checker_.CalledOnValidSequencedThread()); |
| 615 return index_->GetLargestChangeID(); | 595 return index_->GetLargestChangeID(); |
| 616 } | 596 } |
| 617 | 597 |
| (...skipping 798 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1416 } | 1396 } |
| 1417 | 1397 |
| 1418 void MetadataDatabase::GetRegisteredAppIDs(std::vector<std::string>* app_ids) { | 1398 void MetadataDatabase::GetRegisteredAppIDs(std::vector<std::string>* app_ids) { |
| 1419 DCHECK(worker_sequence_checker_.CalledOnValidSequencedThread()); | 1399 DCHECK(worker_sequence_checker_.CalledOnValidSequencedThread()); |
| 1420 DCHECK(app_ids); | 1400 DCHECK(app_ids); |
| 1421 *app_ids = index_->GetRegisteredAppIDs(); | 1401 *app_ids = index_->GetRegisteredAppIDs(); |
| 1422 } | 1402 } |
| 1423 | 1403 |
| 1424 MetadataDatabase::MetadataDatabase( | 1404 MetadataDatabase::MetadataDatabase( |
| 1425 base::SequencedTaskRunner* worker_task_runner, | 1405 base::SequencedTaskRunner* worker_task_runner, |
| 1426 base::SequencedTaskRunner* file_task_runner, | |
| 1427 const base::FilePath& database_path, | 1406 const base::FilePath& database_path, |
| 1428 leveldb::Env* env_override) | 1407 leveldb::Env* env_override) |
| 1429 : worker_task_runner_(worker_task_runner), | 1408 : worker_task_runner_(worker_task_runner), |
| 1430 file_task_runner_(file_task_runner), | |
| 1431 database_path_(database_path), | 1409 database_path_(database_path), |
| 1432 env_override_(env_override), | 1410 env_override_(env_override), |
| 1433 largest_known_change_id_(0), | 1411 largest_known_change_id_(0), |
| 1434 weak_ptr_factory_(this) { | 1412 weak_ptr_factory_(this) { |
| 1435 DCHECK(worker_task_runner); | 1413 DCHECK(worker_task_runner); |
| 1436 DCHECK(file_task_runner); | |
| 1437 } | 1414 } |
| 1438 | 1415 |
| 1439 // static | 1416 // static |
| 1440 void MetadataDatabase::CreateOnFileTaskRunner( | 1417 void MetadataDatabase::CreateOnWorkerTaskRunner( |
| 1441 scoped_ptr<CreateParam> create_param, | 1418 scoped_ptr<CreateParam> create_param, |
| 1442 const CreateCallback& callback) { | 1419 const CreateCallback& callback) { |
|
nhiroki
2014/08/04 05:27:14
Can you check 'worker_sequence_checker_' here?
peria
2014/08/04 05:52:34
This is a static method, so we cannot use member v
| |
| 1443 scoped_ptr<MetadataDatabase> metadata_database( | 1420 scoped_ptr<MetadataDatabase> metadata_database( |
| 1444 new MetadataDatabase(create_param->worker_task_runner.get(), | 1421 new MetadataDatabase(create_param->worker_task_runner.get(), |
| 1445 create_param->file_task_runner.get(), | |
| 1446 create_param->database_path, | 1422 create_param->database_path, |
| 1447 create_param->env_override)); | 1423 create_param->env_override)); |
| 1448 SyncStatusCode status = | 1424 SyncStatusCode status = metadata_database->Initialize(); |
| 1449 metadata_database->InitializeOnFileTaskRunner(); | |
| 1450 if (status != SYNC_STATUS_OK) | 1425 if (status != SYNC_STATUS_OK) |
| 1451 metadata_database.reset(); | 1426 metadata_database.reset(); |
| 1452 | 1427 |
| 1453 metadata_database->DetachFromSequence(); | 1428 metadata_database->DetachFromSequence(); |
| 1454 create_param->worker_task_runner->PostTask( | 1429 create_param->worker_task_runner->PostTask( |
| 1455 FROM_HERE, | 1430 FROM_HERE, |
| 1456 base::Bind( | 1431 base::Bind( |
| 1457 callback, status, base::Passed(&metadata_database))); | 1432 callback, status, base::Passed(&metadata_database))); |
| 1458 } | 1433 } |
| 1459 | 1434 |
| 1460 SyncStatusCode MetadataDatabase::InitializeOnFileTaskRunner() { | 1435 SyncStatusCode MetadataDatabase::Initialize() { |
| 1461 base::ThreadRestrictions::AssertIOAllowed(); | 1436 base::ThreadRestrictions::AssertIOAllowed(); |
| 1462 DCHECK(file_task_runner_->RunsTasksOnCurrentThread()); | 1437 DCHECK(worker_task_runner_->RunsTasksOnCurrentThread()); |
|
nhiroki
2014/08/04 05:27:15
You may have to use "worker_sequence_checker_".
peria
2014/08/04 05:52:34
Done.
| |
| 1463 | 1438 |
| 1464 SyncStatusCode status = SYNC_STATUS_UNKNOWN; | 1439 SyncStatusCode status = SYNC_STATUS_UNKNOWN; |
| 1465 bool created = false; | 1440 bool created = false; |
| 1466 // Open database unless |db_| is overridden for testing. | 1441 // Open database unless |db_| is overridden for testing. |
| 1467 if (!db_) { | 1442 if (!db_) { |
| 1468 status = OpenDatabase(database_path_, env_override_, &db_, &created); | 1443 status = OpenDatabase(database_path_, env_override_, &db_, &created); |
| 1469 if (status != SYNC_STATUS_OK) | 1444 if (status != SYNC_STATUS_OK) |
| 1470 return status; | 1445 return status; |
| 1471 } | 1446 } |
| 1472 | 1447 |
| (...skipping 264 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1737 const SyncStatusCallback& callback) { | 1712 const SyncStatusCallback& callback) { |
| 1738 DCHECK(worker_sequence_checker_.CalledOnValidSequencedThread()); | 1713 DCHECK(worker_sequence_checker_.CalledOnValidSequencedThread()); |
| 1739 | 1714 |
| 1740 if (!batch) { | 1715 if (!batch) { |
| 1741 worker_task_runner_->PostTask( | 1716 worker_task_runner_->PostTask( |
| 1742 FROM_HERE, | 1717 FROM_HERE, |
| 1743 base::Bind(callback, SYNC_STATUS_OK)); | 1718 base::Bind(callback, SYNC_STATUS_OK)); |
| 1744 return; | 1719 return; |
| 1745 } | 1720 } |
| 1746 | 1721 |
| 1747 // TODO(peria): Write to DB on disk synchronously. | 1722 leveldb::Status status = db_->Write(leveldb::WriteOptions(), batch.get()); |
| 1748 file_task_runner_->PostTask( | 1723 worker_task_runner_->PostTask( |
| 1749 FROM_HERE, | 1724 FROM_HERE, |
| 1750 base::Bind(&WriteOnFileTaskRunner, | 1725 base::Bind(callback, LevelDBStatusToSyncStatusCode(status))); |
|
nhiroki
2014/08/04 05:27:15
I guess you don't have to post a task here since y
peria
2014/08/04 05:52:34
Done.
| |
| 1751 base::Unretained(db_.get()), | |
| 1752 base::Passed(&batch), | |
| 1753 worker_task_runner_, | |
| 1754 callback)); | |
| 1755 } | 1726 } |
| 1756 | 1727 |
| 1757 scoped_ptr<base::ListValue> MetadataDatabase::DumpFiles( | 1728 scoped_ptr<base::ListValue> MetadataDatabase::DumpFiles( |
| 1758 const std::string& app_id) { | 1729 const std::string& app_id) { |
| 1759 DCHECK(worker_sequence_checker_.CalledOnValidSequencedThread()); | 1730 DCHECK(worker_sequence_checker_.CalledOnValidSequencedThread()); |
| 1760 | 1731 |
| 1761 scoped_ptr<base::ListValue> files(new base::ListValue); | 1732 scoped_ptr<base::ListValue> files(new base::ListValue); |
| 1762 | 1733 |
| 1763 FileTracker app_root_tracker; | 1734 FileTracker app_root_tracker; |
| 1764 if (!FindAppRootTracker(app_id, &app_root_tracker)) | 1735 if (!FindAppRootTracker(app_id, &app_root_tracker)) |
| (...skipping 201 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1966 index_->StoreFileMetadata(app_root_metadata.Pass(), batch); | 1937 index_->StoreFileMetadata(app_root_metadata.Pass(), batch); |
| 1967 index_->StoreFileTracker(app_root_tracker.Pass(), batch); | 1938 index_->StoreFileTracker(app_root_tracker.Pass(), batch); |
| 1968 } | 1939 } |
| 1969 | 1940 |
| 1970 void MetadataDatabase::DetachFromSequence() { | 1941 void MetadataDatabase::DetachFromSequence() { |
| 1971 worker_sequence_checker_.DetachFromSequence(); | 1942 worker_sequence_checker_.DetachFromSequence(); |
| 1972 } | 1943 } |
| 1973 | 1944 |
| 1974 } // namespace drive_backend | 1945 } // namespace drive_backend |
| 1975 } // namespace sync_file_system | 1946 } // namespace sync_file_system |
| OLD | NEW |