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 240 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
251 | 251 |
252 EntryKernel::EntryKernel() : dirty_(false) { | 252 EntryKernel::EntryKernel() : dirty_(false) { |
253 // Everything else should already be default-initialized. | 253 // Everything else should already be default-initialized. |
254 for (int i = INT64_FIELDS_BEGIN; i < INT64_FIELDS_END; ++i) { | 254 for (int i = INT64_FIELDS_BEGIN; i < INT64_FIELDS_END; ++i) { |
255 int64_fields[i] = 0; | 255 int64_fields[i] = 0; |
256 } | 256 } |
257 } | 257 } |
258 | 258 |
259 EntryKernel::~EntryKernel() {} | 259 EntryKernel::~EntryKernel() {} |
260 | 260 |
| 261 syncable::ModelType EntryKernel::GetServerModelType() const { |
| 262 ModelType specifics_type = GetModelTypeFromSpecifics(ref(SERVER_SPECIFICS)); |
| 263 if (specifics_type != UNSPECIFIED) |
| 264 return specifics_type; |
| 265 if (ref(ID).IsRoot()) |
| 266 return TOP_LEVEL_FOLDER; |
| 267 // Loose check for server-created top-level folders that aren't |
| 268 // bound to a particular model type. |
| 269 if (!ref(UNIQUE_SERVER_TAG).empty() && ref(SERVER_IS_DIR)) |
| 270 return TOP_LEVEL_FOLDER; |
| 271 |
| 272 return UNSPECIFIED; |
| 273 } |
| 274 |
261 bool EntryKernel::ContainsString(const std::string& lowercase_query) const { | 275 bool EntryKernel::ContainsString(const std::string& lowercase_query) const { |
262 // TODO(lipalani) - figure out what to do if the node is encrypted. | 276 // TODO(lipalani) - figure out what to do if the node is encrypted. |
263 const sync_pb::EntitySpecifics& specifics = ref(SPECIFICS); | 277 const sync_pb::EntitySpecifics& specifics = ref(SPECIFICS); |
264 std::string temp; | 278 std::string temp; |
265 // The protobuf serialized string contains the original strings. So | 279 // The protobuf serialized string contains the original strings. So |
266 // we will just serialize it and search it. | 280 // we will just serialize it and search it. |
267 specifics.SerializeToString(&temp); | 281 specifics.SerializeToString(&temp); |
268 | 282 |
269 // Now convert to lower case. | 283 // Now convert to lower case. |
270 StringToLowerASCII(&temp); | 284 StringToLowerASCII(&temp); |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
321 | 335 |
322 StringValue* IdToValue(const Id& id) { | 336 StringValue* IdToValue(const Id& id) { |
323 return id.ToValue(); | 337 return id.ToValue(); |
324 } | 338 } |
325 | 339 |
326 } // namespace | 340 } // namespace |
327 | 341 |
328 DictionaryValue* EntryKernel::ToValue() const { | 342 DictionaryValue* EntryKernel::ToValue() const { |
329 DictionaryValue* kernel_info = new DictionaryValue(); | 343 DictionaryValue* kernel_info = new DictionaryValue(); |
330 kernel_info->SetBoolean("isDirty", is_dirty()); | 344 kernel_info->SetBoolean("isDirty", is_dirty()); |
| 345 kernel_info->Set("serverModelType", ModelTypeToValue(GetServerModelType())); |
331 | 346 |
332 // Int64 fields. | 347 // Int64 fields. |
333 SetFieldValues(*this, kernel_info, | 348 SetFieldValues(*this, kernel_info, |
334 &GetMetahandleFieldString, &Int64ToValue, | 349 &GetMetahandleFieldString, &Int64ToValue, |
335 INT64_FIELDS_BEGIN, META_HANDLE); | 350 INT64_FIELDS_BEGIN, META_HANDLE); |
336 SetFieldValues(*this, kernel_info, | 351 SetFieldValues(*this, kernel_info, |
337 &GetBaseVersionString, &Int64ToValue, | 352 &GetBaseVersionString, &Int64ToValue, |
338 META_HANDLE + 1, BASE_VERSION); | 353 META_HANDLE + 1, BASE_VERSION); |
339 SetFieldValues(*this, kernel_info, | 354 SetFieldValues(*this, kernel_info, |
340 &GetInt64FieldString, &Int64ToValue, | 355 &GetInt64FieldString, &Int64ToValue, |
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
426 const browser_sync::WeakHandle<TransactionObserver>& | 441 const browser_sync::WeakHandle<TransactionObserver>& |
427 transaction_observer) | 442 transaction_observer) |
428 : db_path(db_path), | 443 : db_path(db_path), |
429 refcount(1), | 444 refcount(1), |
430 next_write_transaction_id(0), | 445 next_write_transaction_id(0), |
431 name(name), | 446 name(name), |
432 metahandles_index(new Directory::MetahandlesIndex), | 447 metahandles_index(new Directory::MetahandlesIndex), |
433 ids_index(new Directory::IdsIndex), | 448 ids_index(new Directory::IdsIndex), |
434 parent_id_child_index(new Directory::ParentIdChildIndex), | 449 parent_id_child_index(new Directory::ParentIdChildIndex), |
435 client_tag_index(new Directory::ClientTagIndex), | 450 client_tag_index(new Directory::ClientTagIndex), |
436 unapplied_update_metahandles(new MetahandleSet), | |
437 unsynced_metahandles(new MetahandleSet), | 451 unsynced_metahandles(new MetahandleSet), |
438 dirty_metahandles(new MetahandleSet), | 452 dirty_metahandles(new MetahandleSet), |
439 metahandles_to_purge(new MetahandleSet), | 453 metahandles_to_purge(new MetahandleSet), |
440 info_status(Directory::KERNEL_SHARE_INFO_VALID), | 454 info_status(Directory::KERNEL_SHARE_INFO_VALID), |
441 persisted_info(info.kernel_info), | 455 persisted_info(info.kernel_info), |
442 cache_guid(info.cache_guid), | 456 cache_guid(info.cache_guid), |
443 next_metahandle(info.max_metahandle + 1), | 457 next_metahandle(info.max_metahandle + 1), |
444 delegate(delegate), | 458 delegate(delegate), |
445 transaction_observer(transaction_observer) { | 459 transaction_observer(transaction_observer) { |
446 DCHECK(delegate); | 460 DCHECK(delegate); |
447 DCHECK(transaction_observer.IsInitialized()); | 461 DCHECK(transaction_observer.IsInitialized()); |
448 } | 462 } |
449 | 463 |
450 void Directory::Kernel::AddRef() { | 464 void Directory::Kernel::AddRef() { |
451 base::subtle::NoBarrier_AtomicIncrement(&refcount, 1); | 465 base::subtle::NoBarrier_AtomicIncrement(&refcount, 1); |
452 } | 466 } |
453 | 467 |
454 void Directory::Kernel::Release() { | 468 void Directory::Kernel::Release() { |
455 if (!base::subtle::NoBarrier_AtomicIncrement(&refcount, -1)) | 469 if (!base::subtle::NoBarrier_AtomicIncrement(&refcount, -1)) |
456 delete this; | 470 delete this; |
457 } | 471 } |
458 | 472 |
459 Directory::Kernel::~Kernel() { | 473 Directory::Kernel::~Kernel() { |
460 CHECK_EQ(0, refcount); | 474 CHECK_EQ(0, refcount); |
461 delete unsynced_metahandles; | 475 delete unsynced_metahandles; |
462 delete unapplied_update_metahandles; | |
463 delete dirty_metahandles; | 476 delete dirty_metahandles; |
464 delete metahandles_to_purge; | 477 delete metahandles_to_purge; |
465 delete parent_id_child_index; | 478 delete parent_id_child_index; |
466 delete client_tag_index; | 479 delete client_tag_index; |
467 delete ids_index; | 480 delete ids_index; |
468 STLDeleteElements(metahandles_index); | 481 STLDeleteElements(metahandles_index); |
469 delete metahandles_index; | 482 delete metahandles_index; |
470 } | 483 } |
471 | 484 |
472 Directory::Directory() : kernel_(NULL), store_(NULL) { | 485 Directory::Directory() : kernel_(NULL), store_(NULL) { |
(...skipping 16 matching lines...) Expand all Loading... |
489 } | 502 } |
490 | 503 |
491 void Directory::InitializeIndices() { | 504 void Directory::InitializeIndices() { |
492 MetahandlesIndex::iterator it = kernel_->metahandles_index->begin(); | 505 MetahandlesIndex::iterator it = kernel_->metahandles_index->begin(); |
493 for (; it != kernel_->metahandles_index->end(); ++it) { | 506 for (; it != kernel_->metahandles_index->end(); ++it) { |
494 EntryKernel* entry = *it; | 507 EntryKernel* entry = *it; |
495 InitializeIndexEntry<ParentIdAndHandleIndexer>(entry, | 508 InitializeIndexEntry<ParentIdAndHandleIndexer>(entry, |
496 kernel_->parent_id_child_index); | 509 kernel_->parent_id_child_index); |
497 InitializeIndexEntry<IdIndexer>(entry, kernel_->ids_index); | 510 InitializeIndexEntry<IdIndexer>(entry, kernel_->ids_index); |
498 InitializeIndexEntry<ClientTagIndexer>(entry, kernel_->client_tag_index); | 511 InitializeIndexEntry<ClientTagIndexer>(entry, kernel_->client_tag_index); |
| 512 const int64 metahandle = entry->ref(META_HANDLE); |
499 if (entry->ref(IS_UNSYNCED)) | 513 if (entry->ref(IS_UNSYNCED)) |
500 kernel_->unsynced_metahandles->insert(entry->ref(META_HANDLE)); | 514 kernel_->unsynced_metahandles->insert(metahandle); |
501 if (entry->ref(IS_UNAPPLIED_UPDATE)) | 515 if (entry->ref(IS_UNAPPLIED_UPDATE)) { |
502 kernel_->unapplied_update_metahandles->insert(entry->ref(META_HANDLE)); | 516 const ModelType type = entry->GetServerModelType(); |
| 517 kernel_->unapplied_update_metahandles[type].insert(metahandle); |
| 518 } |
503 DCHECK(!entry->is_dirty()); | 519 DCHECK(!entry->is_dirty()); |
504 } | 520 } |
505 } | 521 } |
506 | 522 |
507 DirectoryBackingStore* Directory::CreateBackingStore( | 523 DirectoryBackingStore* Directory::CreateBackingStore( |
508 const string& dir_name, const FilePath& backing_filepath) { | 524 const string& dir_name, const FilePath& backing_filepath) { |
509 return new DirectoryBackingStore(dir_name, backing_filepath); | 525 return new DirectoryBackingStore(dir_name, backing_filepath); |
510 } | 526 } |
511 | 527 |
512 DirOpenResult Directory::OpenImpl( | 528 DirOpenResult Directory::OpenImpl( |
(...skipping 182 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
695 kernel_->transaction_mutex.AssertAcquired(); | 711 kernel_->transaction_mutex.AssertAcquired(); |
696 kernel_->dirty_metahandles->clear(); | 712 kernel_->dirty_metahandles->clear(); |
697 } | 713 } |
698 | 714 |
699 bool Directory::SafeToPurgeFromMemory(const EntryKernel* const entry) const { | 715 bool Directory::SafeToPurgeFromMemory(const EntryKernel* const entry) const { |
700 bool safe = entry->ref(IS_DEL) && !entry->is_dirty() && | 716 bool safe = entry->ref(IS_DEL) && !entry->is_dirty() && |
701 !entry->ref(SYNCING) && !entry->ref(IS_UNAPPLIED_UPDATE) && | 717 !entry->ref(SYNCING) && !entry->ref(IS_UNAPPLIED_UPDATE) && |
702 !entry->ref(IS_UNSYNCED); | 718 !entry->ref(IS_UNSYNCED); |
703 | 719 |
704 if (safe) { | 720 if (safe) { |
705 int64 handle = entry->ref(META_HANDLE); | 721 const int64 handle = entry->ref(META_HANDLE); |
| 722 const ModelType type = entry->GetServerModelType(); |
706 CHECK_EQ(kernel_->dirty_metahandles->count(handle), 0U); | 723 CHECK_EQ(kernel_->dirty_metahandles->count(handle), 0U); |
707 // TODO(tim): Bug 49278. | 724 // TODO(tim): Bug 49278. |
708 CHECK(!kernel_->unsynced_metahandles->count(handle)); | 725 CHECK(!kernel_->unsynced_metahandles->count(handle)); |
709 CHECK(!kernel_->unapplied_update_metahandles->count(handle)); | 726 CHECK(!kernel_->unapplied_update_metahandles[type].count(handle)); |
710 } | 727 } |
711 | 728 |
712 return safe; | 729 return safe; |
713 } | 730 } |
714 | 731 |
715 void Directory::TakeSnapshotForSaveChanges(SaveChangesSnapshot* snapshot) { | 732 void Directory::TakeSnapshotForSaveChanges(SaveChangesSnapshot* snapshot) { |
716 ReadTransaction trans(FROM_HERE, this); | 733 ReadTransaction trans(FROM_HERE, this); |
717 ScopedKernelLock lock(this); | 734 ScopedKernelLock lock(this); |
718 // Deep copy dirty entries from kernel_->metahandles_index into snapshot and | 735 // Deep copy dirty entries from kernel_->metahandles_index into snapshot and |
719 // clear dirty flags. | 736 // clear dirty flags. |
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
830 kernel_->metahandles_to_purge->insert(handle); | 847 kernel_->metahandles_to_purge->insert(handle); |
831 | 848 |
832 size_t num_erased = 0; | 849 size_t num_erased = 0; |
833 EntryKernel* entry = *it; | 850 EntryKernel* entry = *it; |
834 num_erased = kernel_->ids_index->erase(entry); | 851 num_erased = kernel_->ids_index->erase(entry); |
835 DCHECK_EQ(1u, num_erased); | 852 DCHECK_EQ(1u, num_erased); |
836 num_erased = kernel_->client_tag_index->erase(entry); | 853 num_erased = kernel_->client_tag_index->erase(entry); |
837 DCHECK_EQ(entry->ref(UNIQUE_CLIENT_TAG).empty(), !num_erased); | 854 DCHECK_EQ(entry->ref(UNIQUE_CLIENT_TAG).empty(), !num_erased); |
838 num_erased = kernel_->unsynced_metahandles->erase(handle); | 855 num_erased = kernel_->unsynced_metahandles->erase(handle); |
839 DCHECK_EQ(entry->ref(IS_UNSYNCED), num_erased > 0); | 856 DCHECK_EQ(entry->ref(IS_UNSYNCED), num_erased > 0); |
840 num_erased = kernel_->unapplied_update_metahandles->erase(handle); | 857 num_erased = |
| 858 kernel_->unapplied_update_metahandles[server_type].erase(handle); |
841 DCHECK_EQ(entry->ref(IS_UNAPPLIED_UPDATE), num_erased > 0); | 859 DCHECK_EQ(entry->ref(IS_UNAPPLIED_UPDATE), num_erased > 0); |
842 num_erased = kernel_->parent_id_child_index->erase(entry); | 860 num_erased = kernel_->parent_id_child_index->erase(entry); |
843 DCHECK_EQ(entry->ref(IS_DEL), !num_erased); | 861 DCHECK_EQ(entry->ref(IS_DEL), !num_erased); |
844 kernel_->metahandles_index->erase(it++); | 862 kernel_->metahandles_index->erase(it++); |
845 delete entry; | 863 delete entry; |
846 } else { | 864 } else { |
847 ++it; | 865 ++it; |
848 } | 866 } |
849 } | 867 } |
850 | 868 |
(...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1000 ScopedKernelLock lock(this); | 1018 ScopedKernelLock lock(this); |
1001 copy(kernel_->unsynced_metahandles->begin(), | 1019 copy(kernel_->unsynced_metahandles->begin(), |
1002 kernel_->unsynced_metahandles->end(), back_inserter(*result)); | 1020 kernel_->unsynced_metahandles->end(), back_inserter(*result)); |
1003 } | 1021 } |
1004 | 1022 |
1005 int64 Directory::unsynced_entity_count() const { | 1023 int64 Directory::unsynced_entity_count() const { |
1006 ScopedKernelLock lock(this); | 1024 ScopedKernelLock lock(this); |
1007 return kernel_->unsynced_metahandles->size(); | 1025 return kernel_->unsynced_metahandles->size(); |
1008 } | 1026 } |
1009 | 1027 |
1010 void Directory::GetUnappliedUpdateMetaHandles(BaseTransaction* trans, | 1028 syncable::ModelTypeBitSet |
| 1029 Directory::GetServerTypesWithUnappliedUpdates( |
| 1030 BaseTransaction* trans) const { |
| 1031 syncable::ModelTypeBitSet server_types; |
| 1032 ScopedKernelLock lock(this); |
| 1033 for (int i = 0; i < MODEL_TYPE_COUNT; ++i) { |
| 1034 if (!kernel_->unapplied_update_metahandles[i].empty()) { |
| 1035 server_types.set(i); |
| 1036 } |
| 1037 } |
| 1038 return server_types; |
| 1039 } |
| 1040 |
| 1041 void Directory::GetUnappliedUpdateMetaHandles( |
| 1042 BaseTransaction* trans, |
| 1043 syncable::ModelTypeBitSet server_types, |
1011 UnappliedUpdateMetaHandles* result) { | 1044 UnappliedUpdateMetaHandles* result) { |
1012 result->clear(); | 1045 result->clear(); |
1013 ScopedKernelLock lock(this); | 1046 ScopedKernelLock lock(this); |
1014 copy(kernel_->unapplied_update_metahandles->begin(), | 1047 for (int i = 0; i < MODEL_TYPE_COUNT; ++i) { |
1015 kernel_->unapplied_update_metahandles->end(), | 1048 const ModelType type = ModelTypeFromInt(i); |
1016 back_inserter(*result)); | 1049 if (server_types.test(type)) { |
| 1050 std::copy(kernel_->unapplied_update_metahandles[type].begin(), |
| 1051 kernel_->unapplied_update_metahandles[type].end(), |
| 1052 back_inserter(*result)); |
| 1053 } |
| 1054 } |
1017 } | 1055 } |
1018 | 1056 |
1019 | 1057 |
1020 class IdFilter { | 1058 class IdFilter { |
1021 public: | 1059 public: |
1022 virtual ~IdFilter() { } | 1060 virtual ~IdFilter() { } |
1023 virtual bool ShouldConsider(const Id& id) const = 0; | 1061 virtual bool ShouldConsider(const Id& id) const = 0; |
1024 }; | 1062 }; |
1025 | 1063 |
1026 | 1064 |
(...skipping 336 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1363 | 1401 |
1364 Id Entry::ComputePrevIdFromServerPosition(const Id& parent_id) const { | 1402 Id Entry::ComputePrevIdFromServerPosition(const Id& parent_id) const { |
1365 return dir()->ComputePrevIdFromServerPosition(kernel_, parent_id); | 1403 return dir()->ComputePrevIdFromServerPosition(kernel_, parent_id); |
1366 } | 1404 } |
1367 | 1405 |
1368 DictionaryValue* Entry::ToValue() const { | 1406 DictionaryValue* Entry::ToValue() const { |
1369 DictionaryValue* entry_info = new DictionaryValue(); | 1407 DictionaryValue* entry_info = new DictionaryValue(); |
1370 entry_info->SetBoolean("good", good()); | 1408 entry_info->SetBoolean("good", good()); |
1371 if (good()) { | 1409 if (good()) { |
1372 entry_info->Set("kernel", kernel_->ToValue()); | 1410 entry_info->Set("kernel", kernel_->ToValue()); |
1373 entry_info->Set("serverModelType", | |
1374 ModelTypeToValue(GetServerModelTypeHelper())); | |
1375 entry_info->Set("modelType", | 1411 entry_info->Set("modelType", |
1376 ModelTypeToValue(GetModelType())); | 1412 ModelTypeToValue(GetModelType())); |
1377 entry_info->SetBoolean("existsOnClientBecauseNameIsNonEmpty", | 1413 entry_info->SetBoolean("existsOnClientBecauseNameIsNonEmpty", |
1378 ExistsOnClientBecauseNameIsNonEmpty()); | 1414 ExistsOnClientBecauseNameIsNonEmpty()); |
1379 entry_info->SetBoolean("isRoot", IsRoot()); | 1415 entry_info->SetBoolean("isRoot", IsRoot()); |
1380 } | 1416 } |
1381 return entry_info; | 1417 return entry_info; |
1382 } | 1418 } |
1383 | 1419 |
1384 const string& Entry::Get(StringField field) const { | 1420 const string& Entry::Get(StringField field) const { |
1385 DCHECK(kernel_); | 1421 DCHECK(kernel_); |
1386 return kernel_->ref(field); | 1422 return kernel_->ref(field); |
1387 } | 1423 } |
1388 | 1424 |
1389 syncable::ModelType Entry::GetServerModelType() const { | 1425 syncable::ModelType Entry::GetServerModelType() const { |
1390 ModelType specifics_type = GetServerModelTypeHelper(); | 1426 ModelType specifics_type = kernel_->GetServerModelType(); |
1391 if (specifics_type != UNSPECIFIED) | 1427 if (specifics_type != UNSPECIFIED) |
1392 return specifics_type; | 1428 return specifics_type; |
1393 | 1429 |
1394 // Otherwise, we don't have a server type yet. That should only happen | 1430 // Otherwise, we don't have a server type yet. That should only happen |
1395 // if the item is an uncommitted locally created item. | 1431 // if the item is an uncommitted locally created item. |
1396 // It's possible we'll need to relax these checks in the future; they're | 1432 // It's possible we'll need to relax these checks in the future; they're |
1397 // just here for now as a safety measure. | 1433 // just here for now as a safety measure. |
1398 DCHECK(Get(IS_UNSYNCED)); | 1434 DCHECK(Get(IS_UNSYNCED)); |
1399 DCHECK_EQ(Get(SERVER_VERSION), 0); | 1435 DCHECK_EQ(Get(SERVER_VERSION), 0); |
1400 DCHECK(Get(SERVER_IS_DEL)); | 1436 DCHECK(Get(SERVER_IS_DEL)); |
1401 // Note: can't enforce !Get(ID).ServerKnows() here because that could | 1437 // Note: can't enforce !Get(ID).ServerKnows() here because that could |
1402 // actually happen if we hit AttemptReuniteLostCommitResponses. | 1438 // actually happen if we hit AttemptReuniteLostCommitResponses. |
1403 return UNSPECIFIED; | 1439 return UNSPECIFIED; |
1404 } | 1440 } |
1405 | 1441 |
1406 syncable::ModelType Entry::GetServerModelTypeHelper() const { | |
1407 ModelType specifics_type = GetModelTypeFromSpecifics(Get(SERVER_SPECIFICS)); | |
1408 if (specifics_type != UNSPECIFIED) | |
1409 return specifics_type; | |
1410 if (IsRoot()) | |
1411 return TOP_LEVEL_FOLDER; | |
1412 // Loose check for server-created top-level folders that aren't | |
1413 // bound to a particular model type. | |
1414 if (!Get(UNIQUE_SERVER_TAG).empty() && Get(SERVER_IS_DIR)) | |
1415 return TOP_LEVEL_FOLDER; | |
1416 | |
1417 return UNSPECIFIED; | |
1418 } | |
1419 | |
1420 syncable::ModelType Entry::GetModelType() const { | 1442 syncable::ModelType Entry::GetModelType() const { |
1421 ModelType specifics_type = GetModelTypeFromSpecifics(Get(SPECIFICS)); | 1443 ModelType specifics_type = GetModelTypeFromSpecifics(Get(SPECIFICS)); |
1422 if (specifics_type != UNSPECIFIED) | 1444 if (specifics_type != UNSPECIFIED) |
1423 return specifics_type; | 1445 return specifics_type; |
1424 if (IsRoot()) | 1446 if (IsRoot()) |
1425 return TOP_LEVEL_FOLDER; | 1447 return TOP_LEVEL_FOLDER; |
1426 // Loose check for server-created top-level folders that aren't | 1448 // Loose check for server-created top-level folders that aren't |
1427 // bound to a particular model type. | 1449 // bound to a particular model type. |
1428 if (!Get(UNIQUE_SERVER_TAG).empty() && Get(IS_DIR)) | 1450 if (!Get(UNIQUE_SERVER_TAG).empty() && Get(IS_DIR)) |
1429 return TOP_LEVEL_FOLDER; | 1451 return TOP_LEVEL_FOLDER; |
(...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1596 bool MutableEntry::Put(StringField field, const string& value) { | 1618 bool MutableEntry::Put(StringField field, const string& value) { |
1597 return PutImpl(field, value); | 1619 return PutImpl(field, value); |
1598 } | 1620 } |
1599 | 1621 |
1600 bool MutableEntry::Put(ProtoField field, | 1622 bool MutableEntry::Put(ProtoField field, |
1601 const sync_pb::EntitySpecifics& value) { | 1623 const sync_pb::EntitySpecifics& value) { |
1602 DCHECK(kernel_); | 1624 DCHECK(kernel_); |
1603 // TODO(ncarter): This is unfortunately heavyweight. Can we do | 1625 // TODO(ncarter): This is unfortunately heavyweight. Can we do |
1604 // better? | 1626 // better? |
1605 if (kernel_->ref(field).SerializeAsString() != value.SerializeAsString()) { | 1627 if (kernel_->ref(field).SerializeAsString() != value.SerializeAsString()) { |
| 1628 const bool update_unapplied_updates_index = |
| 1629 (field == SERVER_SPECIFICS) && kernel_->ref(IS_UNAPPLIED_UPDATE); |
| 1630 if (update_unapplied_updates_index) { |
| 1631 // Remove ourselves from unapplied_update_metahandles with our |
| 1632 // old server type. |
| 1633 const syncable::ModelType old_server_type = |
| 1634 kernel_->GetServerModelType(); |
| 1635 const int64 metahandle = kernel_->ref(META_HANDLE); |
| 1636 size_t erase_count = |
| 1637 dir()->kernel_->unapplied_update_metahandles[old_server_type] |
| 1638 .erase(metahandle); |
| 1639 DCHECK_EQ(erase_count, 1u); |
| 1640 } |
| 1641 |
1606 kernel_->put(field, value); | 1642 kernel_->put(field, value); |
1607 kernel_->mark_dirty(dir()->kernel_->dirty_metahandles); | 1643 kernel_->mark_dirty(dir()->kernel_->dirty_metahandles); |
| 1644 |
| 1645 if (update_unapplied_updates_index) { |
| 1646 // Add ourselves back into unapplied_update_metahandles with our |
| 1647 // new server type. |
| 1648 const syncable::ModelType new_server_type = |
| 1649 kernel_->GetServerModelType(); |
| 1650 const int64 metahandle = kernel_->ref(META_HANDLE); |
| 1651 dir()->kernel_->unapplied_update_metahandles[new_server_type] |
| 1652 .insert(metahandle); |
| 1653 } |
1608 } | 1654 } |
1609 return true; | 1655 return true; |
1610 } | 1656 } |
1611 | 1657 |
1612 bool MutableEntry::Put(BitField field, bool value) { | 1658 bool MutableEntry::Put(BitField field, bool value) { |
1613 DCHECK(kernel_); | 1659 DCHECK(kernel_); |
1614 if (kernel_->ref(field) != value) { | 1660 if (kernel_->ref(field) != value) { |
1615 kernel_->put(field, value); | 1661 kernel_->put(field, value); |
1616 kernel_->mark_dirty(GetDirtyIndexHelper()); | 1662 kernel_->mark_dirty(GetDirtyIndexHelper()); |
1617 } | 1663 } |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1660 kernel_->put(field, value); | 1706 kernel_->put(field, value); |
1661 kernel_->mark_dirty(dir()->kernel_->dirty_metahandles); | 1707 kernel_->mark_dirty(dir()->kernel_->dirty_metahandles); |
1662 } | 1708 } |
1663 return true; | 1709 return true; |
1664 } | 1710 } |
1665 | 1711 |
1666 bool MutableEntry::Put(IndexedBitField field, bool value) { | 1712 bool MutableEntry::Put(IndexedBitField field, bool value) { |
1667 DCHECK(kernel_); | 1713 DCHECK(kernel_); |
1668 if (kernel_->ref(field) != value) { | 1714 if (kernel_->ref(field) != value) { |
1669 MetahandleSet* index; | 1715 MetahandleSet* index; |
1670 if (IS_UNSYNCED == field) | 1716 if (IS_UNSYNCED == field) { |
1671 index = dir()->kernel_->unsynced_metahandles; | 1717 index = dir()->kernel_->unsynced_metahandles; |
1672 else | 1718 } else { |
1673 index = dir()->kernel_->unapplied_update_metahandles; | 1719 // Use kernel_->GetServerModelType() instead of |
| 1720 // GetServerModelType() as we may trigger some DCHECKs in the |
| 1721 // latter. |
| 1722 index = |
| 1723 &dir()->kernel_->unapplied_update_metahandles[ |
| 1724 kernel_->GetServerModelType()]; |
| 1725 } |
1674 | 1726 |
1675 ScopedKernelLock lock(dir()); | 1727 ScopedKernelLock lock(dir()); |
1676 if (value) | 1728 if (value) |
1677 CHECK(index->insert(kernel_->ref(META_HANDLE)).second); | 1729 CHECK(index->insert(kernel_->ref(META_HANDLE)).second); |
1678 else | 1730 else |
1679 CHECK_EQ(1U, index->erase(kernel_->ref(META_HANDLE))); | 1731 CHECK_EQ(1U, index->erase(kernel_->ref(META_HANDLE))); |
1680 kernel_->put(field, value); | 1732 kernel_->put(field, value); |
1681 kernel_->mark_dirty(dir()->kernel_->dirty_metahandles); | 1733 kernel_->mark_dirty(dir()->kernel_->dirty_metahandles); |
1682 } | 1734 } |
1683 return true; | 1735 return true; |
(...skipping 376 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2060 if (entry->ref(NEXT_ID).IsRoot() || | 2112 if (entry->ref(NEXT_ID).IsRoot() || |
2061 entry->ref(NEXT_ID) != entry->ref(PREV_ID)) { | 2113 entry->ref(NEXT_ID) != entry->ref(PREV_ID)) { |
2062 return entry; | 2114 return entry; |
2063 } | 2115 } |
2064 } | 2116 } |
2065 // There were no children in the linked list. | 2117 // There were no children in the linked list. |
2066 return NULL; | 2118 return NULL; |
2067 } | 2119 } |
2068 | 2120 |
2069 } // namespace syncable | 2121 } // namespace syncable |
OLD | NEW |