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 "components/sync/syncable/directory.h" | 5 #include "components/sync/syncable/directory.h" |
6 | 6 |
7 #include <stddef.h> | 7 #include <stddef.h> |
8 #include <stdint.h> | 8 #include <stdint.h> |
9 | 9 |
10 #include <algorithm> | 10 #include <algorithm> |
11 #include <iterator> | 11 #include <iterator> |
12 #include <utility> | 12 #include <utility> |
13 | 13 |
14 #include "base/base64.h" | 14 #include "base/base64.h" |
15 #include "base/guid.h" | 15 #include "base/guid.h" |
16 #include "base/memory/ptr_util.h" | 16 #include "base/memory/ptr_util.h" |
17 #include "base/metrics/histogram_macros.h" | 17 #include "base/metrics/histogram_macros.h" |
18 #include "base/stl_util.h" | |
19 #include "base/strings/string_number_conversions.h" | 18 #include "base/strings/string_number_conversions.h" |
20 #include "base/trace_event/trace_event.h" | 19 #include "base/trace_event/trace_event.h" |
21 #include "components/sync/base/attachment_id_proto.h" | 20 #include "components/sync/base/attachment_id_proto.h" |
22 #include "components/sync/base/unique_position.h" | 21 #include "components/sync/base/unique_position.h" |
23 #include "components/sync/base/unrecoverable_error_handler.h" | 22 #include "components/sync/base/unrecoverable_error_handler.h" |
24 #include "components/sync/syncable/entry.h" | 23 #include "components/sync/syncable/entry.h" |
25 #include "components/sync/syncable/entry_kernel.h" | 24 #include "components/sync/syncable/entry_kernel.h" |
26 #include "components/sync/syncable/in_memory_directory_backing_store.h" | 25 #include "components/sync/syncable/in_memory_directory_backing_store.h" |
27 #include "components/sync/syncable/model_neutral_mutable_entry.h" | 26 #include "components/sync/syncable/model_neutral_mutable_entry.h" |
28 #include "components/sync/syncable/on_disk_directory_backing_store.h" | 27 #include "components/sync/syncable/on_disk_directory_backing_store.h" |
29 #include "components/sync/syncable/scoped_kernel_lock.h" | 28 #include "components/sync/syncable/scoped_kernel_lock.h" |
30 #include "components/sync/syncable/scoped_parent_child_index_updater.h" | 29 #include "components/sync/syncable/scoped_parent_child_index_updater.h" |
31 #include "components/sync/syncable/syncable-inl.h" | |
32 #include "components/sync/syncable/syncable_base_transaction.h" | 30 #include "components/sync/syncable/syncable_base_transaction.h" |
33 #include "components/sync/syncable/syncable_changes_version.h" | 31 #include "components/sync/syncable/syncable_changes_version.h" |
34 #include "components/sync/syncable/syncable_read_transaction.h" | 32 #include "components/sync/syncable/syncable_read_transaction.h" |
35 #include "components/sync/syncable/syncable_util.h" | 33 #include "components/sync/syncable/syncable_util.h" |
36 #include "components/sync/syncable/syncable_write_transaction.h" | 34 #include "components/sync/syncable/syncable_write_transaction.h" |
37 | 35 |
38 using std::string; | 36 using std::string; |
39 | 37 |
40 namespace syncer { | 38 namespace syncer { |
41 namespace syncable { | 39 namespace syncable { |
(...skipping 27 matching lines...) Expand all Loading... | |
69 bool Directory::PersistedKernelInfo::HasEmptyDownloadProgress( | 67 bool Directory::PersistedKernelInfo::HasEmptyDownloadProgress( |
70 ModelType model_type) { | 68 ModelType model_type) { |
71 const sync_pb::DataTypeProgressMarker& progress_marker = | 69 const sync_pb::DataTypeProgressMarker& progress_marker = |
72 download_progress[model_type]; | 70 download_progress[model_type]; |
73 return progress_marker.token().empty(); | 71 return progress_marker.token().empty(); |
74 } | 72 } |
75 | 73 |
76 Directory::SaveChangesSnapshot::SaveChangesSnapshot() | 74 Directory::SaveChangesSnapshot::SaveChangesSnapshot() |
77 : kernel_info_status(KERNEL_SHARE_INFO_INVALID) {} | 75 : kernel_info_status(KERNEL_SHARE_INFO_INVALID) {} |
78 | 76 |
79 Directory::SaveChangesSnapshot::~SaveChangesSnapshot() { | 77 Directory::SaveChangesSnapshot::~SaveChangesSnapshot() {} |
80 base::STLDeleteElements(&dirty_metas); | |
81 base::STLDeleteElements(&delete_journals); | |
82 } | |
83 | 78 |
84 bool Directory::SaveChangesSnapshot::HasUnsavedMetahandleChanges() const { | 79 bool Directory::SaveChangesSnapshot::HasUnsavedMetahandleChanges() const { |
85 return !dirty_metas.empty() || !metahandles_to_purge.empty() || | 80 return !dirty_metas.empty() || !metahandles_to_purge.empty() || |
86 !delete_journals.empty() || !delete_journals_to_purge.empty(); | 81 !delete_journals.empty() || !delete_journals_to_purge.empty(); |
87 } | 82 } |
88 | 83 |
89 Directory::Kernel::Kernel( | 84 Directory::Kernel::Kernel( |
90 const std::string& name, | 85 const std::string& name, |
91 const KernelLoadInfo& info, | 86 const KernelLoadInfo& info, |
92 DirectoryChangeDelegate* delegate, | 87 DirectoryChangeDelegate* delegate, |
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
176 | 171 |
177 DirOpenResult Directory::OpenImpl( | 172 DirOpenResult Directory::OpenImpl( |
178 const string& name, | 173 const string& name, |
179 DirectoryChangeDelegate* delegate, | 174 DirectoryChangeDelegate* delegate, |
180 const WeakHandle<TransactionObserver>& transaction_observer) { | 175 const WeakHandle<TransactionObserver>& transaction_observer) { |
181 KernelLoadInfo info; | 176 KernelLoadInfo info; |
182 // Temporary indices before kernel_ initialized in case Load fails. We 0(1) | 177 // Temporary indices before kernel_ initialized in case Load fails. We 0(1) |
183 // swap these later. | 178 // swap these later. |
184 Directory::MetahandlesMap tmp_handles_map; | 179 Directory::MetahandlesMap tmp_handles_map; |
185 | 180 |
186 JournalIndex delete_journals; | 181 std::unique_ptr<JournalIndex> delete_journals = |
182 base::MakeUnique<JournalIndex>(); | |
187 MetahandleSet metahandles_to_purge; | 183 MetahandleSet metahandles_to_purge; |
188 | 184 |
189 DirOpenResult result = store_->Load(&tmp_handles_map, &delete_journals, | 185 DirOpenResult result = store_->Load(&tmp_handles_map, delete_journals.get(), |
190 &metahandles_to_purge, &info); | 186 &metahandles_to_purge, &info); |
191 if (OPENED != result) | 187 if (OPENED != result) |
192 return result; | 188 return result; |
193 | 189 |
194 DCHECK(!kernel_); | 190 DCHECK(!kernel_); |
195 kernel_ = new Kernel(name, info, delegate, transaction_observer); | 191 kernel_ = new Kernel(name, info, delegate, transaction_observer); |
196 kernel_->metahandles_to_purge.swap(metahandles_to_purge); | 192 kernel_->metahandles_to_purge.swap(metahandles_to_purge); |
197 delete_journal_.reset(new DeleteJournal(&delete_journals)); | 193 delete_journal_ = base::MakeUnique<DeleteJournal>(std::move(delete_journals)); |
maxbogue
2016/09/01 21:10:22
I don't think you need the MakeUnique here, do you
maxbogue
2016/09/01 21:13:17
Never mind, Pavel pointed out that these are diffe
| |
198 InitializeIndices(&tmp_handles_map); | 194 InitializeIndices(&tmp_handles_map); |
199 | 195 |
200 // Save changes back in case there are any metahandles to purge. | 196 // Save changes back in case there are any metahandles to purge. |
201 if (!SaveChanges()) | 197 if (!SaveChanges()) |
202 return FAILED_INITIAL_WRITE; | 198 return FAILED_INITIAL_WRITE; |
203 | 199 |
204 // Now that we've successfully opened the store, install an error handler to | 200 // Now that we've successfully opened the store, install an error handler to |
205 // deal with catastrophic errors that may occur later on. Use a weak pointer | 201 // deal with catastrophic errors that may occur later on. Use a weak pointer |
206 // because we cannot guarantee that this Directory will outlive the Closure. | 202 // because we cannot guarantee that this Directory will outlive the Closure. |
207 store_->SetCatastrophicErrorHandler(base::Bind( | 203 store_->SetCatastrophicErrorHandler(base::Bind( |
(...skipping 326 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
534 // clear dirty flags. | 530 // clear dirty flags. |
535 for (MetahandleSet::const_iterator i = kernel_->dirty_metahandles.begin(); | 531 for (MetahandleSet::const_iterator i = kernel_->dirty_metahandles.begin(); |
536 i != kernel_->dirty_metahandles.end(); ++i) { | 532 i != kernel_->dirty_metahandles.end(); ++i) { |
537 EntryKernel* entry = GetEntryByHandle(lock, *i); | 533 EntryKernel* entry = GetEntryByHandle(lock, *i); |
538 if (!entry) | 534 if (!entry) |
539 continue; | 535 continue; |
540 // Skip over false positives; it happens relatively infrequently. | 536 // Skip over false positives; it happens relatively infrequently. |
541 if (!entry->is_dirty()) | 537 if (!entry->is_dirty()) |
542 continue; | 538 continue; |
543 snapshot->dirty_metas.insert(snapshot->dirty_metas.end(), | 539 snapshot->dirty_metas.insert(snapshot->dirty_metas.end(), |
544 new EntryKernel(*entry)); | 540 base::MakeUnique<EntryKernel>(*entry)); |
545 DCHECK_EQ(1U, kernel_->dirty_metahandles.count(*i)); | 541 DCHECK_EQ(1U, kernel_->dirty_metahandles.count(*i)); |
546 // We don't bother removing from the index here as we blow the entire thing | 542 // We don't bother removing from the index here as we blow the entire thing |
547 // in a moment, and it unnecessarily complicates iteration. | 543 // in a moment, and it unnecessarily complicates iteration. |
548 entry->clear_dirty(NULL); | 544 entry->clear_dirty(NULL); |
549 } | 545 } |
550 ClearDirtyMetahandles(lock); | 546 ClearDirtyMetahandles(lock); |
551 | 547 |
552 // Set purged handles. | 548 // Set purged handles. |
553 DCHECK(snapshot->metahandles_to_purge.empty()); | 549 DCHECK(snapshot->metahandles_to_purge.empty()); |
554 snapshot->metahandles_to_purge.swap(kernel_->metahandles_to_purge); | 550 snapshot->metahandles_to_purge.swap(kernel_->metahandles_to_purge); |
(...skipping 27 matching lines...) Expand all Loading... | |
582 } | 578 } |
583 | 579 |
584 bool Directory::VacuumAfterSaveChanges(const SaveChangesSnapshot& snapshot) { | 580 bool Directory::VacuumAfterSaveChanges(const SaveChangesSnapshot& snapshot) { |
585 if (snapshot.dirty_metas.empty()) | 581 if (snapshot.dirty_metas.empty()) |
586 return true; | 582 return true; |
587 | 583 |
588 // Need a write transaction as we are about to permanently purge entries. | 584 // Need a write transaction as we are about to permanently purge entries. |
589 WriteTransaction trans(FROM_HERE, VACUUM_AFTER_SAVE, this); | 585 WriteTransaction trans(FROM_HERE, VACUUM_AFTER_SAVE, this); |
590 ScopedKernelLock lock(this); | 586 ScopedKernelLock lock(this); |
591 // Now drop everything we can out of memory. | 587 // Now drop everything we can out of memory. |
592 for (EntryKernelSet::const_iterator i = snapshot.dirty_metas.begin(); | 588 for (auto i = snapshot.dirty_metas.begin(); i != snapshot.dirty_metas.end(); |
593 i != snapshot.dirty_metas.end(); ++i) { | 589 ++i) { |
594 MetahandlesMap::iterator found = | 590 MetahandlesMap::iterator found = |
595 kernel_->metahandles_map.find((*i)->ref(META_HANDLE)); | 591 kernel_->metahandles_map.find((*i)->ref(META_HANDLE)); |
596 EntryKernel* entry = | 592 EntryKernel* entry = |
597 (found == kernel_->metahandles_map.end() ? NULL : found->second.get()); | 593 (found == kernel_->metahandles_map.end() ? NULL : found->second.get()); |
598 if (entry && SafeToPurgeFromMemory(&trans, entry)) { | 594 if (entry && SafeToPurgeFromMemory(&trans, entry)) { |
599 // We now drop deleted metahandles that are up to date on both the client | 595 // We now drop deleted metahandles that are up to date on both the client |
600 // and the server. | 596 // and the server. |
601 std::unique_ptr<EntryKernel> unique_entry = std::move(found->second); | 597 std::unique_ptr<EntryKernel> unique_entry = std::move(found->second); |
602 | 598 |
603 size_t num_erased = 0; | 599 size_t num_erased = 0; |
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
679 | 675 |
680 // At this point locally created items that aren't synced will become locally | 676 // At this point locally created items that aren't synced will become locally |
681 // deleted items, and purged on the next snapshot. All other items will match | 677 // deleted items, and purged on the next snapshot. All other items will match |
682 // the state they would have had if they were just created via a server | 678 // the state they would have had if they were just created via a server |
683 // update. See MutableEntry::MutableEntry(.., CreateNewUpdateItem, ..). | 679 // update. See MutableEntry::MutableEntry(.., CreateNewUpdateItem, ..). |
684 } | 680 } |
685 | 681 |
686 void Directory::DeleteEntry(const ScopedKernelLock& lock, | 682 void Directory::DeleteEntry(const ScopedKernelLock& lock, |
687 bool save_to_journal, | 683 bool save_to_journal, |
688 EntryKernel* entry, | 684 EntryKernel* entry, |
689 EntryKernelSet* entries_to_journal) { | 685 OwnedEntryKernelSet* entries_to_journal) { |
690 int64_t handle = entry->ref(META_HANDLE); | 686 int64_t handle = entry->ref(META_HANDLE); |
691 ModelType server_type = | 687 ModelType server_type = |
692 GetModelTypeFromSpecifics(entry->ref(SERVER_SPECIFICS)); | 688 GetModelTypeFromSpecifics(entry->ref(SERVER_SPECIFICS)); |
693 | 689 |
694 kernel_->metahandles_to_purge.insert(handle); | 690 kernel_->metahandles_to_purge.insert(handle); |
695 | 691 |
696 std::unique_ptr<EntryKernel> entry_ptr = | 692 std::unique_ptr<EntryKernel> entry_ptr = |
697 std::move(kernel_->metahandles_map[handle]); | 693 std::move(kernel_->metahandles_map[handle]); |
698 | 694 |
699 size_t num_erased = 0; | 695 size_t num_erased = 0; |
(...skipping 12 matching lines...) Expand all Loading... | |
712 num_erased = kernel_->client_tags_map.erase(entry->ref(UNIQUE_CLIENT_TAG)); | 708 num_erased = kernel_->client_tags_map.erase(entry->ref(UNIQUE_CLIENT_TAG)); |
713 DCHECK_EQ(1u, num_erased); | 709 DCHECK_EQ(1u, num_erased); |
714 } | 710 } |
715 if (!entry->ref(UNIQUE_SERVER_TAG).empty()) { | 711 if (!entry->ref(UNIQUE_SERVER_TAG).empty()) { |
716 num_erased = kernel_->server_tags_map.erase(entry->ref(UNIQUE_SERVER_TAG)); | 712 num_erased = kernel_->server_tags_map.erase(entry->ref(UNIQUE_SERVER_TAG)); |
717 DCHECK_EQ(1u, num_erased); | 713 DCHECK_EQ(1u, num_erased); |
718 } | 714 } |
719 RemoveFromAttachmentIndex(lock, handle, entry->ref(ATTACHMENT_METADATA)); | 715 RemoveFromAttachmentIndex(lock, handle, entry->ref(ATTACHMENT_METADATA)); |
720 | 716 |
721 if (save_to_journal) { | 717 if (save_to_journal) { |
722 entries_to_journal->insert(entry_ptr.release()); | 718 entries_to_journal->insert(std::move(entry_ptr)); |
723 } | 719 } |
724 } | 720 } |
725 | 721 |
726 bool Directory::PurgeEntriesWithTypeIn(ModelTypeSet disabled_types, | 722 bool Directory::PurgeEntriesWithTypeIn(ModelTypeSet disabled_types, |
727 ModelTypeSet types_to_journal, | 723 ModelTypeSet types_to_journal, |
728 ModelTypeSet types_to_unapply) { | 724 ModelTypeSet types_to_unapply) { |
729 disabled_types.RemoveAll(ProxyTypes()); | 725 disabled_types.RemoveAll(ProxyTypes()); |
730 | 726 |
731 if (disabled_types.Empty()) | 727 if (disabled_types.Empty()) |
732 return true; | 728 return true; |
733 | 729 |
734 { | 730 { |
735 WriteTransaction trans(FROM_HERE, PURGE_ENTRIES, this); | 731 WriteTransaction trans(FROM_HERE, PURGE_ENTRIES, this); |
736 | 732 |
737 EntryKernelSet entries_to_journal; | 733 OwnedEntryKernelSet entries_to_journal; |
738 base::STLElementDeleter<EntryKernelSet> journal_deleter( | |
739 &entries_to_journal); | |
740 | 734 |
741 { | 735 { |
742 ScopedKernelLock lock(this); | 736 ScopedKernelLock lock(this); |
743 | 737 |
744 bool found_progress = false; | 738 bool found_progress = false; |
745 for (ModelTypeSet::Iterator iter = disabled_types.First(); iter.Good(); | 739 for (ModelTypeSet::Iterator iter = disabled_types.First(); iter.Good(); |
746 iter.Inc()) { | 740 iter.Inc()) { |
747 if (!kernel_->persisted_info.HasEmptyDownloadProgress(iter.Get())) | 741 if (!kernel_->persisted_info.HasEmptyDownloadProgress(iter.Get())) |
748 found_progress = true; | 742 found_progress = true; |
749 } | 743 } |
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
850 void Directory::HandleSaveChangesFailure(const SaveChangesSnapshot& snapshot) { | 844 void Directory::HandleSaveChangesFailure(const SaveChangesSnapshot& snapshot) { |
851 WriteTransaction trans(FROM_HERE, HANDLE_SAVE_FAILURE, this); | 845 WriteTransaction trans(FROM_HERE, HANDLE_SAVE_FAILURE, this); |
852 ScopedKernelLock lock(this); | 846 ScopedKernelLock lock(this); |
853 kernel_->info_status = KERNEL_SHARE_INFO_DIRTY; | 847 kernel_->info_status = KERNEL_SHARE_INFO_DIRTY; |
854 | 848 |
855 // Because we optimistically cleared the dirty bit on the real entries when | 849 // Because we optimistically cleared the dirty bit on the real entries when |
856 // taking the snapshot, we must restore it on failure. Not doing this could | 850 // taking the snapshot, we must restore it on failure. Not doing this could |
857 // cause lost data, if no other changes are made to the in-memory entries | 851 // cause lost data, if no other changes are made to the in-memory entries |
858 // that would cause the dirty bit to get set again. Setting the bit ensures | 852 // that would cause the dirty bit to get set again. Setting the bit ensures |
859 // that SaveChanges will at least try again later. | 853 // that SaveChanges will at least try again later. |
860 for (EntryKernelSet::const_iterator i = snapshot.dirty_metas.begin(); | 854 for (auto i = snapshot.dirty_metas.begin(); i != snapshot.dirty_metas.end(); |
861 i != snapshot.dirty_metas.end(); ++i) { | 855 ++i) { |
862 MetahandlesMap::iterator found = | 856 MetahandlesMap::iterator found = |
863 kernel_->metahandles_map.find((*i)->ref(META_HANDLE)); | 857 kernel_->metahandles_map.find((*i)->ref(META_HANDLE)); |
864 if (found != kernel_->metahandles_map.end()) { | 858 if (found != kernel_->metahandles_map.end()) { |
865 found->second->mark_dirty(&kernel_->dirty_metahandles); | 859 found->second->mark_dirty(&kernel_->dirty_metahandles); |
866 } | 860 } |
867 } | 861 } |
868 | 862 |
869 kernel_->metahandles_to_purge.insert(snapshot.metahandles_to_purge.begin(), | 863 kernel_->metahandles_to_purge.insert(snapshot.metahandles_to_purge.begin(), |
870 snapshot.metahandles_to_purge.end()); | 864 snapshot.metahandles_to_purge.end()); |
871 | 865 |
(...skipping 667 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1539 Directory::Kernel* Directory::kernel() { | 1533 Directory::Kernel* Directory::kernel() { |
1540 return kernel_; | 1534 return kernel_; |
1541 } | 1535 } |
1542 | 1536 |
1543 const Directory::Kernel* Directory::kernel() const { | 1537 const Directory::Kernel* Directory::kernel() const { |
1544 return kernel_; | 1538 return kernel_; |
1545 } | 1539 } |
1546 | 1540 |
1547 } // namespace syncable | 1541 } // namespace syncable |
1548 } // namespace syncer | 1542 } // namespace syncer |
OLD | NEW |