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