Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(925)

Side by Side Diff: chrome/browser/sync/syncable/syncable.cc

Issue 8637006: [Sync] Make syncer commands avoid posting tasks on threads with no work to do (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Sync to head, fix windows compile Created 9 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
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
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
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
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
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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « chrome/browser/sync/syncable/syncable.h ('k') | chrome/browser/sync/syncable/syncable_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698