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 482 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
493 | 493 |
494 int64 MetadataDatabase::GetLargestFetchedChangeID() const { | 494 int64 MetadataDatabase::GetLargestFetchedChangeID() const { |
495 return service_metadata_->largest_change_id(); | 495 return service_metadata_->largest_change_id(); |
496 } | 496 } |
497 | 497 |
498 int64 MetadataDatabase::GetSyncRootTrackerID() const { | 498 int64 MetadataDatabase::GetSyncRootTrackerID() const { |
499 return service_metadata_->sync_root_tracker_id(); | 499 return service_metadata_->sync_root_tracker_id(); |
500 } | 500 } |
501 | 501 |
502 int64 MetadataDatabase::GetLargestKnownChangeID() const { | 502 int64 MetadataDatabase::GetLargestKnownChangeID() const { |
503 // TODO(tzik): Implement: | 503 DCHECK_LE(GetLargestFetchedChangeID(), largest_known_change_id_); |
504 // - Add |largest_known_file_id| member to hold the value, that should | 504 return largest_known_change_id_; |
505 // initially have the same value to |largest_change_id|. | |
506 // - Change UpdateByFileResource and UpdateByChangeList not to overwrite | |
507 // FileMetadata if the newer one. | |
508 // - Change ListChangesTask to set UpdateLargestKnownChangeID. | |
509 return GetLargestFetchedChangeID(); | |
510 } | 505 } |
511 | 506 |
512 void MetadataDatabase::UpdateLargestKnownChangeID(int64 change_id) { | 507 void MetadataDatabase::UpdateLargestKnownChangeID(int64 change_id) { |
513 NOTIMPLEMENTED(); | 508 if (largest_known_change_id_ < change_id) |
| 509 largest_known_change_id_ = change_id; |
514 } | 510 } |
515 | 511 |
516 bool MetadataDatabase::HasSyncRoot() const { | 512 bool MetadataDatabase::HasSyncRoot() const { |
517 return service_metadata_->has_sync_root_tracker_id() && | 513 return service_metadata_->has_sync_root_tracker_id() && |
518 !!service_metadata_->sync_root_tracker_id(); | 514 !!service_metadata_->sync_root_tracker_id(); |
519 } | 515 } |
520 | 516 |
521 void MetadataDatabase::PopulateInitialData( | 517 void MetadataDatabase::PopulateInitialData( |
522 int64 largest_change_id, | 518 int64 largest_change_id, |
523 const google_apis::FileResource& sync_root_folder, | 519 const google_apis::FileResource& sync_root_folder, |
524 const ScopedVector<google_apis::FileResource>& app_root_folders, | 520 const ScopedVector<google_apis::FileResource>& app_root_folders, |
525 const SyncStatusCallback& callback) { | 521 const SyncStatusCallback& callback) { |
526 DCHECK(tracker_by_id_.empty()); | 522 DCHECK(tracker_by_id_.empty()); |
527 DCHECK(file_by_id_.empty()); | 523 DCHECK(file_by_id_.empty()); |
528 | 524 |
529 scoped_ptr<leveldb::WriteBatch> batch(new leveldb::WriteBatch); | 525 scoped_ptr<leveldb::WriteBatch> batch(new leveldb::WriteBatch); |
530 service_metadata_->set_largest_change_id(largest_change_id); | 526 service_metadata_->set_largest_change_id(largest_change_id); |
| 527 UpdateLargestKnownChangeID(largest_change_id); |
531 | 528 |
532 FileTracker* sync_root_tracker = NULL; | 529 FileTracker* sync_root_tracker = NULL; |
533 int64 sync_root_tracker_id = 0; | 530 int64 sync_root_tracker_id = 0; |
534 { | 531 { |
535 scoped_ptr<FileMetadata> folder; | 532 scoped_ptr<FileMetadata> folder; |
536 scoped_ptr<FileTracker> tracker; | 533 scoped_ptr<FileTracker> tracker; |
537 CreateInitialSyncRootTracker(GetNextTrackerID(batch.get()), | 534 CreateInitialSyncRootTracker(GetNextTrackerID(batch.get()), |
538 sync_root_folder, | 535 sync_root_folder, |
539 &folder, | 536 &folder, |
540 &tracker); | 537 &tracker); |
(...skipping 213 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
754 const SyncStatusCallback& callback) { | 751 const SyncStatusCallback& callback) { |
755 DCHECK_LE(service_metadata_->largest_change_id(), largest_change_id); | 752 DCHECK_LE(service_metadata_->largest_change_id(), largest_change_id); |
756 | 753 |
757 scoped_ptr<leveldb::WriteBatch> batch(new leveldb::WriteBatch); | 754 scoped_ptr<leveldb::WriteBatch> batch(new leveldb::WriteBatch); |
758 | 755 |
759 for (ScopedVector<google_apis::ChangeResource>::const_iterator itr = | 756 for (ScopedVector<google_apis::ChangeResource>::const_iterator itr = |
760 changes.begin(); | 757 changes.begin(); |
761 itr != changes.end(); | 758 itr != changes.end(); |
762 ++itr) { | 759 ++itr) { |
763 const google_apis::ChangeResource& change = **itr; | 760 const google_apis::ChangeResource& change = **itr; |
| 761 if (HasNewerFileMetadata(change.file_id(), change.change_id())) |
| 762 continue; |
| 763 |
764 scoped_ptr<FileMetadata> file( | 764 scoped_ptr<FileMetadata> file( |
765 CreateFileMetadataFromChangeResource(change)); | 765 CreateFileMetadataFromChangeResource(change)); |
766 std::string file_id = file->file_id(); | 766 std::string file_id = file->file_id(); |
767 | 767 |
768 MarkTrackersDirtyByFileID(file_id, batch.get()); | 768 MarkTrackersDirtyByFileID(file_id, batch.get()); |
769 if (!file->details().deleted()) | 769 if (!file->details().deleted()) |
770 MaybeAddTrackersForNewFile(*file, batch.get()); | 770 MaybeAddTrackersForNewFile(*file, batch.get()); |
771 | 771 |
772 if (FindTrackersByFileID(file_id, NULL)) { | 772 if (FindTrackersByFileID(file_id, NULL)) { |
773 PutFileToBatch(*file, batch.get()); | 773 PutFileToBatch(*file, batch.get()); |
774 | 774 |
775 // Set |file| to |file_by_id_[file_id]| and delete old value. | 775 // Set |file| to |file_by_id_[file_id]| and delete old value. |
776 FileMetadata* file_ptr = file.release(); | 776 FileMetadata* file_ptr = file.release(); |
777 std::swap(file_ptr, file_by_id_[file_id]); | 777 std::swap(file_ptr, file_by_id_[file_id]); |
778 delete file_ptr; | 778 delete file_ptr; |
779 } | 779 } |
780 } | 780 } |
781 | 781 |
| 782 UpdateLargestKnownChangeID(largest_change_id); |
782 service_metadata_->set_largest_change_id(largest_change_id); | 783 service_metadata_->set_largest_change_id(largest_change_id); |
783 PutServiceMetadataToBatch(*service_metadata_, batch.get()); | 784 PutServiceMetadataToBatch(*service_metadata_, batch.get()); |
784 WriteToDatabase(batch.Pass(), callback); | 785 WriteToDatabase(batch.Pass(), callback); |
785 } | 786 } |
786 | 787 |
787 void MetadataDatabase::UpdateByFileResource( | 788 void MetadataDatabase::UpdateByFileResource( |
788 int64 change_id, | 789 int64 change_id, |
789 const google_apis::FileResource& resource, | 790 const google_apis::FileResource& resource, |
790 const SyncStatusCallback& callback) { | 791 const SyncStatusCallback& callback) { |
791 scoped_ptr<leveldb::WriteBatch> batch(new leveldb::WriteBatch); | 792 scoped_ptr<leveldb::WriteBatch> batch(new leveldb::WriteBatch); |
792 | 793 |
793 scoped_ptr<FileMetadata> file( | 794 scoped_ptr<FileMetadata> file( |
794 CreateFileMetadataFromFileResource(change_id, resource)); | 795 CreateFileMetadataFromFileResource(change_id, resource)); |
795 std::string file_id = file->file_id(); | 796 std::string file_id = file->file_id(); |
| 797 if (HasNewerFileMetadata(file_id, change_id)) |
| 798 return; |
796 | 799 |
797 // TODO(tzik): Consolidate with UpdateByChangeList. | 800 // TODO(tzik): Consolidate with UpdateByChangeList. |
798 MarkTrackersDirtyByFileID(file_id, batch.get()); | 801 MarkTrackersDirtyByFileID(file_id, batch.get()); |
799 if (!file->details().deleted()) { | 802 if (!file->details().deleted()) { |
800 MaybeAddTrackersForNewFile(*file, batch.get()); | 803 MaybeAddTrackersForNewFile(*file, batch.get()); |
801 | 804 |
802 if (FindTrackersByFileID(file_id, NULL)) { | 805 if (FindTrackersByFileID(file_id, NULL)) { |
803 PutFileToBatch(*file, batch.get()); | 806 PutFileToBatch(*file, batch.get()); |
804 | 807 |
805 // Set |file| to |file_by_id_[file_id]| and delete old value. | 808 // Set |file| to |file_by_id_[file_id]| and delete old value. |
(...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
947 NOTIMPLEMENTED(); | 950 NOTIMPLEMENTED(); |
948 return false; | 951 return false; |
949 } | 952 } |
950 | 953 |
951 bool MetadataDatabase::GetLowPriorityDirtyTracker(FileTracker* tracker) { | 954 bool MetadataDatabase::GetLowPriorityDirtyTracker(FileTracker* tracker) { |
952 NOTIMPLEMENTED(); | 955 NOTIMPLEMENTED(); |
953 return false; | 956 return false; |
954 } | 957 } |
955 | 958 |
956 MetadataDatabase::MetadataDatabase(base::SequencedTaskRunner* task_runner) | 959 MetadataDatabase::MetadataDatabase(base::SequencedTaskRunner* task_runner) |
957 : task_runner_(task_runner), weak_ptr_factory_(this) { | 960 : task_runner_(task_runner), |
| 961 largest_known_change_id_(0), |
| 962 weak_ptr_factory_(this) { |
958 DCHECK(task_runner); | 963 DCHECK(task_runner); |
959 } | 964 } |
960 | 965 |
961 // static | 966 // static |
962 void MetadataDatabase::CreateOnTaskRunner( | 967 void MetadataDatabase::CreateOnTaskRunner( |
963 base::SingleThreadTaskRunner* callback_runner, | 968 base::SingleThreadTaskRunner* callback_runner, |
964 base::SequencedTaskRunner* task_runner, | 969 base::SequencedTaskRunner* task_runner, |
965 const base::FilePath& database_path, | 970 const base::FilePath& database_path, |
966 const CreateCallback& callback) { | 971 const CreateCallback& callback) { |
967 scoped_ptr<MetadataDatabase> metadata_database( | 972 scoped_ptr<MetadataDatabase> metadata_database( |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1041 db_->Write(leveldb::WriteOptions(), &batch)); | 1046 db_->Write(leveldb::WriteOptions(), &batch)); |
1042 if (status != SYNC_STATUS_OK) | 1047 if (status != SYNC_STATUS_OK) |
1043 return status; | 1048 return status; |
1044 | 1049 |
1045 BuildIndexes(&contents); | 1050 BuildIndexes(&contents); |
1046 return status; | 1051 return status; |
1047 } | 1052 } |
1048 | 1053 |
1049 void MetadataDatabase::BuildIndexes(DatabaseContents* contents) { | 1054 void MetadataDatabase::BuildIndexes(DatabaseContents* contents) { |
1050 service_metadata_ = contents->service_metadata.Pass(); | 1055 service_metadata_ = contents->service_metadata.Pass(); |
| 1056 UpdateLargestKnownChangeID(service_metadata_->largest_change_id()); |
1051 | 1057 |
1052 for (ScopedVector<FileMetadata>::const_iterator itr = | 1058 for (ScopedVector<FileMetadata>::const_iterator itr = |
1053 contents->file_metadata.begin(); | 1059 contents->file_metadata.begin(); |
1054 itr != contents->file_metadata.end(); | 1060 itr != contents->file_metadata.end(); |
1055 ++itr) { | 1061 ++itr) { |
1056 file_by_id_[(*itr)->file_id()] = *itr; | 1062 file_by_id_[(*itr)->file_id()] = *itr; |
1057 } | 1063 } |
1058 contents->file_metadata.weak_clear(); | 1064 contents->file_metadata.weak_clear(); |
1059 | 1065 |
1060 for (ScopedVector<FileTracker>::const_iterator itr = | 1066 for (ScopedVector<FileTracker>::const_iterator itr = |
(...skipping 487 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1548 details->SetString("dirty", tracker->dirty() ? "true" : "false"); | 1554 details->SetString("dirty", tracker->dirty() ? "true" : "false"); |
1549 | 1555 |
1550 file->Set("details", details); | 1556 file->Set("details", details); |
1551 | 1557 |
1552 files->Append(file); | 1558 files->Append(file); |
1553 } | 1559 } |
1554 | 1560 |
1555 return files.Pass(); | 1561 return files.Pass(); |
1556 } | 1562 } |
1557 | 1563 |
| 1564 bool MetadataDatabase::HasNewerFileMetadata(const std::string& file_id, |
| 1565 int64 change_id) { |
| 1566 FileByID::const_iterator found = file_by_id_.find(file_id); |
| 1567 if (found == file_by_id_.end()) |
| 1568 return false; |
| 1569 DCHECK(found->second->has_details()); |
| 1570 return found->second->details().change_id() >= change_id; |
| 1571 } |
| 1572 |
1558 } // namespace drive_backend | 1573 } // namespace drive_backend |
1559 } // namespace sync_file_system | 1574 } // namespace sync_file_system |
OLD | NEW |