OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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/syncable/syncable.h" | 5 #include "chrome/browser/sync/syncable/syncable.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 #include <cstring> | 8 #include <cstring> |
9 #include <functional> | 9 #include <functional> |
10 #include <iomanip> | 10 #include <iomanip> |
(...skipping 801 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
812 | 812 |
813 // Might not be in it | 813 // Might not be in it |
814 num_erased = kernel_->client_tag_index->erase(entry); | 814 num_erased = kernel_->client_tag_index->erase(entry); |
815 DCHECK_EQ(entry->ref(UNIQUE_CLIENT_TAG).empty(), !num_erased); | 815 DCHECK_EQ(entry->ref(UNIQUE_CLIENT_TAG).empty(), !num_erased); |
816 CHECK(!kernel_->parent_id_child_index->count(entry)); | 816 CHECK(!kernel_->parent_id_child_index->count(entry)); |
817 delete entry; | 817 delete entry; |
818 } | 818 } |
819 } | 819 } |
820 } | 820 } |
821 | 821 |
822 void Directory::PurgeEntriesWithTypeIn(const std::set<ModelType>& types) { | 822 void Directory::PurgeEntriesWithTypeIn(ModelEnumSet types) { |
823 if (types.count(UNSPECIFIED) != 0U || types.count(TOP_LEVEL_FOLDER) != 0U) { | 823 if (types.Empty()) |
824 NOTREACHED() << "Don't support purging unspecified or top level entries."; | |
825 return; | |
826 } | |
827 | |
828 if (types.empty()) | |
829 return; | 824 return; |
830 | 825 |
831 { | 826 { |
832 WriteTransaction trans(FROM_HERE, PURGE_ENTRIES, this); | 827 WriteTransaction trans(FROM_HERE, PURGE_ENTRIES, this); |
833 { | 828 { |
834 ScopedKernelLock lock(this); | 829 ScopedKernelLock lock(this); |
835 MetahandlesIndex::iterator it = kernel_->metahandles_index->begin(); | 830 MetahandlesIndex::iterator it = kernel_->metahandles_index->begin(); |
836 while (it != kernel_->metahandles_index->end()) { | 831 while (it != kernel_->metahandles_index->end()) { |
837 const sync_pb::EntitySpecifics& local_specifics = (*it)->ref(SPECIFICS); | 832 const sync_pb::EntitySpecifics& local_specifics = (*it)->ref(SPECIFICS); |
838 const sync_pb::EntitySpecifics& server_specifics = | 833 const sync_pb::EntitySpecifics& server_specifics = |
839 (*it)->ref(SERVER_SPECIFICS); | 834 (*it)->ref(SERVER_SPECIFICS); |
840 ModelType local_type = GetModelTypeFromSpecifics(local_specifics); | 835 ModelType local_type = GetModelTypeFromSpecifics(local_specifics); |
841 ModelType server_type = GetModelTypeFromSpecifics(server_specifics); | 836 ModelType server_type = GetModelTypeFromSpecifics(server_specifics); |
842 | 837 |
843 // Note the dance around incrementing |it|, since we sometimes erase(). | 838 // Note the dance around incrementing |it|, since we sometimes erase(). |
844 if (types.count(local_type) > 0 || types.count(server_type) > 0) { | 839 if ((IsRealDataType(local_type) && types.Has(local_type)) || |
| 840 (IsRealDataType(server_type) && types.Has(server_type))) { |
845 UnlinkEntryFromOrder(*it, NULL, &lock); | 841 UnlinkEntryFromOrder(*it, NULL, &lock); |
846 int64 handle = (*it)->ref(META_HANDLE); | 842 int64 handle = (*it)->ref(META_HANDLE); |
847 kernel_->metahandles_to_purge->insert(handle); | 843 kernel_->metahandles_to_purge->insert(handle); |
848 | 844 |
849 size_t num_erased = 0; | 845 size_t num_erased = 0; |
850 EntryKernel* entry = *it; | 846 EntryKernel* entry = *it; |
851 num_erased = kernel_->ids_index->erase(entry); | 847 num_erased = kernel_->ids_index->erase(entry); |
852 DCHECK_EQ(1u, num_erased); | 848 DCHECK_EQ(1u, num_erased); |
853 num_erased = kernel_->client_tag_index->erase(entry); | 849 num_erased = kernel_->client_tag_index->erase(entry); |
854 DCHECK_EQ(entry->ref(UNIQUE_CLIENT_TAG).empty(), !num_erased); | 850 DCHECK_EQ(entry->ref(UNIQUE_CLIENT_TAG).empty(), !num_erased); |
855 num_erased = kernel_->unsynced_metahandles->erase(handle); | 851 num_erased = kernel_->unsynced_metahandles->erase(handle); |
856 DCHECK_EQ(entry->ref(IS_UNSYNCED), num_erased > 0); | 852 DCHECK_EQ(entry->ref(IS_UNSYNCED), num_erased > 0); |
857 num_erased = | 853 num_erased = |
858 kernel_->unapplied_update_metahandles[server_type].erase(handle); | 854 kernel_->unapplied_update_metahandles[server_type].erase(handle); |
859 DCHECK_EQ(entry->ref(IS_UNAPPLIED_UPDATE), num_erased > 0); | 855 DCHECK_EQ(entry->ref(IS_UNAPPLIED_UPDATE), num_erased > 0); |
860 num_erased = kernel_->parent_id_child_index->erase(entry); | 856 num_erased = kernel_->parent_id_child_index->erase(entry); |
861 DCHECK_EQ(entry->ref(IS_DEL), !num_erased); | 857 DCHECK_EQ(entry->ref(IS_DEL), !num_erased); |
862 kernel_->metahandles_index->erase(it++); | 858 kernel_->metahandles_index->erase(it++); |
863 delete entry; | 859 delete entry; |
864 } else { | 860 } else { |
865 ++it; | 861 ++it; |
866 } | 862 } |
867 } | 863 } |
868 | 864 |
869 // Ensure meta tracking for these data types reflects the deleted state. | 865 // Ensure meta tracking for these data types reflects the deleted state. |
870 for (std::set<ModelType>::const_iterator it = types.begin(); | 866 for (syncable::ModelEnumSet::Iterator it = types.First(); |
871 it != types.end(); ++it) { | 867 it.Good(); it.Inc()) { |
872 set_initial_sync_ended_for_type_unsafe(*it, false); | 868 set_initial_sync_ended_for_type_unsafe(it.Get(), false); |
873 kernel_->persisted_info.reset_download_progress(*it); | 869 kernel_->persisted_info.reset_download_progress(it.Get()); |
874 } | 870 } |
875 } | 871 } |
876 } | 872 } |
877 } | 873 } |
878 | 874 |
879 void Directory::HandleSaveChangesFailure(const SaveChangesSnapshot& snapshot) { | 875 void Directory::HandleSaveChangesFailure(const SaveChangesSnapshot& snapshot) { |
880 ScopedKernelLock lock(this); | 876 ScopedKernelLock lock(this); |
881 kernel_->info_status = KERNEL_SHARE_INFO_DIRTY; | 877 kernel_->info_status = KERNEL_SHARE_INFO_DIRTY; |
882 | 878 |
883 // Because we optimistically cleared the dirty bit on the real entries when | 879 // Because we optimistically cleared the dirty bit on the real entries when |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
923 void Directory::SetDownloadProgress( | 919 void Directory::SetDownloadProgress( |
924 ModelType model_type, | 920 ModelType model_type, |
925 const sync_pb::DataTypeProgressMarker& new_progress) { | 921 const sync_pb::DataTypeProgressMarker& new_progress) { |
926 ScopedKernelLock lock(this); | 922 ScopedKernelLock lock(this); |
927 kernel_->persisted_info.download_progress[model_type].CopyFrom(new_progress); | 923 kernel_->persisted_info.download_progress[model_type].CopyFrom(new_progress); |
928 kernel_->info_status = KERNEL_SHARE_INFO_DIRTY; | 924 kernel_->info_status = KERNEL_SHARE_INFO_DIRTY; |
929 } | 925 } |
930 | 926 |
931 bool Directory::initial_sync_ended_for_type(ModelType type) const { | 927 bool Directory::initial_sync_ended_for_type(ModelType type) const { |
932 ScopedKernelLock lock(this); | 928 ScopedKernelLock lock(this); |
933 return kernel_->persisted_info.initial_sync_ended[type]; | 929 return kernel_->persisted_info.initial_sync_ended.Has(type); |
934 } | 930 } |
935 | 931 |
936 template <class T> void Directory::TestAndSet( | 932 template <class T> void Directory::TestAndSet( |
937 T* kernel_data, const T* data_to_set) { | 933 T* kernel_data, const T* data_to_set) { |
938 if (*kernel_data != *data_to_set) { | 934 if (*kernel_data != *data_to_set) { |
939 *kernel_data = *data_to_set; | 935 *kernel_data = *data_to_set; |
940 kernel_->info_status = KERNEL_SHARE_INFO_DIRTY; | 936 kernel_->info_status = KERNEL_SHARE_INFO_DIRTY; |
941 } | 937 } |
942 } | 938 } |
943 | 939 |
944 void Directory::set_initial_sync_ended_for_type(ModelType type, bool x) { | 940 void Directory::set_initial_sync_ended_for_type(ModelType type, bool x) { |
945 ScopedKernelLock lock(this); | 941 ScopedKernelLock lock(this); |
946 set_initial_sync_ended_for_type_unsafe(type, x); | 942 set_initial_sync_ended_for_type_unsafe(type, x); |
947 } | 943 } |
948 | 944 |
949 void Directory::set_initial_sync_ended_for_type_unsafe(ModelType type, | 945 void Directory::set_initial_sync_ended_for_type_unsafe(ModelType type, |
950 bool x) { | 946 bool x) { |
951 if (kernel_->persisted_info.initial_sync_ended[type] == x) | 947 if (kernel_->persisted_info.initial_sync_ended.Has(type) == x) |
952 return; | 948 return; |
953 kernel_->persisted_info.initial_sync_ended.set(type, x); | 949 if (x) { |
| 950 kernel_->persisted_info.initial_sync_ended.Put(type); |
| 951 } else { |
| 952 kernel_->persisted_info.initial_sync_ended.Remove(type); |
| 953 } |
954 kernel_->info_status = KERNEL_SHARE_INFO_DIRTY; | 954 kernel_->info_status = KERNEL_SHARE_INFO_DIRTY; |
955 } | 955 } |
956 | 956 |
957 void Directory::SetNotificationStateUnsafe( | 957 void Directory::SetNotificationStateUnsafe( |
958 const std::string& notification_state) { | 958 const std::string& notification_state) { |
959 if (notification_state == kernel_->persisted_info.notification_state) | 959 if (notification_state == kernel_->persisted_info.notification_state) |
960 return; | 960 return; |
961 kernel_->persisted_info.notification_state = notification_state; | 961 kernel_->persisted_info.notification_state = notification_state; |
962 kernel_->info_status = KERNEL_SHARE_INFO_DIRTY; | 962 kernel_->info_status = KERNEL_SHARE_INFO_DIRTY; |
963 } | 963 } |
(...skipping 337 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1301 // Not actually mutated, so erase from |mutations_|. | 1301 // Not actually mutated, so erase from |mutations_|. |
1302 mutations_.erase(it++); | 1302 mutations_.erase(it++); |
1303 } | 1303 } |
1304 } | 1304 } |
1305 return ImmutableEntryKernelMutationMap(&mutations_); | 1305 return ImmutableEntryKernelMutationMap(&mutations_); |
1306 } | 1306 } |
1307 | 1307 |
1308 void WriteTransaction::UnlockAndNotify( | 1308 void WriteTransaction::UnlockAndNotify( |
1309 const ImmutableEntryKernelMutationMap& mutations) { | 1309 const ImmutableEntryKernelMutationMap& mutations) { |
1310 // Work while transaction mutex is held. | 1310 // Work while transaction mutex is held. |
1311 ModelTypeBitSet models_with_changes; | 1311 ModelEnumSet models_with_changes; |
1312 bool has_mutations = !mutations.Get().empty(); | 1312 bool has_mutations = !mutations.Get().empty(); |
1313 if (has_mutations) { | 1313 if (has_mutations) { |
1314 models_with_changes = NotifyTransactionChangingAndEnding(mutations); | 1314 models_with_changes = NotifyTransactionChangingAndEnding(mutations); |
1315 } | 1315 } |
1316 Unlock(); | 1316 Unlock(); |
1317 | 1317 |
1318 // Work after mutex is relased. | 1318 // Work after mutex is relased. |
1319 if (has_mutations) { | 1319 if (has_mutations) { |
1320 NotifyTransactionComplete(models_with_changes); | 1320 NotifyTransactionComplete(models_with_changes); |
1321 } | 1321 } |
1322 } | 1322 } |
1323 | 1323 |
1324 ModelTypeBitSet WriteTransaction::NotifyTransactionChangingAndEnding( | 1324 ModelEnumSet WriteTransaction::NotifyTransactionChangingAndEnding( |
1325 const ImmutableEntryKernelMutationMap& mutations) { | 1325 const ImmutableEntryKernelMutationMap& mutations) { |
1326 dirkernel_->transaction_mutex.AssertAcquired(); | 1326 dirkernel_->transaction_mutex.AssertAcquired(); |
1327 DCHECK(!mutations.Get().empty()); | 1327 DCHECK(!mutations.Get().empty()); |
1328 | 1328 |
1329 WriteTransactionInfo write_transaction_info( | 1329 WriteTransactionInfo write_transaction_info( |
1330 dirkernel_->next_write_transaction_id, from_here_, writer_, mutations); | 1330 dirkernel_->next_write_transaction_id, from_here_, writer_, mutations); |
1331 ++dirkernel_->next_write_transaction_id; | 1331 ++dirkernel_->next_write_transaction_id; |
1332 | 1332 |
1333 ImmutableWriteTransactionInfo immutable_write_transaction_info( | 1333 ImmutableWriteTransactionInfo immutable_write_transaction_info( |
1334 &write_transaction_info); | 1334 &write_transaction_info); |
1335 DirectoryChangeDelegate* const delegate = dirkernel_->delegate; | 1335 DirectoryChangeDelegate* const delegate = dirkernel_->delegate; |
1336 if (writer_ == syncable::SYNCAPI) { | 1336 if (writer_ == syncable::SYNCAPI) { |
1337 delegate->HandleCalculateChangesChangeEventFromSyncApi( | 1337 delegate->HandleCalculateChangesChangeEventFromSyncApi( |
1338 immutable_write_transaction_info, this); | 1338 immutable_write_transaction_info, this); |
1339 } else { | 1339 } else { |
1340 delegate->HandleCalculateChangesChangeEventFromSyncer( | 1340 delegate->HandleCalculateChangesChangeEventFromSyncer( |
1341 immutable_write_transaction_info, this); | 1341 immutable_write_transaction_info, this); |
1342 } | 1342 } |
1343 | 1343 |
1344 ModelTypeBitSet models_with_changes = | 1344 ModelEnumSet models_with_changes = |
1345 delegate->HandleTransactionEndingChangeEvent( | 1345 delegate->HandleTransactionEndingChangeEvent( |
1346 immutable_write_transaction_info, this); | 1346 immutable_write_transaction_info, this); |
1347 | 1347 |
1348 dirkernel_->transaction_observer.Call(FROM_HERE, | 1348 dirkernel_->transaction_observer.Call(FROM_HERE, |
1349 &TransactionObserver::OnTransactionWrite, | 1349 &TransactionObserver::OnTransactionWrite, |
1350 immutable_write_transaction_info, models_with_changes); | 1350 immutable_write_transaction_info, models_with_changes); |
1351 | 1351 |
1352 return models_with_changes; | 1352 return models_with_changes; |
1353 } | 1353 } |
1354 | 1354 |
1355 void WriteTransaction::NotifyTransactionComplete( | 1355 void WriteTransaction::NotifyTransactionComplete( |
1356 ModelTypeBitSet models_with_changes) { | 1356 ModelEnumSet models_with_changes) { |
1357 dirkernel_->delegate->HandleTransactionCompleteChangeEvent( | 1357 dirkernel_->delegate->HandleTransactionCompleteChangeEvent( |
1358 models_with_changes); | 1358 models_with_changes); |
1359 } | 1359 } |
1360 | 1360 |
1361 WriteTransaction::~WriteTransaction() { | 1361 WriteTransaction::~WriteTransaction() { |
1362 const ImmutableEntryKernelMutationMap& mutations = RecordMutations(); | 1362 const ImmutableEntryKernelMutationMap& mutations = RecordMutations(); |
1363 | 1363 |
1364 if (OFF != kInvariantCheckLevel) { | 1364 if (OFF != kInvariantCheckLevel) { |
1365 const bool full_scan = (FULL_DB_VERIFICATION == kInvariantCheckLevel); | 1365 const bool full_scan = (FULL_DB_VERIFICATION == kInvariantCheckLevel); |
1366 if (full_scan) | 1366 if (full_scan) |
(...skipping 745 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2112 if (entry->ref(NEXT_ID).IsRoot() || | 2112 if (entry->ref(NEXT_ID).IsRoot() || |
2113 entry->ref(NEXT_ID) != entry->ref(PREV_ID)) { | 2113 entry->ref(NEXT_ID) != entry->ref(PREV_ID)) { |
2114 return entry; | 2114 return entry; |
2115 } | 2115 } |
2116 } | 2116 } |
2117 // There were no children in the linked list. | 2117 // There were no children in the linked list. |
2118 return NULL; | 2118 return NULL; |
2119 } | 2119 } |
2120 | 2120 |
2121 } // namespace syncable | 2121 } // namespace syncable |
OLD | NEW |