| 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/model_neutral_mutable_entry.h" | 5 #include "components/sync/syncable/model_neutral_mutable_entry.h" |
| 6 | 6 |
| 7 #include <stddef.h> | 7 #include <stddef.h> |
| 8 #include <stdint.h> | 8 #include <stdint.h> |
| 9 | 9 |
| 10 #include <string> | 10 #include <string> |
| 11 | 11 |
| 12 #include "sync/internal_api/public/base/unique_position.h" | 12 #include "components/sync/base/unique_position.h" |
| 13 #include "sync/syncable/directory.h" | 13 #include "components/sync/syncable/directory.h" |
| 14 #include "sync/syncable/scoped_kernel_lock.h" | 14 #include "components/sync/syncable/scoped_kernel_lock.h" |
| 15 #include "sync/syncable/syncable_changes_version.h" | 15 #include "components/sync/syncable/syncable_changes_version.h" |
| 16 #include "sync/syncable/syncable_util.h" | 16 #include "components/sync/syncable/syncable_util.h" |
| 17 #include "sync/syncable/syncable_write_transaction.h" | 17 #include "components/sync/syncable/syncable_write_transaction.h" |
| 18 | 18 |
| 19 using std::string; | 19 using std::string; |
| 20 | 20 |
| 21 namespace syncer { | 21 namespace syncer { |
| 22 | 22 |
| 23 namespace syncable { | 23 namespace syncable { |
| 24 | 24 |
| 25 ModelNeutralMutableEntry::ModelNeutralMutableEntry(BaseWriteTransaction* trans, | 25 ModelNeutralMutableEntry::ModelNeutralMutableEntry(BaseWriteTransaction* trans, |
| 26 CreateNewUpdateItem, | 26 CreateNewUpdateItem, |
| 27 const Id& id) | 27 const Id& id) |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 79 | 79 |
| 80 if (!trans->directory()->InsertEntry(trans, kernel.get())) { | 80 if (!trans->directory()->InsertEntry(trans, kernel.get())) { |
| 81 return; // Failed inserting. | 81 return; // Failed inserting. |
| 82 } | 82 } |
| 83 | 83 |
| 84 trans->TrackChangesTo(kernel.get()); | 84 trans->TrackChangesTo(kernel.get()); |
| 85 | 85 |
| 86 kernel_ = kernel.release(); | 86 kernel_ = kernel.release(); |
| 87 } | 87 } |
| 88 | 88 |
| 89 ModelNeutralMutableEntry::ModelNeutralMutableEntry( | 89 ModelNeutralMutableEntry::ModelNeutralMutableEntry(BaseWriteTransaction* trans, |
| 90 BaseWriteTransaction* trans, GetById, const Id& id) | 90 GetById, |
| 91 : Entry(trans, GET_BY_ID, id), base_write_transaction_(trans) { | 91 const Id& id) |
| 92 } | 92 : Entry(trans, GET_BY_ID, id), base_write_transaction_(trans) {} |
| 93 | 93 |
| 94 ModelNeutralMutableEntry::ModelNeutralMutableEntry(BaseWriteTransaction* trans, | 94 ModelNeutralMutableEntry::ModelNeutralMutableEntry(BaseWriteTransaction* trans, |
| 95 GetByHandle, | 95 GetByHandle, |
| 96 int64_t metahandle) | 96 int64_t metahandle) |
| 97 : Entry(trans, GET_BY_HANDLE, metahandle), base_write_transaction_(trans) {} | 97 : Entry(trans, GET_BY_HANDLE, metahandle), base_write_transaction_(trans) {} |
| 98 | 98 |
| 99 ModelNeutralMutableEntry::ModelNeutralMutableEntry( | 99 ModelNeutralMutableEntry::ModelNeutralMutableEntry(BaseWriteTransaction* trans, |
| 100 BaseWriteTransaction* trans, GetByClientTag, const std::string& tag) | 100 GetByClientTag, |
| 101 : Entry(trans, GET_BY_CLIENT_TAG, tag), base_write_transaction_(trans) { | 101 const std::string& tag) |
| 102 } | 102 : Entry(trans, GET_BY_CLIENT_TAG, tag), base_write_transaction_(trans) {} |
| 103 | 103 |
| 104 ModelNeutralMutableEntry::ModelNeutralMutableEntry( | 104 ModelNeutralMutableEntry::ModelNeutralMutableEntry(BaseWriteTransaction* trans, |
| 105 BaseWriteTransaction* trans, GetTypeRoot, ModelType type) | 105 GetTypeRoot, |
| 106 : Entry(trans, GET_TYPE_ROOT, type), base_write_transaction_(trans) { | 106 ModelType type) |
| 107 } | 107 : Entry(trans, GET_TYPE_ROOT, type), base_write_transaction_(trans) {} |
| 108 | 108 |
| 109 void ModelNeutralMutableEntry::PutBaseVersion(int64_t value) { | 109 void ModelNeutralMutableEntry::PutBaseVersion(int64_t value) { |
| 110 DCHECK(kernel_); | 110 DCHECK(kernel_); |
| 111 if (kernel_->ref(BASE_VERSION) != value) { | 111 if (kernel_->ref(BASE_VERSION) != value) { |
| 112 base_write_transaction_->TrackChangesTo(kernel_); | 112 base_write_transaction_->TrackChangesTo(kernel_); |
| 113 kernel_->put(BASE_VERSION, value); | 113 kernel_->put(BASE_VERSION, value); |
| 114 MarkDirty(); | 114 MarkDirty(); |
| 115 } | 115 } |
| 116 } | 116 } |
| 117 | 117 |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 165 | 165 |
| 166 bool ModelNeutralMutableEntry::PutIsUnsynced(bool value) { | 166 bool ModelNeutralMutableEntry::PutIsUnsynced(bool value) { |
| 167 DCHECK(kernel_); | 167 DCHECK(kernel_); |
| 168 if (kernel_->ref(IS_UNSYNCED) != value) { | 168 if (kernel_->ref(IS_UNSYNCED) != value) { |
| 169 base_write_transaction_->TrackChangesTo(kernel_); | 169 base_write_transaction_->TrackChangesTo(kernel_); |
| 170 MetahandleSet* index = &dir()->kernel()->unsynced_metahandles; | 170 MetahandleSet* index = &dir()->kernel()->unsynced_metahandles; |
| 171 | 171 |
| 172 ScopedKernelLock lock(dir()); | 172 ScopedKernelLock lock(dir()); |
| 173 if (value) { | 173 if (value) { |
| 174 if (!SyncAssert(index->insert(kernel_->ref(META_HANDLE)).second, | 174 if (!SyncAssert(index->insert(kernel_->ref(META_HANDLE)).second, |
| 175 FROM_HERE, | 175 FROM_HERE, "Could not insert", |
| 176 "Could not insert", | |
| 177 base_write_transaction())) { | 176 base_write_transaction())) { |
| 178 return false; | 177 return false; |
| 179 } | 178 } |
| 180 } else { | 179 } else { |
| 181 if (!SyncAssert(1U == index->erase(kernel_->ref(META_HANDLE)), | 180 if (!SyncAssert(1U == index->erase(kernel_->ref(META_HANDLE)), FROM_HERE, |
| 182 FROM_HERE, | |
| 183 "Entry Not succesfully erased", | 181 "Entry Not succesfully erased", |
| 184 base_write_transaction())) { | 182 base_write_transaction())) { |
| 185 return false; | 183 return false; |
| 186 } | 184 } |
| 187 } | 185 } |
| 188 kernel_->put(IS_UNSYNCED, value); | 186 kernel_->put(IS_UNSYNCED, value); |
| 189 MarkDirty(); | 187 MarkDirty(); |
| 190 } | 188 } |
| 191 return true; | 189 return true; |
| 192 } | 190 } |
| 193 | 191 |
| 194 bool ModelNeutralMutableEntry::PutIsUnappliedUpdate(bool value) { | 192 bool ModelNeutralMutableEntry::PutIsUnappliedUpdate(bool value) { |
| 195 DCHECK(kernel_); | 193 DCHECK(kernel_); |
| 196 if (kernel_->ref(IS_UNAPPLIED_UPDATE) != value) { | 194 if (kernel_->ref(IS_UNAPPLIED_UPDATE) != value) { |
| 197 base_write_transaction_->TrackChangesTo(kernel_); | 195 base_write_transaction_->TrackChangesTo(kernel_); |
| 198 // Use kernel_->GetServerModelType() instead of | 196 // Use kernel_->GetServerModelType() instead of |
| 199 // GetServerModelType() as we may trigger some DCHECKs in the | 197 // GetServerModelType() as we may trigger some DCHECKs in the |
| 200 // latter. | 198 // latter. |
| 201 MetahandleSet* index = &dir()->kernel()->unapplied_update_metahandles[ | 199 MetahandleSet* index = |
| 202 kernel_->GetServerModelType()]; | 200 &dir() |
| 201 ->kernel() |
| 202 ->unapplied_update_metahandles[kernel_->GetServerModelType()]; |
| 203 | 203 |
| 204 ScopedKernelLock lock(dir()); | 204 ScopedKernelLock lock(dir()); |
| 205 if (value) { | 205 if (value) { |
| 206 if (!SyncAssert(index->insert(kernel_->ref(META_HANDLE)).second, | 206 if (!SyncAssert(index->insert(kernel_->ref(META_HANDLE)).second, |
| 207 FROM_HERE, | 207 FROM_HERE, "Could not insert", |
| 208 "Could not insert", | |
| 209 base_write_transaction())) { | 208 base_write_transaction())) { |
| 210 return false; | 209 return false; |
| 211 } | 210 } |
| 212 } else { | 211 } else { |
| 213 if (!SyncAssert(1U == index->erase(kernel_->ref(META_HANDLE)), | 212 if (!SyncAssert(1U == index->erase(kernel_->ref(META_HANDLE)), FROM_HERE, |
| 214 FROM_HERE, | |
| 215 "Entry Not succesfully erased", | 213 "Entry Not succesfully erased", |
| 216 base_write_transaction())) { | 214 base_write_transaction())) { |
| 217 return false; | 215 return false; |
| 218 } | 216 } |
| 219 } | 217 } |
| 220 kernel_->put(IS_UNAPPLIED_UPDATE, value); | 218 kernel_->put(IS_UNAPPLIED_UPDATE, value); |
| 221 MarkDirty(); | 219 MarkDirty(); |
| 222 } | 220 } |
| 223 return true; | 221 return true; |
| 224 } | 222 } |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 273 } | 271 } |
| 274 | 272 |
| 275 base_write_transaction_->TrackChangesTo(kernel_); | 273 base_write_transaction_->TrackChangesTo(kernel_); |
| 276 ScopedKernelLock lock(dir()); | 274 ScopedKernelLock lock(dir()); |
| 277 // Make sure your new value is not in there already. | 275 // Make sure your new value is not in there already. |
| 278 if (dir()->kernel()->server_tags_map.find(new_tag) != | 276 if (dir()->kernel()->server_tags_map.find(new_tag) != |
| 279 dir()->kernel()->server_tags_map.end()) { | 277 dir()->kernel()->server_tags_map.end()) { |
| 280 DVLOG(1) << "Detected duplicate server tag"; | 278 DVLOG(1) << "Detected duplicate server tag"; |
| 281 return false; | 279 return false; |
| 282 } | 280 } |
| 283 dir()->kernel()->server_tags_map.erase( | 281 dir()->kernel()->server_tags_map.erase(kernel_->ref(UNIQUE_SERVER_TAG)); |
| 284 kernel_->ref(UNIQUE_SERVER_TAG)); | |
| 285 kernel_->put(UNIQUE_SERVER_TAG, new_tag); | 282 kernel_->put(UNIQUE_SERVER_TAG, new_tag); |
| 286 MarkDirty(); | 283 MarkDirty(); |
| 287 if (!new_tag.empty()) { | 284 if (!new_tag.empty()) { |
| 288 dir()->kernel()->server_tags_map[new_tag] = kernel_; | 285 dir()->kernel()->server_tags_map[new_tag] = kernel_; |
| 289 } | 286 } |
| 290 | 287 |
| 291 return true; | 288 return true; |
| 292 } | 289 } |
| 293 | 290 |
| 294 bool ModelNeutralMutableEntry::PutUniqueClientTag(const string& new_tag) { | 291 bool ModelNeutralMutableEntry::PutUniqueClientTag(const string& new_tag) { |
| 295 if (new_tag == kernel_->ref(UNIQUE_CLIENT_TAG)) { | 292 if (new_tag == kernel_->ref(UNIQUE_CLIENT_TAG)) { |
| 296 return true; | 293 return true; |
| 297 } | 294 } |
| 298 | 295 |
| 299 base_write_transaction_->TrackChangesTo(kernel_); | 296 base_write_transaction_->TrackChangesTo(kernel_); |
| 300 ScopedKernelLock lock(dir()); | 297 ScopedKernelLock lock(dir()); |
| 301 // Make sure your new value is not in there already. | 298 // Make sure your new value is not in there already. |
| 302 if (dir()->kernel()->client_tags_map.find(new_tag) != | 299 if (dir()->kernel()->client_tags_map.find(new_tag) != |
| 303 dir()->kernel()->client_tags_map.end()) { | 300 dir()->kernel()->client_tags_map.end()) { |
| 304 DVLOG(1) << "Detected duplicate client tag"; | 301 DVLOG(1) << "Detected duplicate client tag"; |
| 305 return false; | 302 return false; |
| 306 } | 303 } |
| 307 dir()->kernel()->client_tags_map.erase( | 304 dir()->kernel()->client_tags_map.erase(kernel_->ref(UNIQUE_CLIENT_TAG)); |
| 308 kernel_->ref(UNIQUE_CLIENT_TAG)); | |
| 309 kernel_->put(UNIQUE_CLIENT_TAG, new_tag); | 305 kernel_->put(UNIQUE_CLIENT_TAG, new_tag); |
| 310 MarkDirty(); | 306 MarkDirty(); |
| 311 if (!new_tag.empty()) { | 307 if (!new_tag.empty()) { |
| 312 dir()->kernel()->client_tags_map[new_tag] = kernel_; | 308 dir()->kernel()->client_tags_map[new_tag] = kernel_; |
| 313 } | 309 } |
| 314 | 310 |
| 315 return true; | 311 return true; |
| 316 } | 312 } |
| 317 | 313 |
| 318 void ModelNeutralMutableEntry::PutUniqueBookmarkTag(const std::string& tag) { | 314 void ModelNeutralMutableEntry::PutUniqueBookmarkTag(const std::string& tag) { |
| 319 // This unique tag will eventually be used as the unique suffix when adjusting | 315 // This unique tag will eventually be used as the unique suffix when adjusting |
| 320 // this bookmark's position. Let's make sure it's a valid suffix. | 316 // this bookmark's position. Let's make sure it's a valid suffix. |
| 321 if (!UniquePosition::IsValidSuffix(tag)) { | 317 if (!UniquePosition::IsValidSuffix(tag)) { |
| 322 NOTREACHED(); | 318 NOTREACHED(); |
| 323 return; | 319 return; |
| 324 } | 320 } |
| 325 | 321 |
| 326 // TODO(stanisc): Does this need a call to TrackChangesTo? | 322 // TODO(stanisc): Does this need a call to TrackChangesTo? |
| 327 | 323 |
| 328 if (!kernel_->ref(UNIQUE_BOOKMARK_TAG).empty() && | 324 if (!kernel_->ref(UNIQUE_BOOKMARK_TAG).empty() && |
| 329 tag != kernel_->ref(UNIQUE_BOOKMARK_TAG)) { | 325 tag != kernel_->ref(UNIQUE_BOOKMARK_TAG)) { |
| 330 // There is only one scenario where our tag is expected to change. That | 326 // There is only one scenario where our tag is expected to change. That |
| 331 // scenario occurs when our current tag is a non-correct tag assigned during | 327 // scenario occurs when our current tag is a non-correct tag assigned during |
| 332 // the UniquePosition migration. | 328 // the UniquePosition migration. |
| 333 std::string migration_generated_tag = | 329 std::string migration_generated_tag = GenerateSyncableBookmarkHash( |
| 334 GenerateSyncableBookmarkHash(std::string(), | 330 std::string(), kernel_->ref(ID).GetServerId()); |
| 335 kernel_->ref(ID).GetServerId()); | |
| 336 DCHECK_EQ(migration_generated_tag, kernel_->ref(UNIQUE_BOOKMARK_TAG)); | 331 DCHECK_EQ(migration_generated_tag, kernel_->ref(UNIQUE_BOOKMARK_TAG)); |
| 337 } | 332 } |
| 338 | 333 |
| 339 kernel_->put(UNIQUE_BOOKMARK_TAG, tag); | 334 kernel_->put(UNIQUE_BOOKMARK_TAG, tag); |
| 340 MarkDirty(); | 335 MarkDirty(); |
| 341 } | 336 } |
| 342 | 337 |
| 343 void ModelNeutralMutableEntry::PutServerSpecifics( | 338 void ModelNeutralMutableEntry::PutServerSpecifics( |
| 344 const sync_pb::EntitySpecifics& value) { | 339 const sync_pb::EntitySpecifics& value) { |
| 345 DCHECK(kernel_); | 340 DCHECK(kernel_); |
| 346 CHECK(!value.password().has_client_only_encrypted_data()); | 341 CHECK(!value.password().has_client_only_encrypted_data()); |
| 347 // TODO(ncarter): This is unfortunately heavyweight. Can we do | 342 // TODO(ncarter): This is unfortunately heavyweight. Can we do |
| 348 // better? | 343 // better? |
| 349 const std::string& serialized_value = value.SerializeAsString(); | 344 const std::string& serialized_value = value.SerializeAsString(); |
| 350 if (serialized_value != kernel_->ref(SERVER_SPECIFICS).SerializeAsString()) { | 345 if (serialized_value != kernel_->ref(SERVER_SPECIFICS).SerializeAsString()) { |
| 351 base_write_transaction_->TrackChangesTo(kernel_); | 346 base_write_transaction_->TrackChangesTo(kernel_); |
| 352 if (kernel_->ref(IS_UNAPPLIED_UPDATE)) { | 347 if (kernel_->ref(IS_UNAPPLIED_UPDATE)) { |
| 353 // Remove ourselves from unapplied_update_metahandles with our | 348 // Remove ourselves from unapplied_update_metahandles with our |
| 354 // old server type. | 349 // old server type. |
| 355 const ModelType old_server_type = kernel_->GetServerModelType(); | 350 const ModelType old_server_type = kernel_->GetServerModelType(); |
| 356 const int64_t metahandle = kernel_->ref(META_HANDLE); | 351 const int64_t metahandle = kernel_->ref(META_HANDLE); |
| 357 size_t erase_count = | 352 size_t erase_count = |
| 358 dir()->kernel()->unapplied_update_metahandles[old_server_type] | 353 dir()->kernel()->unapplied_update_metahandles[old_server_type].erase( |
| 359 .erase(metahandle); | 354 metahandle); |
| 360 DCHECK_EQ(erase_count, 1u); | 355 DCHECK_EQ(erase_count, 1u); |
| 361 } | 356 } |
| 362 | 357 |
| 363 // Check for potential sharing - SERVER_SPECIFICS is often | 358 // Check for potential sharing - SERVER_SPECIFICS is often |
| 364 // copied from SPECIFICS. | 359 // copied from SPECIFICS. |
| 365 if (serialized_value == kernel_->ref(SPECIFICS).SerializeAsString()) { | 360 if (serialized_value == kernel_->ref(SPECIFICS).SerializeAsString()) { |
| 366 kernel_->copy(SPECIFICS, SERVER_SPECIFICS); | 361 kernel_->copy(SPECIFICS, SERVER_SPECIFICS); |
| 367 } else { | 362 } else { |
| 368 kernel_->put(SERVER_SPECIFICS, value); | 363 kernel_->put(SERVER_SPECIFICS, value); |
| 369 } | 364 } |
| 370 MarkDirty(); | 365 MarkDirty(); |
| 371 | 366 |
| 372 if (kernel_->ref(IS_UNAPPLIED_UPDATE)) { | 367 if (kernel_->ref(IS_UNAPPLIED_UPDATE)) { |
| 373 // Add ourselves back into unapplied_update_metahandles with our | 368 // Add ourselves back into unapplied_update_metahandles with our |
| 374 // new server type. | 369 // new server type. |
| 375 const ModelType new_server_type = kernel_->GetServerModelType(); | 370 const ModelType new_server_type = kernel_->GetServerModelType(); |
| 376 const int64_t metahandle = kernel_->ref(META_HANDLE); | 371 const int64_t metahandle = kernel_->ref(META_HANDLE); |
| 377 dir()->kernel()->unapplied_update_metahandles[new_server_type] | 372 dir()->kernel()->unapplied_update_metahandles[new_server_type].insert( |
| 378 .insert(metahandle); | 373 metahandle); |
| 379 } | 374 } |
| 380 } | 375 } |
| 381 } | 376 } |
| 382 | 377 |
| 383 void ModelNeutralMutableEntry::PutBaseServerSpecifics( | 378 void ModelNeutralMutableEntry::PutBaseServerSpecifics( |
| 384 const sync_pb::EntitySpecifics& value) { | 379 const sync_pb::EntitySpecifics& value) { |
| 385 DCHECK(kernel_); | 380 DCHECK(kernel_); |
| 386 CHECK(!value.password().has_client_only_encrypted_data()); | 381 CHECK(!value.password().has_client_only_encrypted_data()); |
| 387 // TODO(ncarter): This is unfortunately heavyweight. Can we do | 382 // TODO(ncarter): This is unfortunately heavyweight. Can we do |
| 388 // better? | 383 // better? |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 448 dir()->ReindexParentId(base_write_transaction(), kernel_, parent_id); | 443 dir()->ReindexParentId(base_write_transaction(), kernel_, parent_id); |
| 449 MarkDirty(); | 444 MarkDirty(); |
| 450 } | 445 } |
| 451 | 446 |
| 452 void ModelNeutralMutableEntry::UpdateTransactionVersion(int64_t value) { | 447 void ModelNeutralMutableEntry::UpdateTransactionVersion(int64_t value) { |
| 453 kernel_->put(TRANSACTION_VERSION, value); | 448 kernel_->put(TRANSACTION_VERSION, value); |
| 454 MarkDirty(); | 449 MarkDirty(); |
| 455 } | 450 } |
| 456 | 451 |
| 457 ModelNeutralMutableEntry::ModelNeutralMutableEntry(BaseWriteTransaction* trans) | 452 ModelNeutralMutableEntry::ModelNeutralMutableEntry(BaseWriteTransaction* trans) |
| 458 : Entry(trans), base_write_transaction_(trans) {} | 453 : Entry(trans), base_write_transaction_(trans) {} |
| 459 | 454 |
| 460 void ModelNeutralMutableEntry::MarkDirty() { | 455 void ModelNeutralMutableEntry::MarkDirty() { |
| 461 kernel_->mark_dirty(&dir()->kernel()->dirty_metahandles); | 456 kernel_->mark_dirty(&dir()->kernel()->dirty_metahandles); |
| 462 } | 457 } |
| 463 | 458 |
| 464 } // namespace syncable | 459 } // namespace syncable |
| 465 | 460 |
| 466 } // namespace syncer | 461 } // namespace syncer |
| OLD | NEW |