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 "sync/syncable/directory.h" | 5 #include "sync/syncable/directory.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <iterator> | 8 #include <iterator> |
| 9 | 9 |
| 10 #include "base/base64.h" | 10 #include "base/base64.h" |
| (...skipping 730 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 741 | 741 |
| 742 EntryKernelSet entries_to_journal; | 742 EntryKernelSet entries_to_journal; |
| 743 STLElementDeleter<EntryKernelSet> journal_deleter(&entries_to_journal); | 743 STLElementDeleter<EntryKernelSet> journal_deleter(&entries_to_journal); |
| 744 | 744 |
| 745 { | 745 { |
| 746 ScopedKernelLock lock(this); | 746 ScopedKernelLock lock(this); |
| 747 | 747 |
| 748 bool found_progress = false; | 748 bool found_progress = false; |
| 749 for (ModelTypeSet::Iterator iter = disabled_types.First(); iter.Good(); | 749 for (ModelTypeSet::Iterator iter = disabled_types.First(); iter.Good(); |
| 750 iter.Inc()) { | 750 iter.Inc()) { |
| 751 if (!kernel_->persisted_info.HasEmptyDownloadProgress(iter.Get())) | 751 if (!HasEmptyDownloadProgress(iter.Get())) |
| 752 found_progress = true; | 752 found_progress = true; |
| 753 } | 753 } |
| 754 | 754 |
| 755 // If none of the disabled types have progress markers, there's nothing to | 755 // If none of the disabled types have progress markers, there's nothing to |
| 756 // purge. | 756 // purge. |
| 757 if (!found_progress) | 757 if (!found_progress) |
| 758 return true; | 758 return true; |
| 759 | 759 |
| 760 // We iterate in two passes to avoid a bug in STLport (which is used in | 760 // We iterate in two passes to avoid a bug in STLport (which is used in |
| 761 // the Android build). There are some versions of that library where a | 761 // the Android build). There are some versions of that library where a |
| (...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 918 } | 918 } |
| 919 | 919 |
| 920 void Directory::SetDownloadProgress( | 920 void Directory::SetDownloadProgress( |
| 921 ModelType model_type, | 921 ModelType model_type, |
| 922 const sync_pb::DataTypeProgressMarker& new_progress) { | 922 const sync_pb::DataTypeProgressMarker& new_progress) { |
| 923 ScopedKernelLock lock(this); | 923 ScopedKernelLock lock(this); |
| 924 kernel_->persisted_info.download_progress[model_type].CopyFrom(new_progress); | 924 kernel_->persisted_info.download_progress[model_type].CopyFrom(new_progress); |
| 925 kernel_->info_status = KERNEL_SHARE_INFO_DIRTY; | 925 kernel_->info_status = KERNEL_SHARE_INFO_DIRTY; |
| 926 } | 926 } |
| 927 | 927 |
| 928 bool Directory::HasEmptyDownloadProgress(ModelType type) const { | |
| 929 return kernel_->persisted_info.HasEmptyDownloadProgress(type); | |
|
maniscalco
2015/01/24 00:55:59
Normally, when Directory methods access kernel_ th
stanisc
2015/01/26 19:02:09
Done.
maniscalco
2015/01/26 19:17:34
Since Directory::HasEmptyDownloadProgress is calle
stanisc
2015/01/29 00:27:37
Directory::HasEmptyDownloadProgress isn't called f
maniscalco
2015/01/29 00:36:34
Ah, you're right. I misread which HasEmptyDownloa
| |
| 930 } | |
| 931 | |
| 928 int64 Directory::GetTransactionVersion(ModelType type) const { | 932 int64 Directory::GetTransactionVersion(ModelType type) const { |
| 929 kernel_->transaction_mutex.AssertAcquired(); | 933 kernel_->transaction_mutex.AssertAcquired(); |
| 930 return kernel_->persisted_info.transaction_version[type]; | 934 return kernel_->persisted_info.transaction_version[type]; |
| 931 } | 935 } |
| 932 | 936 |
| 933 void Directory::IncrementTransactionVersion(ModelType type) { | 937 void Directory::IncrementTransactionVersion(ModelType type) { |
| 934 kernel_->transaction_mutex.AssertAcquired(); | 938 kernel_->transaction_mutex.AssertAcquired(); |
| 935 kernel_->persisted_info.transaction_version[type]++; | 939 kernel_->persisted_info.transaction_version[type]++; |
| 936 } | 940 } |
| 937 | 941 |
| 938 void Directory::GetDataTypeContext(BaseTransaction* trans, | 942 void Directory::GetDataTypeContext(BaseTransaction* trans, |
| 939 ModelType type, | 943 ModelType type, |
| 940 sync_pb::DataTypeContext* context) const { | 944 sync_pb::DataTypeContext* context) const { |
| 941 ScopedKernelLock lock(this); | 945 ScopedKernelLock lock(this); |
| 942 context->CopyFrom(kernel_->persisted_info.datatype_context[type]); | 946 context->CopyFrom(kernel_->persisted_info.datatype_context[type]); |
| 943 } | 947 } |
| 944 | 948 |
| 945 void Directory::SetDataTypeContext( | 949 void Directory::SetDataTypeContext( |
| 946 BaseWriteTransaction* trans, | 950 BaseWriteTransaction* trans, |
| 947 ModelType type, | 951 ModelType type, |
| 948 const sync_pb::DataTypeContext& context) { | 952 const sync_pb::DataTypeContext& context) { |
| 949 ScopedKernelLock lock(this); | 953 ScopedKernelLock lock(this); |
| 950 kernel_->persisted_info.datatype_context[type].CopyFrom(context); | 954 kernel_->persisted_info.datatype_context[type].CopyFrom(context); |
| 951 kernel_->info_status = KERNEL_SHARE_INFO_DIRTY; | 955 kernel_->info_status = KERNEL_SHARE_INFO_DIRTY; |
| 952 } | 956 } |
| 953 | 957 |
| 958 // TODO: change these to not rely on the folders | |
| 954 ModelTypeSet Directory::InitialSyncEndedTypes() { | 959 ModelTypeSet Directory::InitialSyncEndedTypes() { |
| 955 syncable::ReadTransaction trans(FROM_HERE, this); | 960 syncable::ReadTransaction trans(FROM_HERE, this); |
| 956 ModelTypeSet protocol_types = ProtocolTypes(); | 961 ModelTypeSet protocol_types = ProtocolTypes(); |
| 957 ModelTypeSet initial_sync_ended_types; | 962 ModelTypeSet initial_sync_ended_types; |
| 958 for (ModelTypeSet::Iterator i = protocol_types.First(); i.Good(); i.Inc()) { | 963 for (ModelTypeSet::Iterator i = protocol_types.First(); i.Good(); i.Inc()) { |
| 959 if (InitialSyncEndedForType(&trans, i.Get())) { | 964 if (InitialSyncEndedForType(&trans, i.Get())) { |
| 960 initial_sync_ended_types.Put(i.Get()); | 965 initial_sync_ended_types.Put(i.Get()); |
| 961 } | 966 } |
| 962 } | 967 } |
| 963 return initial_sync_ended_types; | 968 return initial_sync_ended_types; |
| (...skipping 204 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1168 | 1173 |
| 1169 if (id.IsRoot()) { | 1174 if (id.IsRoot()) { |
| 1170 if (!SyncAssert(e.GetIsDir(), FROM_HERE, | 1175 if (!SyncAssert(e.GetIsDir(), FROM_HERE, |
| 1171 "Entry should be a directory", | 1176 "Entry should be a directory", |
| 1172 trans)) | 1177 trans)) |
| 1173 return false; | 1178 return false; |
| 1174 if (!SyncAssert(parentid.IsRoot(), FROM_HERE, | 1179 if (!SyncAssert(parentid.IsRoot(), FROM_HERE, |
| 1175 "Entry should be root", | 1180 "Entry should be root", |
| 1176 trans)) | 1181 trans)) |
| 1177 return false; | 1182 return false; |
| 1178 if (!SyncAssert(!e.GetIsUnsynced(), FROM_HERE, | 1183 if (!SyncAssert(!e.GetIsUnsynced(), FROM_HERE, "Entry should be synced", |
| 1179 "Entry should be sycned", | |
| 1180 trans)) | 1184 trans)) |
| 1181 return false; | 1185 return false; |
| 1182 continue; | 1186 continue; |
| 1183 } | 1187 } |
| 1184 | 1188 |
| 1185 if (!e.GetIsDel()) { | 1189 if (!e.GetIsDel()) { |
| 1186 if (!SyncAssert(id != parentid, FROM_HERE, | 1190 if (!SyncAssert(id != parentid, FROM_HERE, |
| 1187 "Id should be different from parent id.", | 1191 "Id should be different from parent id.", |
| 1188 trans)) | 1192 trans)) |
| 1189 return false; | 1193 return false; |
| 1190 if (!SyncAssert(!e.GetNonUniqueName().empty(), FROM_HERE, | 1194 if (!SyncAssert(!e.GetNonUniqueName().empty(), FROM_HERE, |
| 1191 "Non unique name should not be empty.", | 1195 "Non unique name should not be empty.", |
| 1192 trans)) | 1196 trans)) |
| 1193 return false; | 1197 return false; |
| 1194 | 1198 |
| 1195 if (!parentid.IsNull()) { | 1199 if (!parentid.IsNull()) { |
| 1196 int safety_count = handles.size() + 1; | 1200 int safety_count = handles.size() + 1; |
| 1197 // TODO(stanisc): handle items with Null parentid | |
| 1198 while (!parentid.IsRoot()) { | 1201 while (!parentid.IsRoot()) { |
| 1199 Entry parent(trans, GET_BY_ID, parentid); | 1202 Entry parent(trans, GET_BY_ID, parentid); |
| 1200 if (!SyncAssert(parent.good(), FROM_HERE, | 1203 if (!SyncAssert(parent.good(), FROM_HERE, |
| 1201 "Parent entry is not valid.", trans)) | 1204 "Parent entry is not valid.", trans)) |
| 1202 return false; | 1205 return false; |
| 1203 if (handles.end() == handles.find(parent.GetMetahandle())) | 1206 if (handles.end() == handles.find(parent.GetMetahandle())) |
| 1204 break; // Skip further checking if parent was unmodified. | 1207 break; // Skip further checking if parent was unmodified. |
| 1205 if (!SyncAssert(parent.GetIsDir(), FROM_HERE, | 1208 if (!SyncAssert(parent.GetIsDir(), FROM_HERE, |
| 1206 "Parent should be a directory", trans)) | 1209 "Parent should be a directory", trans)) |
| 1207 return false; | 1210 return false; |
| 1208 if (!SyncAssert(!parent.GetIsDel(), FROM_HERE, | 1211 if (!SyncAssert(!parent.GetIsDel(), FROM_HERE, |
| 1209 "Parent should not have been marked for deletion.", | 1212 "Parent should not have been marked for deletion.", |
| 1210 trans)) | 1213 trans)) |
| 1211 return false; | 1214 return false; |
| 1212 if (!SyncAssert(handles.end() != handles.find(parent.GetMetahandle()), | 1215 if (!SyncAssert(handles.end() != handles.find(parent.GetMetahandle()), |
| 1213 FROM_HERE, "Parent should be in the index.", trans)) | 1216 FROM_HERE, "Parent should be in the index.", trans)) |
| 1214 return false; | 1217 return false; |
| 1215 parentid = parent.GetParentId(); | 1218 parentid = parent.GetParentId(); |
| 1216 if (!SyncAssert(--safety_count > 0, FROM_HERE, | 1219 if (!SyncAssert(--safety_count > 0, FROM_HERE, |
| 1217 "Count should be greater than zero.", trans)) | 1220 "Count should be greater than zero.", trans)) |
| 1218 return false; | 1221 return false; |
| 1219 } | 1222 } |
| 1220 } | 1223 } |
| 1221 } | 1224 } |
| 1222 int64 base_version = e.GetBaseVersion(); | 1225 int64 base_version = e.GetBaseVersion(); |
| 1223 int64 server_version = e.GetServerVersion(); | 1226 int64 server_version = e.GetServerVersion(); |
| 1224 bool using_unique_client_tag = !e.GetUniqueClientTag().empty(); | 1227 bool using_unique_client_tag = !e.GetUniqueClientTag().empty(); |
| 1228 bool is_type_root_folder = | |
| 1229 parentid.IsRoot() && | |
| 1230 e.GetUniqueServerTag() == ModelTypeToRootTag(e.GetModelType()); | |
| 1225 if (CHANGES_VERSION == base_version || 0 == base_version) { | 1231 if (CHANGES_VERSION == base_version || 0 == base_version) { |
| 1226 if (e.GetIsUnappliedUpdate()) { | 1232 if (e.GetIsUnappliedUpdate()) { |
| 1227 // Must be a new item, or a de-duplicated unique client tag | 1233 // Must be a new item, or a de-duplicated unique client tag |
| 1228 // that was created both locally and remotely. | 1234 // that was created both locally and remotely. |
| 1229 if (!using_unique_client_tag) { | 1235 if (!(using_unique_client_tag || is_type_root_folder)) { |
| 1230 if (!SyncAssert(e.GetIsDel(), FROM_HERE, | 1236 if (!SyncAssert(e.GetIsDel(), FROM_HERE, |
| 1231 "The entry should not have been deleted.", | 1237 "The entry should have been deleted.", |
| 1232 trans)) | 1238 trans)) |
| 1233 return false; | 1239 return false; |
| 1234 } | 1240 } |
| 1235 // It came from the server, so it must have a server ID. | 1241 // It came from the server, so it must have a server ID. |
| 1236 if (!SyncAssert(id.ServerKnows(), FROM_HERE, | 1242 if (!SyncAssert(id.ServerKnows(), FROM_HERE, |
| 1237 "The id should be from a server.", | 1243 "The id should be from a server.", |
| 1238 trans)) | 1244 trans)) |
| 1239 return false; | 1245 return false; |
| 1240 } else { | 1246 } else { |
| 1241 if (e.GetIsDir()) { | 1247 if (e.GetIsDir()) { |
| 1242 // TODO(chron): Implement this mode if clients ever need it. | 1248 // TODO(chron): Implement this mode if clients ever need it. |
| 1243 // For now, you can't combine a client tag and a directory. | 1249 // For now, you can't combine a client tag and a directory. |
| 1244 if (!SyncAssert(!using_unique_client_tag, FROM_HERE, | 1250 if (!SyncAssert(!using_unique_client_tag, FROM_HERE, |
| 1245 "Directory cannot have a client tag.", | 1251 "Directory cannot have a client tag.", |
| 1246 trans)) | 1252 trans)) |
| 1247 return false; | 1253 return false; |
| 1248 } | 1254 } |
| 1249 // Should be an uncomitted item, or a successfully deleted one. | 1255 if (is_type_root_folder) { |
| 1250 if (!e.GetIsDel()) { | 1256 // This must be a locally created type root folder |
| 1251 if (!SyncAssert(e.GetIsUnsynced(), FROM_HERE, | 1257 if (!SyncAssert( |
| 1252 "The item should be unsynced.", | 1258 !e.GetIsUnsynced(), FROM_HERE, |
| 1253 trans)) | 1259 "Locally created type root folders should not be unsynced.", |
| 1260 trans)) | |
| 1254 return false; | 1261 return false; |
| 1262 | |
| 1263 if (!SyncAssert( | |
| 1264 !e.GetIsDel(), FROM_HERE, | |
| 1265 "Locally created type root folders should not be deleted.", | |
| 1266 trans)) | |
| 1267 return false; | |
| 1268 } else { | |
| 1269 // Should be an uncomitted item, or a successfully deleted one. | |
| 1270 if (!e.GetIsDel()) { | |
| 1271 if (!SyncAssert(e.GetIsUnsynced(), FROM_HERE, | |
| 1272 "The item should be unsynced.", trans)) | |
| 1273 return false; | |
| 1274 } | |
| 1255 } | 1275 } |
| 1256 // If the next check failed, it would imply that an item exists | 1276 // If the next check failed, it would imply that an item exists |
| 1257 // on the server, isn't waiting for application locally, but either | 1277 // on the server, isn't waiting for application locally, but either |
| 1258 // is an unsynced create or a sucessful delete in the local copy. | 1278 // is an unsynced create or a sucessful delete in the local copy. |
| 1259 // Either way, that's a mismatch. | 1279 // Either way, that's a mismatch. |
| 1260 if (!SyncAssert(0 == server_version, FROM_HERE, | 1280 if (!SyncAssert(0 == server_version, FROM_HERE, |
| 1261 "Server version should be zero.", | 1281 "Server version should be zero.", |
| 1262 trans)) | 1282 trans)) |
| 1263 return false; | 1283 return false; |
| 1264 // Items that aren't using the unique client tag should have a zero | 1284 // Items that aren't using the unique client tag should have a zero |
| (...skipping 191 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1456 void Directory::AppendChildHandles(const ScopedKernelLock& lock, | 1476 void Directory::AppendChildHandles(const ScopedKernelLock& lock, |
| 1457 const Id& parent_id, | 1477 const Id& parent_id, |
| 1458 Directory::Metahandles* result) { | 1478 Directory::Metahandles* result) { |
| 1459 const OrderedChildSet* children = | 1479 const OrderedChildSet* children = |
| 1460 kernel_->parent_child_index.GetChildren(parent_id); | 1480 kernel_->parent_child_index.GetChildren(parent_id); |
| 1461 if (!children) | 1481 if (!children) |
| 1462 return; | 1482 return; |
| 1463 | 1483 |
| 1464 for (OrderedChildSet::const_iterator i = children->begin(); | 1484 for (OrderedChildSet::const_iterator i = children->begin(); |
| 1465 i != children->end(); ++i) { | 1485 i != children->end(); ++i) { |
| 1466 DCHECK_EQ(parent_id, (*i)->ref(PARENT_ID)); | |
| 1467 result->push_back((*i)->ref(META_HANDLE)); | 1486 result->push_back((*i)->ref(META_HANDLE)); |
| 1468 } | 1487 } |
| 1469 } | 1488 } |
| 1470 | 1489 |
| 1471 void Directory::UnmarkDirtyEntry(WriteTransaction* trans, Entry* entry) { | 1490 void Directory::UnmarkDirtyEntry(WriteTransaction* trans, Entry* entry) { |
| 1472 CHECK(trans); | 1491 CHECK(trans); |
| 1473 entry->kernel_->clear_dirty(&kernel_->dirty_metahandles); | 1492 entry->kernel_->clear_dirty(&kernel_->dirty_metahandles); |
| 1474 } | 1493 } |
| 1475 | 1494 |
| 1476 void Directory::GetAttachmentIdsToUpload(BaseTransaction* trans, | 1495 void Directory::GetAttachmentIdsToUpload(BaseTransaction* trans, |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1522 // TODO(maniscalco): Eliminate redundant metadata storage (bug 415203). | 1541 // TODO(maniscalco): Eliminate redundant metadata storage (bug 415203). |
| 1523 std::set_difference(not_on_server_id_set.begin(), | 1542 std::set_difference(not_on_server_id_set.begin(), |
| 1524 not_on_server_id_set.end(), | 1543 not_on_server_id_set.end(), |
| 1525 on_server_id_set.begin(), | 1544 on_server_id_set.begin(), |
| 1526 on_server_id_set.end(), | 1545 on_server_id_set.end(), |
| 1527 std::inserter(*id_set, id_set->end())); | 1546 std::inserter(*id_set, id_set->end())); |
| 1528 } | 1547 } |
| 1529 | 1548 |
| 1530 } // namespace syncable | 1549 } // namespace syncable |
| 1531 } // namespace syncer | 1550 } // namespace syncer |
| OLD | NEW |