diff options
author | Torne (Richard Coles) <torne@google.com> | 2013-09-26 13:24:57 +0100 |
---|---|---|
committer | Torne (Richard Coles) <torne@google.com> | 2013-09-26 13:24:57 +0100 |
commit | 68043e1e95eeb07d5cae7aca370b26518b0867d6 (patch) | |
tree | cc6a216bce6aa9319a216327b73a07f49200dab5 /sync | |
parent | cede44592cfb9ec370925d10c2df733349a94a82 (diff) | |
download | chromium_org-68043e1e95eeb07d5cae7aca370b26518b0867d6.tar.gz |
Merge from Chromium at DEPS revision 225410
This commit was generated by merge_to_master.py.
Change-Id: Ifa1539ca216abb163295ee7a77f81bb67f52e178
Diffstat (limited to 'sync')
-rw-r--r-- | sync/android/java/src/org/chromium/sync/signin/AccountManagerHelper.java | 7 | ||||
-rw-r--r-- | sync/engine/download_unittest.cc | 5 | ||||
-rw-r--r-- | sync/engine/syncer_unittest.cc | 2 | ||||
-rw-r--r-- | sync/internal_api/debug_info_event_listener.cc | 132 | ||||
-rw-r--r-- | sync/internal_api/debug_info_event_listener.h | 6 | ||||
-rw-r--r-- | sync/internal_api/public/data_type_debug_info_listener.h | 11 | ||||
-rw-r--r-- | sync/internal_api/sync_manager_impl_unittest.cc | 2 | ||||
-rw-r--r-- | sync/sessions/sync_session_context.cc | 3 | ||||
-rw-r--r-- | sync/sync_core.gypi | 2 | ||||
-rw-r--r-- | sync/syncable/directory.h | 1 | ||||
-rw-r--r-- | sync/syncable/model_neutral_mutable_entry.cc | 355 | ||||
-rw-r--r-- | sync/syncable/model_neutral_mutable_entry.h | 109 | ||||
-rw-r--r-- | sync/syncable/mutable_entry.cc | 339 | ||||
-rw-r--r-- | sync/syncable/mutable_entry.h | 79 | ||||
-rw-r--r-- | sync/tools/sync_client.cc | 1 | ||||
-rw-r--r-- | sync/tools/sync_listen_notifications.cc | 1 |
16 files changed, 575 insertions, 480 deletions
diff --git a/sync/android/java/src/org/chromium/sync/signin/AccountManagerHelper.java b/sync/android/java/src/org/chromium/sync/signin/AccountManagerHelper.java index 01ad1620bb..1a6f34cfe9 100644 --- a/sync/android/java/src/org/chromium/sync/signin/AccountManagerHelper.java +++ b/sync/android/java/src/org/chromium/sync/signin/AccountManagerHelper.java @@ -136,6 +136,13 @@ public class AccountManagerHelper { } /** + * Returns whether the accounts exists. + */ + public boolean hasAccountForName(String accountName) { + return getAccountFromName(accountName) != null; + } + + /** * @return Whether or not there is an account authenticator for Google accounts. */ public boolean hasGoogleAccountAuthenticator() { diff --git a/sync/engine/download_unittest.cc b/sync/engine/download_unittest.cc index 6aac31d51b..fb4431a5c1 100644 --- a/sync/engine/download_unittest.cc +++ b/sync/engine/download_unittest.cc @@ -144,7 +144,10 @@ TEST_F(DownloadUpdatesTest, VerifyAppendDebugInfo) { // Create a new session, record an event, and try again. scoped_ptr<sessions::SyncSession> session2( sessions::SyncSession::Build(context(), delegate())); - debug_info_event_listener()->OnConfigureComplete(); + DataTypeConfigurationStats stats; + stats.model_type = BOOKMARKS; + debug_info_event_listener()->OnDataTypeConfigureComplete( + std::vector<DataTypeConfigurationStats>(1, stats)); sync_pb::ClientToServerMessage msg2; BuildNormalDownloadUpdates(session2.get(), false, diff --git a/sync/engine/syncer_unittest.cc b/sync/engine/syncer_unittest.cc index b1a9646353..970fed548c 100644 --- a/sync/engine/syncer_unittest.cc +++ b/sync/engine/syncer_unittest.cc @@ -3249,8 +3249,6 @@ TEST_F(SyncerTest, UpdateWhereParentIsNotAFolder) { } } -const char kRootId[] = "0"; - TEST_F(SyncerTest, DirectoryUpdateTest) { Id in_root_id = ids_.NewServerId(); Id in_in_root_id = ids_.NewServerId(); diff --git a/sync/internal_api/debug_info_event_listener.cc b/sync/internal_api/debug_info_event_listener.cc index 64bbab87ed..51e6c0f4d3 100644 --- a/sync/internal_api/debug_info_event_listener.cc +++ b/sync/internal_api/debug_info_event_listener.cc @@ -177,76 +177,76 @@ base::WeakPtr<DataTypeDebugInfoListener> DebugInfoEventListener::GetWeakPtr() { return weak_ptr_factory_.GetWeakPtr(); } -void DebugInfoEventListener::OnSingleDataTypeConfigureComplete( - const DataTypeConfigurationStats& configuration_stats) { +void DebugInfoEventListener::OnDataTypeConfigureComplete( + const std::vector<DataTypeConfigurationStats>& configuration_stats) { DCHECK(thread_checker_.CalledOnValidThread()); - DCHECK(ProtocolTypes().Has(configuration_stats.model_type)); - - const DataTypeAssociationStats& association_stats = - configuration_stats.association_stats; - - sync_pb::DebugEventInfo association_event; - sync_pb::DatatypeAssociationStats* datatype_stats = - association_event.mutable_datatype_association_stats(); - datatype_stats->set_data_type_id( - GetSpecificsFieldNumberFromModelType(configuration_stats.model_type)); - datatype_stats->set_num_local_items_before_association( - association_stats.num_local_items_before_association); - datatype_stats->set_num_sync_items_before_association( - association_stats.num_sync_items_before_association); - datatype_stats->set_num_local_items_after_association( - association_stats.num_local_items_after_association); - datatype_stats->set_num_sync_items_after_association( - association_stats.num_sync_items_after_association); - datatype_stats->set_num_local_items_added( - association_stats.num_local_items_added); - datatype_stats->set_num_local_items_deleted( - association_stats.num_local_items_deleted); - datatype_stats->set_num_local_items_modified( - association_stats.num_local_items_modified); - datatype_stats->set_num_sync_items_added( - association_stats.num_sync_items_added); - datatype_stats->set_num_sync_items_deleted( - association_stats.num_sync_items_deleted); - datatype_stats->set_num_sync_items_modified( - association_stats.num_sync_items_modified); - datatype_stats->set_local_version_pre_association( - association_stats.local_version_pre_association); - datatype_stats->set_sync_version_pre_association( - association_stats.sync_version_pre_association); - datatype_stats->set_had_error(association_stats.had_error); - datatype_stats->set_association_wait_time_for_same_priority_us( - association_stats.association_wait_time.InMicroseconds()); - datatype_stats->set_association_time_us( - association_stats.association_time.InMicroseconds()); - datatype_stats->set_download_wait_time_us( - configuration_stats.download_wait_time.InMicroseconds()); - datatype_stats->set_download_time_us( - configuration_stats.download_time.InMicroseconds()); - datatype_stats->set_association_wait_time_for_high_priority_us( - configuration_stats.association_wait_time_for_high_priority - .InMicroseconds()); - - for (ModelTypeSet::Iterator it = - configuration_stats.high_priority_types_configured_before.First(); - it.Good(); it.Inc()) { - datatype_stats->add_high_priority_type_configured_before( - GetSpecificsFieldNumberFromModelType(it.Get())); - } - for (ModelTypeSet::Iterator it = - configuration_stats.same_priority_types_configured_before.First(); - it.Good(); it.Inc()) { - datatype_stats->add_same_priority_type_configured_before( - GetSpecificsFieldNumberFromModelType(it.Get())); - } + for (size_t i = 0; i < configuration_stats.size(); ++i) { + DCHECK(ProtocolTypes().Has(configuration_stats[i].model_type)); + const DataTypeAssociationStats& association_stats = + configuration_stats[i].association_stats; + + sync_pb::DebugEventInfo association_event; + sync_pb::DatatypeAssociationStats* datatype_stats = + association_event.mutable_datatype_association_stats(); + datatype_stats->set_data_type_id( + GetSpecificsFieldNumberFromModelType( + configuration_stats[i].model_type)); + datatype_stats->set_num_local_items_before_association( + association_stats.num_local_items_before_association); + datatype_stats->set_num_sync_items_before_association( + association_stats.num_sync_items_before_association); + datatype_stats->set_num_local_items_after_association( + association_stats.num_local_items_after_association); + datatype_stats->set_num_sync_items_after_association( + association_stats.num_sync_items_after_association); + datatype_stats->set_num_local_items_added( + association_stats.num_local_items_added); + datatype_stats->set_num_local_items_deleted( + association_stats.num_local_items_deleted); + datatype_stats->set_num_local_items_modified( + association_stats.num_local_items_modified); + datatype_stats->set_num_sync_items_added( + association_stats.num_sync_items_added); + datatype_stats->set_num_sync_items_deleted( + association_stats.num_sync_items_deleted); + datatype_stats->set_num_sync_items_modified( + association_stats.num_sync_items_modified); + datatype_stats->set_local_version_pre_association( + association_stats.local_version_pre_association); + datatype_stats->set_sync_version_pre_association( + association_stats.sync_version_pre_association); + datatype_stats->set_had_error(association_stats.had_error); + datatype_stats->set_association_wait_time_for_same_priority_us( + association_stats.association_wait_time.InMicroseconds()); + datatype_stats->set_association_time_us( + association_stats.association_time.InMicroseconds()); + datatype_stats->set_download_wait_time_us( + configuration_stats[i].download_wait_time.InMicroseconds()); + datatype_stats->set_download_time_us( + configuration_stats[i].download_time.InMicroseconds()); + datatype_stats->set_association_wait_time_for_high_priority_us( + configuration_stats[i].association_wait_time_for_high_priority + .InMicroseconds()); + + for (ModelTypeSet::Iterator it = + configuration_stats[i].high_priority_types_configured_before + .First(); + it.Good(); it.Inc()) { + datatype_stats->add_high_priority_type_configured_before( + GetSpecificsFieldNumberFromModelType(it.Get())); + } - AddEventToQueue(association_event); -} + for (ModelTypeSet::Iterator it = + configuration_stats[i].same_priority_types_configured_before + .First(); + it.Good(); it.Inc()) { + datatype_stats->add_same_priority_type_configured_before( + GetSpecificsFieldNumberFromModelType(it.Get())); + } -void DebugInfoEventListener::OnConfigureComplete() { - DCHECK(thread_checker_.CalledOnValidThread()); - CreateAndAddEvent(sync_pb::DebugEventInfo::CONFIGURE_COMPLETE); + AddEventToQueue(association_event); + } } void DebugInfoEventListener::CreateAndAddEvent( diff --git a/sync/internal_api/debug_info_event_listener.h b/sync/internal_api/debug_info_event_listener.h index 022fafb91f..c3aa9d0929 100644 --- a/sync/internal_api/debug_info_event_listener.h +++ b/sync/internal_api/debug_info_event_listener.h @@ -77,9 +77,9 @@ class SYNC_EXPORT_PRIVATE DebugInfoEventListener virtual void GetAndClearDebugInfo(sync_pb::DebugInfo* debug_info) OVERRIDE; // DataTypeDebugInfoListener implementation. - virtual void OnSingleDataTypeConfigureComplete( - const DataTypeConfigurationStats& configuration_stats) OVERRIDE; - virtual void OnConfigureComplete() OVERRIDE; + virtual void OnDataTypeConfigureComplete( + const std::vector<DataTypeConfigurationStats>& configuration_stats) + OVERRIDE; // Returns a weak pointer to this object. base::WeakPtr<DataTypeDebugInfoListener> GetWeakPtr(); diff --git a/sync/internal_api/public/data_type_debug_info_listener.h b/sync/internal_api/public/data_type_debug_info_listener.h index 82d64598f2..6395a0450a 100644 --- a/sync/internal_api/public/data_type_debug_info_listener.h +++ b/sync/internal_api/public/data_type_debug_info_listener.h @@ -5,6 +5,8 @@ #ifndef SYNC_INTERNAL_API_PUBLIC_DATA_TYPE_DEBUG_INFO_LISTENER_H_ #define SYNC_INTERNAL_API_PUBLIC_DATA_TYPE_DEBUG_INFO_LISTENER_H_ +#include <vector> + #include "sync/internal_api/public/base/model_type.h" #include "sync/internal_api/public/data_type_association_stats.h" @@ -38,12 +40,9 @@ struct SYNC_EXPORT DataTypeConfigurationStats { // Interface for the sync internals to listen to external sync events. class DataTypeDebugInfoListener { public: - // Notify the listener that configuration of one data type has completed. - virtual void OnSingleDataTypeConfigureComplete( - const DataTypeConfigurationStats& configuration_stats) = 0; - - // Notify the listener that configuration has completed and sync has begun. - virtual void OnConfigureComplete() = 0; + // Notify the listener that configuration of data types has completed. + virtual void OnDataTypeConfigureComplete( + const std::vector<DataTypeConfigurationStats>& configuration_stats) = 0; }; } // namespace syncer diff --git a/sync/internal_api/sync_manager_impl_unittest.cc b/sync/internal_api/sync_manager_impl_unittest.cc index dc47365437..2e0d9ae8f7 100644 --- a/sync/internal_api/sync_manager_impl_unittest.cc +++ b/sync/internal_api/sync_manager_impl_unittest.cc @@ -96,8 +96,6 @@ using syncable::kEncryptedString; namespace { -const char kTestChromeVersion[] = "test chrome version"; - void ExpectInt64Value(int64 expected_value, const base::DictionaryValue& value, const std::string& key) { diff --git a/sync/sessions/sync_session_context.cc b/sync/sessions/sync_session_context.cc index 98ab5f01a9..bf1da3a174 100644 --- a/sync/sessions/sync_session_context.cc +++ b/sync/sessions/sync_session_context.cc @@ -10,9 +10,6 @@ namespace syncer { namespace sessions { -const unsigned int kMaxMessagesToRecord = 10; -const unsigned int kMaxMessageSizeToRecord = 5 * 1024; - SyncSessionContext::SyncSessionContext( ServerConnectionManager* connection_manager, syncable::Directory* directory, diff --git a/sync/sync_core.gypi b/sync/sync_core.gypi index 95b3ff8bae..9633f5e764 100644 --- a/sync/sync_core.gypi +++ b/sync/sync_core.gypi @@ -128,6 +128,8 @@ 'syncable/invalid_directory_backing_store.cc', 'syncable/invalid_directory_backing_store.h', 'syncable/metahandle_set.h', + 'syncable/model_neutral_mutable_entry.cc', + 'syncable/model_neutral_mutable_entry.h', 'syncable/model_type.cc', 'syncable/mutable_entry.cc', 'syncable/mutable_entry.h', diff --git a/sync/syncable/directory.h b/sync/syncable/directory.h index 2212a8c650..6de3a470ec 100644 --- a/sync/syncable/directory.h +++ b/sync/syncable/directory.h @@ -48,6 +48,7 @@ enum InvariantCheckLevel { class SYNC_EXPORT Directory { friend class BaseTransaction; friend class Entry; + friend class ModelNeutralMutableEntry; friend class MutableEntry; friend class ReadTransaction; friend class ScopedKernelLock; diff --git a/sync/syncable/model_neutral_mutable_entry.cc b/sync/syncable/model_neutral_mutable_entry.cc new file mode 100644 index 0000000000..3d019e62a3 --- /dev/null +++ b/sync/syncable/model_neutral_mutable_entry.cc @@ -0,0 +1,355 @@ +// Copyright 2013 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "sync/syncable/model_neutral_mutable_entry.h" + +#include <string> + +#include "sync/internal_api/public/base/unique_position.h" +#include "sync/syncable/directory.h" +#include "sync/syncable/scoped_kernel_lock.h" +#include "sync/syncable/syncable_util.h" +#include "sync/syncable/syncable_write_transaction.h" + +using std::string; + +namespace syncer { + +namespace syncable { + +ModelNeutralMutableEntry::ModelNeutralMutableEntry( + WriteTransaction* trans, GetById, const Id& id) + : Entry(trans, GET_BY_ID, id), write_transaction_(trans) { +} + +ModelNeutralMutableEntry::ModelNeutralMutableEntry( + WriteTransaction* trans, GetByHandle, int64 metahandle) + : Entry(trans, GET_BY_HANDLE, metahandle), write_transaction_(trans) { +} + +ModelNeutralMutableEntry::ModelNeutralMutableEntry( + WriteTransaction* trans, GetByClientTag, const std::string& tag) + : Entry(trans, GET_BY_CLIENT_TAG, tag), write_transaction_(trans) { +} + +ModelNeutralMutableEntry::ModelNeutralMutableEntry( + WriteTransaction* trans, GetByServerTag, const string& tag) + : Entry(trans, GET_BY_SERVER_TAG, tag), write_transaction_(trans) { +} + +void ModelNeutralMutableEntry::PutBaseVersion(int64 value) { + DCHECK(kernel_); + write_transaction_->SaveOriginal(kernel_); + if (kernel_->ref(BASE_VERSION) != value) { + kernel_->put(BASE_VERSION, value); + kernel_->mark_dirty(&dir()->kernel_->dirty_metahandles); + } +} + +void ModelNeutralMutableEntry::PutServerVersion(int64 value) { + DCHECK(kernel_); + write_transaction_->SaveOriginal(kernel_); + if (kernel_->ref(SERVER_VERSION) != value) { + ScopedKernelLock lock(dir()); + kernel_->put(SERVER_VERSION, value); + kernel_->mark_dirty(&dir()->kernel_->dirty_metahandles); + } +} + +void ModelNeutralMutableEntry::PutServerMtime(base::Time value) { + DCHECK(kernel_); + write_transaction_->SaveOriginal(kernel_); + if (kernel_->ref(SERVER_MTIME) != value) { + kernel_->put(SERVER_MTIME, value); + kernel_->mark_dirty(&dir()->kernel_->dirty_metahandles); + } +} + +void ModelNeutralMutableEntry::PutServerCtime(base::Time value) { + DCHECK(kernel_); + write_transaction_->SaveOriginal(kernel_); + if (kernel_->ref(SERVER_CTIME) != value) { + kernel_->put(SERVER_CTIME, value); + kernel_->mark_dirty(&dir()->kernel_->dirty_metahandles); + } +} + +bool ModelNeutralMutableEntry::PutId(const Id& value) { + DCHECK(kernel_); + write_transaction_->SaveOriginal(kernel_); + if (kernel_->ref(ID) != value) { + if (!dir()->ReindexId(write_transaction(), kernel_, value)) + return false; + kernel_->mark_dirty(&dir()->kernel_->dirty_metahandles); + } + return true; +} + +void ModelNeutralMutableEntry::PutServerParentId(const Id& value) { + DCHECK(kernel_); + write_transaction_->SaveOriginal(kernel_); + + if (kernel_->ref(SERVER_PARENT_ID) != value) { + kernel_->put(SERVER_PARENT_ID, value); + kernel_->mark_dirty(&dir()->kernel_->dirty_metahandles); + } +} + +bool ModelNeutralMutableEntry::PutIsUnsynced(bool value) { + DCHECK(kernel_); + write_transaction_->SaveOriginal(kernel_); + if (kernel_->ref(IS_UNSYNCED) != value) { + MetahandleSet* index = &dir()->kernel_->unsynced_metahandles; + + ScopedKernelLock lock(dir()); + if (value) { + if (!SyncAssert(index->insert(kernel_->ref(META_HANDLE)).second, + FROM_HERE, + "Could not insert", + write_transaction())) { + return false; + } + } else { + if (!SyncAssert(1U == index->erase(kernel_->ref(META_HANDLE)), + FROM_HERE, + "Entry Not succesfully erased", + write_transaction())) { + return false; + } + } + kernel_->put(IS_UNSYNCED, value); + kernel_->mark_dirty(&dir()->kernel_->dirty_metahandles); + } + return true; +} + +bool ModelNeutralMutableEntry::PutIsUnappliedUpdate(bool value) { + DCHECK(kernel_); + write_transaction_->SaveOriginal(kernel_); + if (kernel_->ref(IS_UNAPPLIED_UPDATE) != value) { + // Use kernel_->GetServerModelType() instead of + // GetServerModelType() as we may trigger some DCHECKs in the + // latter. + MetahandleSet* index = &dir()->kernel_->unapplied_update_metahandles[ + kernel_->GetServerModelType()]; + + ScopedKernelLock lock(dir()); + if (value) { + if (!SyncAssert(index->insert(kernel_->ref(META_HANDLE)).second, + FROM_HERE, + "Could not insert", + write_transaction())) { + return false; + } + } else { + if (!SyncAssert(1U == index->erase(kernel_->ref(META_HANDLE)), + FROM_HERE, + "Entry Not succesfully erased", + write_transaction())) { + return false; + } + } + kernel_->put(IS_UNAPPLIED_UPDATE, value); + kernel_->mark_dirty(&dir()->kernel_->dirty_metahandles); + } + return true; +} + +void ModelNeutralMutableEntry::PutServerIsDir(bool value) { + DCHECK(kernel_); + write_transaction_->SaveOriginal(kernel_); + bool old_value = kernel_->ref(SERVER_IS_DIR); + if (old_value != value) { + kernel_->put(SERVER_IS_DIR, value); + kernel_->mark_dirty(GetDirtyIndexHelper()); + } +} + +void ModelNeutralMutableEntry::PutServerIsDel(bool value) { + DCHECK(kernel_); + write_transaction_->SaveOriginal(kernel_); + bool old_value = kernel_->ref(SERVER_IS_DEL); + if (old_value != value) { + kernel_->put(SERVER_IS_DEL, value); + kernel_->mark_dirty(GetDirtyIndexHelper()); + } + + // Update delete journal for existence status change on server side here + // instead of in PutIsDel() because IS_DEL may not be updated due to + // early returns when processing updates. And because + // UpdateDeleteJournalForServerDelete() checks for SERVER_IS_DEL, it has + // to be called on sync thread. + dir()->delete_journal()->UpdateDeleteJournalForServerDelete( + write_transaction(), old_value, *kernel_); +} + +void ModelNeutralMutableEntry::PutServerNonUniqueName( + const std::string& value) { + DCHECK(kernel_); + write_transaction_->SaveOriginal(kernel_); + + if (kernel_->ref(SERVER_NON_UNIQUE_NAME) != value) { + kernel_->put(SERVER_NON_UNIQUE_NAME, value); + kernel_->mark_dirty(&dir()->kernel_->dirty_metahandles); + } +} + +bool ModelNeutralMutableEntry::PutUniqueServerTag(const string& new_tag) { + if (new_tag == kernel_->ref(UNIQUE_SERVER_TAG)) { + return true; + } + + write_transaction_->SaveOriginal(kernel_); + ScopedKernelLock lock(dir()); + // Make sure your new value is not in there already. + if (dir()->kernel_->server_tags_map.find(new_tag) != + dir()->kernel_->server_tags_map.end()) { + DVLOG(1) << "Detected duplicate server tag"; + return false; + } + dir()->kernel_->server_tags_map.erase( + kernel_->ref(UNIQUE_SERVER_TAG)); + kernel_->put(UNIQUE_SERVER_TAG, new_tag); + kernel_->mark_dirty(&dir()->kernel_->dirty_metahandles); + if (!new_tag.empty()) { + dir()->kernel_->server_tags_map[new_tag] = kernel_; + } + + return true; +} + +bool ModelNeutralMutableEntry::PutUniqueClientTag(const string& new_tag) { + if (new_tag == kernel_->ref(UNIQUE_CLIENT_TAG)) { + return true; + } + + write_transaction_->SaveOriginal(kernel_); + ScopedKernelLock lock(dir()); + // Make sure your new value is not in there already. + if (dir()->kernel_->client_tags_map.find(new_tag) != + dir()->kernel_->client_tags_map.end()) { + DVLOG(1) << "Detected duplicate client tag"; + return false; + } + dir()->kernel_->client_tags_map.erase( + kernel_->ref(UNIQUE_CLIENT_TAG)); + kernel_->put(UNIQUE_CLIENT_TAG, new_tag); + kernel_->mark_dirty(&dir()->kernel_->dirty_metahandles); + if (!new_tag.empty()) { + dir()->kernel_->client_tags_map[new_tag] = kernel_; + } + + return true; +} + +void ModelNeutralMutableEntry::PutUniqueBookmarkTag(const std::string& tag) { + // This unique tag will eventually be used as the unique suffix when adjusting + // this bookmark's position. Let's make sure it's a valid suffix. + if (!UniquePosition::IsValidSuffix(tag)) { + NOTREACHED(); + return; + } + + if (!kernel_->ref(UNIQUE_BOOKMARK_TAG).empty() && + tag != kernel_->ref(UNIQUE_BOOKMARK_TAG)) { + // There is only one scenario where our tag is expected to change. That + // scenario occurs when our current tag is a non-correct tag assigned during + // the UniquePosition migration. + std::string migration_generated_tag = + GenerateSyncableBookmarkHash(std::string(), + kernel_->ref(ID).GetServerId()); + DCHECK_EQ(migration_generated_tag, kernel_->ref(UNIQUE_BOOKMARK_TAG)); + } + + kernel_->put(UNIQUE_BOOKMARK_TAG, tag); + kernel_->mark_dirty(&dir()->kernel_->dirty_metahandles); +} + +void ModelNeutralMutableEntry::PutServerSpecifics( + const sync_pb::EntitySpecifics& value) { + DCHECK(kernel_); + CHECK(!value.password().has_client_only_encrypted_data()); + write_transaction_->SaveOriginal(kernel_); + // TODO(ncarter): This is unfortunately heavyweight. Can we do + // better? + if (kernel_->ref(SERVER_SPECIFICS).SerializeAsString() != + value.SerializeAsString()) { + if (kernel_->ref(IS_UNAPPLIED_UPDATE)) { + // Remove ourselves from unapplied_update_metahandles with our + // old server type. + const ModelType old_server_type = kernel_->GetServerModelType(); + const int64 metahandle = kernel_->ref(META_HANDLE); + size_t erase_count = + dir()->kernel_->unapplied_update_metahandles[old_server_type] + .erase(metahandle); + DCHECK_EQ(erase_count, 1u); + } + + kernel_->put(SERVER_SPECIFICS, value); + kernel_->mark_dirty(&dir()->kernel_->dirty_metahandles); + + if (kernel_->ref(IS_UNAPPLIED_UPDATE)) { + // Add ourselves back into unapplied_update_metahandles with our + // new server type. + const ModelType new_server_type = kernel_->GetServerModelType(); + const int64 metahandle = kernel_->ref(META_HANDLE); + dir()->kernel_->unapplied_update_metahandles[new_server_type] + .insert(metahandle); + } + } +} + +void ModelNeutralMutableEntry::PutBaseServerSpecifics( + const sync_pb::EntitySpecifics& value) { + DCHECK(kernel_); + CHECK(!value.password().has_client_only_encrypted_data()); + write_transaction_->SaveOriginal(kernel_); + // TODO(ncarter): This is unfortunately heavyweight. Can we do + // better? + if (kernel_->ref(BASE_SERVER_SPECIFICS).SerializeAsString() + != value.SerializeAsString()) { + kernel_->put(BASE_SERVER_SPECIFICS, value); + kernel_->mark_dirty(&dir()->kernel_->dirty_metahandles); + } +} + +void ModelNeutralMutableEntry::PutServerUniquePosition( + const UniquePosition& value) { + DCHECK(kernel_); + write_transaction_->SaveOriginal(kernel_); + if(!kernel_->ref(SERVER_UNIQUE_POSITION).Equals(value)) { + // We should never overwrite a valid position with an invalid one. + DCHECK(value.IsValid()); + ScopedKernelLock lock(dir()); + kernel_->put(SERVER_UNIQUE_POSITION, value); + kernel_->mark_dirty(&dir()->kernel_->dirty_metahandles); + } +} + +void ModelNeutralMutableEntry::PutSyncing(bool value) { + kernel_->put(SYNCING, value); +} + +void ModelNeutralMutableEntry::PutParentIdPropertyOnly(const Id& parent_id) { + write_transaction_->SaveOriginal(kernel_); + dir()->ReindexParentId(write_transaction(), kernel_, parent_id); + kernel_->mark_dirty(&dir()->kernel_->dirty_metahandles); +} + +void ModelNeutralMutableEntry::UpdateTransactionVersion(int64 value) { + ScopedKernelLock lock(dir()); + kernel_->put(TRANSACTION_VERSION, value); + kernel_->mark_dirty(&(dir()->kernel_->dirty_metahandles)); +} + +ModelNeutralMutableEntry::ModelNeutralMutableEntry(WriteTransaction* trans) + : Entry(trans), write_transaction_(trans) {} + +MetahandleSet* ModelNeutralMutableEntry::GetDirtyIndexHelper() { + return &dir()->kernel_->dirty_metahandles; +} + +} // namespace syncable + +} // namespace syncer diff --git a/sync/syncable/model_neutral_mutable_entry.h b/sync/syncable/model_neutral_mutable_entry.h new file mode 100644 index 0000000000..0d15fc9d0d --- /dev/null +++ b/sync/syncable/model_neutral_mutable_entry.h @@ -0,0 +1,109 @@ +// Copyright 2013 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef SYNC_SYNCABLE_MODEL_NEUTRAL_MUTABLE_ENTRY_H_ +#define SYNC_SYNCABLE_MODEL_NEUTRAL_MUTABLE_ENTRY_H_ + +#include "sync/base/sync_export.h" +#include "sync/internal_api/public/base/model_type.h" +#include "sync/syncable/entry.h" + +namespace syncer { +class WriteNode; + +namespace syncable { + +class WriteTransaction; + +// This Entry includes all the operations one can safely perform on the sync +// thread. In particular, it does not expose setters to make changes that need +// to be communicated to the model (and the model's thread). It is not possible +// to change an entry's SPECIFICS or UNIQUE_POSITION fields with this kind of +// entry. +class SYNC_EXPORT_PRIVATE ModelNeutralMutableEntry : public Entry { + public: + ModelNeutralMutableEntry(WriteTransaction* trans, GetByHandle, int64); + ModelNeutralMutableEntry(WriteTransaction* trans, GetById, const Id&); + ModelNeutralMutableEntry( + WriteTransaction* trans, + GetByClientTag, + const std::string& tag); + ModelNeutralMutableEntry( + WriteTransaction* trans, + GetByServerTag, + const std::string& tag); + + inline WriteTransaction* write_transaction() const { + return write_transaction_; + } + + // Non-model-changing setters. These setters will change properties internal + // to the node. These fields are important for bookkeeping in the sync + // internals, but it is not necessary to communicate changes in these fields + // to the local models. + // + // Some of them trigger the re-indexing of the entry. They return true on + // success and false on failure, which occurs when putting the value would + // have caused a duplicate in the index. The setters that never fail return + // void. + void PutBaseVersion(int64 value); + void PutServerVersion(int64 value); + void PutServerMtime(base::Time value); + void PutServerCtime(base::Time value); + bool PutId(const Id& value); + void PutServerParentId(const Id& value); + bool PutIsUnsynced(bool value); + bool PutIsUnappliedUpdate(bool value); + void PutServerIsDir(bool value); + void PutServerIsDel(bool value); + void PutServerNonUniqueName(const std::string& value); + bool PutUniqueServerTag(const std::string& value); + bool PutUniqueClientTag(const std::string& value); + void PutUniqueBookmarkTag(const std::string& tag); + void PutServerSpecifics(const sync_pb::EntitySpecifics& value); + void PutBaseServerSpecifics(const sync_pb::EntitySpecifics& value); + void PutServerUniquePosition(const UniquePosition& value); + void PutSyncing(bool value); + + // Do a simple property-only update of the PARENT_ID field. Use with caution. + // + // The normal Put(IS_PARENT) call will move the item to the front of the + // sibling order to maintain the linked list invariants when the parent + // changes. That's usually what you want to do, but it's inappropriate + // when the caller is trying to change the parent ID of a the whole set + // of children (e.g. because the ID changed during a commit). For those + // cases, there's this function. It will corrupt the sibling ordering + // if you're not careful. + void PutParentIdPropertyOnly(const Id& parent_id); + + // This is similar to what one would expect from Put(TRANSACTION_VERSION), + // except that it doesn't bother to invoke 'SaveOriginals'. Calling that + // function is at best unnecessary, since the transaction will have already + // used its list of mutations by the time this function is called. + void UpdateTransactionVersion(int64 version); + + protected: + explicit ModelNeutralMutableEntry(WriteTransaction* trans); + + syncable::MetahandleSet* GetDirtyIndexHelper(); + + private: + friend class syncer::WriteNode; + friend class Directory; + + // Don't allow creation on heap, except by sync API wrappers. + void* operator new(size_t size) { return (::operator new)(size); } + + // Kind of redundant. We should reduce the number of pointers + // floating around if at all possible. Could we store this in Directory? + // Scope: Set on construction, never changed after that. + WriteTransaction* const write_transaction_; + + DISALLOW_COPY_AND_ASSIGN(ModelNeutralMutableEntry); +}; + +} // namespace syncable +} // namespace syncer + +#endif // SYNC_SYNCABLE_MODEL_NEUTRAL_MUTABLE_ENTRY_H_ diff --git a/sync/syncable/mutable_entry.cc b/sync/syncable/mutable_entry.cc index 0c160c27dd..6dcf4841e6 100644 --- a/sync/syncable/mutable_entry.cc +++ b/sync/syncable/mutable_entry.cc @@ -59,8 +59,7 @@ MutableEntry::MutableEntry(WriteTransaction* trans, ModelType model_type, const Id& parent_id, const string& name) - : Entry(trans), - write_transaction_(trans) { + : ModelNeutralMutableEntry(trans) { Init(trans, model_type, parent_id, name); // We need to have a valid position ready before we can index the item. if (model_type == BOOKMARKS) { @@ -79,7 +78,7 @@ MutableEntry::MutableEntry(WriteTransaction* trans, MutableEntry::MutableEntry(WriteTransaction* trans, CreateNewUpdateItem, const Id& id) - : Entry(trans), write_transaction_(trans) { + : ModelNeutralMutableEntry(trans) { Entry same_id(trans, GET_BY_ID, id); kernel_ = NULL; if (same_id.good()) { @@ -102,46 +101,27 @@ MutableEntry::MutableEntry(WriteTransaction* trans, CreateNewUpdateItem, } MutableEntry::MutableEntry(WriteTransaction* trans, GetById, const Id& id) - : Entry(trans, GET_BY_ID, id), write_transaction_(trans) { + : ModelNeutralMutableEntry(trans, GET_BY_ID, id) { } MutableEntry::MutableEntry(WriteTransaction* trans, GetByHandle, int64 metahandle) - : Entry(trans, GET_BY_HANDLE, metahandle), write_transaction_(trans) { + : ModelNeutralMutableEntry(trans, GET_BY_HANDLE, metahandle) { } MutableEntry::MutableEntry(WriteTransaction* trans, GetByClientTag, const std::string& tag) - : Entry(trans, GET_BY_CLIENT_TAG, tag), write_transaction_(trans) { + : ModelNeutralMutableEntry(trans, GET_BY_CLIENT_TAG, tag) { } MutableEntry::MutableEntry(WriteTransaction* trans, GetByServerTag, const string& tag) - : Entry(trans, GET_BY_SERVER_TAG, tag), write_transaction_(trans) { -} - -void MutableEntry::PutBaseVersion(int64 value) { - DCHECK(kernel_); - write_transaction_->SaveOriginal(kernel_); - if (kernel_->ref(BASE_VERSION) != value) { - kernel_->put(BASE_VERSION, value); - kernel_->mark_dirty(&dir()->kernel_->dirty_metahandles); - } -} - -void MutableEntry::PutServerVersion(int64 value) { - DCHECK(kernel_); - write_transaction_->SaveOriginal(kernel_); - if (kernel_->ref(SERVER_VERSION) != value) { - ScopedKernelLock lock(dir()); - kernel_->put(SERVER_VERSION, value); - kernel_->mark_dirty(&dir()->kernel_->dirty_metahandles); - } + : ModelNeutralMutableEntry(trans, GET_BY_SERVER_TAG, tag) { } void MutableEntry::PutLocalExternalId(int64 value) { DCHECK(kernel_); - write_transaction_->SaveOriginal(kernel_); + write_transaction()->SaveOriginal(kernel_); if (kernel_->ref(LOCAL_EXTERNAL_ID) != value) { ScopedKernelLock lock(dir()); kernel_->put(LOCAL_EXTERNAL_ID, value); @@ -151,54 +131,25 @@ void MutableEntry::PutLocalExternalId(int64 value) { void MutableEntry::PutMtime(base::Time value) { DCHECK(kernel_); - write_transaction_->SaveOriginal(kernel_); + write_transaction()->SaveOriginal(kernel_); if (kernel_->ref(MTIME) != value) { kernel_->put(MTIME, value); kernel_->mark_dirty(&dir()->kernel_->dirty_metahandles); } } -void MutableEntry::PutServerMtime(base::Time value) { - DCHECK(kernel_); - write_transaction_->SaveOriginal(kernel_); - if (kernel_->ref(SERVER_MTIME) != value) { - kernel_->put(SERVER_MTIME, value); - kernel_->mark_dirty(&dir()->kernel_->dirty_metahandles); - } -} - void MutableEntry::PutCtime(base::Time value) { DCHECK(kernel_); - write_transaction_->SaveOriginal(kernel_); + write_transaction()->SaveOriginal(kernel_); if (kernel_->ref(CTIME) != value) { kernel_->put(CTIME, value); kernel_->mark_dirty(&dir()->kernel_->dirty_metahandles); } } -void MutableEntry::PutServerCtime(base::Time value) { - DCHECK(kernel_); - write_transaction_->SaveOriginal(kernel_); - if (kernel_->ref(SERVER_CTIME) != value) { - kernel_->put(SERVER_CTIME, value); - kernel_->mark_dirty(&dir()->kernel_->dirty_metahandles); - } -} - -bool MutableEntry::PutId(const Id& value) { - DCHECK(kernel_); - write_transaction_->SaveOriginal(kernel_); - if (kernel_->ref(ID) != value) { - if (!dir()->ReindexId(write_transaction(), kernel_, value)) - return false; - kernel_->mark_dirty(&dir()->kernel_->dirty_metahandles); - } - return true; -} - void MutableEntry::PutParentId(const Id& value) { DCHECK(kernel_); - write_transaction_->SaveOriginal(kernel_); + write_transaction()->SaveOriginal(kernel_); if (kernel_->ref(PARENT_ID) != value) { PutParentIdPropertyOnly(value); if (!GetIsDel()) { @@ -210,79 +161,9 @@ void MutableEntry::PutParentId(const Id& value) { } } -void MutableEntry::PutServerParentId(const Id& value) { - DCHECK(kernel_); - write_transaction_->SaveOriginal(kernel_); - - if (kernel_->ref(SERVER_PARENT_ID) != value) { - kernel_->put(SERVER_PARENT_ID, value); - kernel_->mark_dirty(&dir()->kernel_->dirty_metahandles); - } -} - -bool MutableEntry::PutIsUnsynced(bool value) { - DCHECK(kernel_); - write_transaction_->SaveOriginal(kernel_); - if (kernel_->ref(IS_UNSYNCED) != value) { - MetahandleSet* index = &dir()->kernel_->unsynced_metahandles; - - ScopedKernelLock lock(dir()); - if (value) { - if (!SyncAssert(index->insert(kernel_->ref(META_HANDLE)).second, - FROM_HERE, - "Could not insert", - write_transaction())) { - return false; - } - } else { - if (!SyncAssert(1U == index->erase(kernel_->ref(META_HANDLE)), - FROM_HERE, - "Entry Not succesfully erased", - write_transaction())) { - return false; - } - } - kernel_->put(IS_UNSYNCED, value); - kernel_->mark_dirty(&dir()->kernel_->dirty_metahandles); - } - return true; -} - -bool MutableEntry::PutIsUnappliedUpdate(bool value) { - DCHECK(kernel_); - write_transaction_->SaveOriginal(kernel_); - if (kernel_->ref(IS_UNAPPLIED_UPDATE) != value) { - // Use kernel_->GetServerModelType() instead of - // GetServerModelType() as we may trigger some DCHECKs in the - // latter. - MetahandleSet* index = &dir()->kernel_->unapplied_update_metahandles[ - kernel_->GetServerModelType()]; - - ScopedKernelLock lock(dir()); - if (value) { - if (!SyncAssert(index->insert(kernel_->ref(META_HANDLE)).second, - FROM_HERE, - "Could not insert", - write_transaction())) { - return false; - } - } else { - if (!SyncAssert(1U == index->erase(kernel_->ref(META_HANDLE)), - FROM_HERE, - "Entry Not succesfully erased", - write_transaction())) { - return false; - } - } - kernel_->put(IS_UNAPPLIED_UPDATE, value); - kernel_->mark_dirty(&dir()->kernel_->dirty_metahandles); - } - return true; -} - void MutableEntry::PutIsDir(bool value) { DCHECK(kernel_); - write_transaction_->SaveOriginal(kernel_); + write_transaction()->SaveOriginal(kernel_); bool old_value = kernel_->ref(IS_DIR); if (old_value != value) { kernel_->put(IS_DIR, value); @@ -290,19 +171,9 @@ void MutableEntry::PutIsDir(bool value) { } } -void MutableEntry::PutServerIsDir(bool value) { - DCHECK(kernel_); - write_transaction_->SaveOriginal(kernel_); - bool old_value = kernel_->ref(SERVER_IS_DIR); - if (old_value != value) { - kernel_->put(SERVER_IS_DIR, value); - kernel_->mark_dirty(GetDirtyIndexHelper()); - } -} - void MutableEntry::PutIsDel(bool value) { DCHECK(kernel_); - write_transaction_->SaveOriginal(kernel_); + write_transaction()->SaveOriginal(kernel_); if (value == kernel_->ref(IS_DEL)) { return; } @@ -332,27 +203,9 @@ void MutableEntry::PutIsDel(bool value) { } } -void MutableEntry::PutServerIsDel(bool value) { - DCHECK(kernel_); - write_transaction_->SaveOriginal(kernel_); - bool old_value = kernel_->ref(SERVER_IS_DEL); - if (old_value != value) { - kernel_->put(SERVER_IS_DEL, value); - kernel_->mark_dirty(GetDirtyIndexHelper()); - } - - // Update delete journal for existence status change on server side here - // instead of in PutIsDel() because IS_DEL may not be updated due to - // early returns when processing updates. And because - // UpdateDeleteJournalForServerDelete() checks for SERVER_IS_DEL, it has - // to be called on sync thread. - dir()->delete_journal()->UpdateDeleteJournalForServerDelete( - write_transaction(), old_value, *kernel_); -} - void MutableEntry::PutNonUniqueName(const std::string& value) { DCHECK(kernel_); - write_transaction_->SaveOriginal(kernel_); + write_transaction()->SaveOriginal(kernel_); if (kernel_->ref(NON_UNIQUE_NAME) != value) { kernel_->put(NON_UNIQUE_NAME, value); @@ -360,91 +213,10 @@ void MutableEntry::PutNonUniqueName(const std::string& value) { } } -void MutableEntry::PutServerNonUniqueName(const std::string& value) { - DCHECK(kernel_); - write_transaction_->SaveOriginal(kernel_); - - if (kernel_->ref(SERVER_NON_UNIQUE_NAME) != value) { - kernel_->put(SERVER_NON_UNIQUE_NAME, value); - kernel_->mark_dirty(&dir()->kernel_->dirty_metahandles); - } -} - -bool MutableEntry::PutUniqueServerTag(const string& new_tag) { - if (new_tag == kernel_->ref(UNIQUE_SERVER_TAG)) { - return true; - } - - write_transaction_->SaveOriginal(kernel_); - ScopedKernelLock lock(dir()); - // Make sure your new value is not in there already. - if (dir()->kernel_->server_tags_map.find(new_tag) != - dir()->kernel_->server_tags_map.end()) { - DVLOG(1) << "Detected duplicate server tag"; - return false; - } - dir()->kernel_->server_tags_map.erase( - kernel_->ref(UNIQUE_SERVER_TAG)); - kernel_->put(UNIQUE_SERVER_TAG, new_tag); - kernel_->mark_dirty(&dir()->kernel_->dirty_metahandles); - if (!new_tag.empty()) { - dir()->kernel_->server_tags_map[new_tag] = kernel_; - } - - return true; -} - -bool MutableEntry::PutUniqueClientTag(const string& new_tag) { - if (new_tag == kernel_->ref(UNIQUE_CLIENT_TAG)) { - return true; - } - - write_transaction_->SaveOriginal(kernel_); - ScopedKernelLock lock(dir()); - // Make sure your new value is not in there already. - if (dir()->kernel_->client_tags_map.find(new_tag) != - dir()->kernel_->client_tags_map.end()) { - DVLOG(1) << "Detected duplicate client tag"; - return false; - } - dir()->kernel_->client_tags_map.erase( - kernel_->ref(UNIQUE_CLIENT_TAG)); - kernel_->put(UNIQUE_CLIENT_TAG, new_tag); - kernel_->mark_dirty(&dir()->kernel_->dirty_metahandles); - if (!new_tag.empty()) { - dir()->kernel_->client_tags_map[new_tag] = kernel_; - } - - return true; -} - -void MutableEntry::PutUniqueBookmarkTag(const std::string& tag) { - // This unique tag will eventually be used as the unique suffix when adjusting - // this bookmark's position. Let's make sure it's a valid suffix. - if (!UniquePosition::IsValidSuffix(tag)) { - NOTREACHED(); - return; - } - - if (!kernel_->ref(UNIQUE_BOOKMARK_TAG).empty() && - tag != kernel_->ref(UNIQUE_BOOKMARK_TAG)) { - // There is only one scenario where our tag is expected to change. That - // scenario occurs when our current tag is a non-correct tag assigned during - // the UniquePosition migration. - std::string migration_generated_tag = - GenerateSyncableBookmarkHash(std::string(), - kernel_->ref(ID).GetServerId()); - DCHECK_EQ(migration_generated_tag, kernel_->ref(UNIQUE_BOOKMARK_TAG)); - } - - kernel_->put(UNIQUE_BOOKMARK_TAG, tag); - kernel_->mark_dirty(&dir()->kernel_->dirty_metahandles); -} - void MutableEntry::PutSpecifics(const sync_pb::EntitySpecifics& value) { DCHECK(kernel_); CHECK(!value.password().has_client_only_encrypted_data()); - write_transaction_->SaveOriginal(kernel_); + write_transaction()->SaveOriginal(kernel_); // TODO(ncarter): This is unfortunately heavyweight. Can we do // better? if (kernel_->ref(SPECIFICS).SerializeAsString() != @@ -454,56 +226,9 @@ void MutableEntry::PutSpecifics(const sync_pb::EntitySpecifics& value) { } } -void MutableEntry::PutServerSpecifics(const sync_pb::EntitySpecifics& value) { - DCHECK(kernel_); - CHECK(!value.password().has_client_only_encrypted_data()); - write_transaction_->SaveOriginal(kernel_); - // TODO(ncarter): This is unfortunately heavyweight. Can we do - // better? - if (kernel_->ref(SERVER_SPECIFICS).SerializeAsString() != - value.SerializeAsString()) { - if (kernel_->ref(IS_UNAPPLIED_UPDATE)) { - // Remove ourselves from unapplied_update_metahandles with our - // old server type. - const ModelType old_server_type = kernel_->GetServerModelType(); - const int64 metahandle = kernel_->ref(META_HANDLE); - size_t erase_count = - dir()->kernel_->unapplied_update_metahandles[old_server_type] - .erase(metahandle); - DCHECK_EQ(erase_count, 1u); - } - - kernel_->put(SERVER_SPECIFICS, value); - kernel_->mark_dirty(&dir()->kernel_->dirty_metahandles); - - if (kernel_->ref(IS_UNAPPLIED_UPDATE)) { - // Add ourselves back into unapplied_update_metahandles with our - // new server type. - const ModelType new_server_type = kernel_->GetServerModelType(); - const int64 metahandle = kernel_->ref(META_HANDLE); - dir()->kernel_->unapplied_update_metahandles[new_server_type] - .insert(metahandle); - } - } -} - -void MutableEntry::PutBaseServerSpecifics( - const sync_pb::EntitySpecifics& value) { - DCHECK(kernel_); - CHECK(!value.password().has_client_only_encrypted_data()); - write_transaction_->SaveOriginal(kernel_); - // TODO(ncarter): This is unfortunately heavyweight. Can we do - // better? - if (kernel_->ref(BASE_SERVER_SPECIFICS).SerializeAsString() - != value.SerializeAsString()) { - kernel_->put(BASE_SERVER_SPECIFICS, value); - kernel_->mark_dirty(&dir()->kernel_->dirty_metahandles); - } -} - void MutableEntry::PutUniquePosition(const UniquePosition& value) { DCHECK(kernel_); - write_transaction_->SaveOriginal(kernel_); + write_transaction()->SaveOriginal(kernel_); if(!kernel_->ref(UNIQUE_POSITION).Equals(value)) { // We should never overwrite a valid position with an invalid one. DCHECK(value.IsValid()); @@ -515,46 +240,14 @@ void MutableEntry::PutUniquePosition(const UniquePosition& value) { } } -void MutableEntry::PutServerUniquePosition(const UniquePosition& value) { - DCHECK(kernel_); - write_transaction_->SaveOriginal(kernel_); - if(!kernel_->ref(SERVER_UNIQUE_POSITION).Equals(value)) { - // We should never overwrite a valid position with an invalid one. - DCHECK(value.IsValid()); - ScopedKernelLock lock(dir()); - kernel_->put(SERVER_UNIQUE_POSITION, value); - kernel_->mark_dirty(&dir()->kernel_->dirty_metahandles); - } -} - -void MutableEntry::PutSyncing(bool value) { - kernel_->put(SYNCING, value); -} - -void MutableEntry::PutParentIdPropertyOnly(const Id& parent_id) { - write_transaction_->SaveOriginal(kernel_); - dir()->ReindexParentId(write_transaction(), kernel_, parent_id); - kernel_->mark_dirty(&dir()->kernel_->dirty_metahandles); -} - -MetahandleSet* MutableEntry::GetDirtyIndexHelper() { - return &dir()->kernel_->dirty_metahandles; -} - bool MutableEntry::PutPredecessor(const Id& predecessor_id) { - MutableEntry predecessor(write_transaction_, GET_BY_ID, predecessor_id); + MutableEntry predecessor(write_transaction(), GET_BY_ID, predecessor_id); if (!predecessor.good()) return false; dir()->PutPredecessor(kernel_, predecessor.kernel_); return true; } -void MutableEntry::UpdateTransactionVersion(int64 value) { - ScopedKernelLock lock(dir()); - kernel_->put(TRANSACTION_VERSION, value); - kernel_->mark_dirty(&(dir()->kernel_->dirty_metahandles)); -} - // This function sets only the flags needed to get this entry to sync. bool MarkForSyncing(MutableEntry* e) { DCHECK_NE(static_cast<MutableEntry*>(NULL), e); diff --git a/sync/syncable/mutable_entry.h b/sync/syncable/mutable_entry.h index 40079e17cc..f575c22f45 100644 --- a/sync/syncable/mutable_entry.h +++ b/sync/syncable/mutable_entry.h @@ -9,14 +9,13 @@ #include "sync/internal_api/public/base/model_type.h" #include "sync/syncable/entry.h" #include "sync/syncable/metahandle_set.h" +#include "sync/syncable/model_neutral_mutable_entry.h" namespace syncer { class WriteNode; namespace syncable { -class WriteTransaction; - enum Create { CREATE }; @@ -25,104 +24,40 @@ enum CreateNewUpdateItem { CREATE_NEW_UPDATE_ITEM }; +class WriteTransaction; + // A mutable meta entry. Changes get committed to the database when the // WriteTransaction is destroyed. -class SYNC_EXPORT_PRIVATE MutableEntry : public Entry { +class SYNC_EXPORT_PRIVATE MutableEntry : public ModelNeutralMutableEntry { void Init(WriteTransaction* trans, ModelType model_type, const Id& parent_id, const std::string& name); public: + MutableEntry(WriteTransaction* trans, CreateNewUpdateItem, const Id& id); MutableEntry(WriteTransaction* trans, Create, ModelType model_type, const Id& parent_id, const std::string& name); - MutableEntry(WriteTransaction* trans, CreateNewUpdateItem, const Id& id); MutableEntry(WriteTransaction* trans, GetByHandle, int64); MutableEntry(WriteTransaction* trans, GetById, const Id&); MutableEntry(WriteTransaction* trans, GetByClientTag, const std::string& tag); MutableEntry(WriteTransaction* trans, GetByServerTag, const std::string& tag); - inline WriteTransaction* write_transaction() const { - return write_transaction_; - } - - // Field Accessors. Some of them trigger the re-indexing of the entry. - // Return true on success, return false on failure, which means that putting - // the value would have caused a duplicate in the index. The setters that - // never fail return void. - void PutBaseVersion(int64 value); - void PutServerVersion(int64 value); + // Model-changing setters. These setters make user-visible changes that will + // need to be communicated either to the local model or the sync server. void PutLocalExternalId(int64 value); void PutMtime(base::Time value); - void PutServerMtime(base::Time value); void PutCtime(base::Time value); - void PutServerCtime(base::Time value); - bool PutId(const Id& value); void PutParentId(const Id& value); - void PutServerParentId(const Id& value); - bool PutIsUnsynced(bool value); - bool PutIsUnappliedUpdate(bool value); void PutIsDir(bool value); - void PutServerIsDir(bool value); void PutIsDel(bool value); - void PutServerIsDel(bool value); void PutNonUniqueName(const std::string& value); - void PutServerNonUniqueName(const std::string& value); - bool PutUniqueServerTag(const std::string& value); - bool PutUniqueClientTag(const std::string& value); - void PutUniqueBookmarkTag(const std::string& tag); void PutSpecifics(const sync_pb::EntitySpecifics& value); - void PutServerSpecifics(const sync_pb::EntitySpecifics& value); - void PutBaseServerSpecifics(const sync_pb::EntitySpecifics& value); void PutUniquePosition(const UniquePosition& value); - void PutServerUniquePosition(const UniquePosition& value); - void PutSyncing(bool value); - - // Do a simple property-only update if the PARENT_ID field. Use with caution. - // - // The normal Put(IS_PARENT) call will move the item to the front of the - // sibling order to maintain the linked list invariants when the parent - // changes. That's usually what you want to do, but it's inappropriate - // when the caller is trying to change the parent ID of a the whole set - // of children (e.g. because the ID changed during a commit). For those - // cases, there's this function. It will corrupt the sibling ordering - // if you're not careful. - void PutParentIdPropertyOnly(const Id& parent_id); // Sets the position of this item, and updates the entry kernels of the // adjacent siblings so that list invariants are maintained. Returns false // and fails if |predecessor_id| does not identify a sibling. Pass the root // ID to put the node in first position. bool PutPredecessor(const Id& predecessor_id); - - // This is similar to what one would expect from Put(TRANSACTION_VERSION), - // except that it doesn't bother to invoke 'SaveOriginals'. Calling that - // function is at best unnecessary, since the transaction will have already - // used its list of mutations by the time this function is called. - void UpdateTransactionVersion(int64 version); - - protected: - syncable::MetahandleSet* GetDirtyIndexHelper(); - - private: - friend class Directory; - friend class WriteTransaction; - friend class syncer::WriteNode; - - // Don't allow creation on heap, except by sync API wrappers. - void* operator new(size_t size) { return (::operator new)(size); } - - // Adjusts the successor and predecessor entries so that they no longer - // refer to this entry. - bool UnlinkFromOrder(); - - // Kind of redundant. We should reduce the number of pointers - // floating around if at all possible. Could we store this in Directory? - // Scope: Set on construction, never changed after that. - WriteTransaction* const write_transaction_; - - protected: - MutableEntry(); - - DISALLOW_COPY_AND_ASSIGN(MutableEntry); }; // This function sets only the flags needed to get this entry to sync. diff --git a/sync/tools/sync_client.cc b/sync/tools/sync_client.cc index 95c4211a43..436b342111 100644 --- a/sync/tools/sync_client.cc +++ b/sync/tools/sync_client.cc @@ -64,7 +64,6 @@ const char kXmppHostPortSwitch[] = "xmpp-host-port"; const char kXmppTrySslTcpFirstSwitch[] = "xmpp-try-ssltcp-first"; const char kXmppAllowInsecureConnectionSwitch[] = "xmpp-allow-insecure-connection"; -const char kNotificationMethodSwitch[] = "notification-method"; // Needed to use a real host resolver. class MyTestURLRequestContext : public net::TestURLRequestContext { diff --git a/sync/tools/sync_listen_notifications.cc b/sync/tools/sync_listen_notifications.cc index 9cebcee65b..b70ee6d57c 100644 --- a/sync/tools/sync_listen_notifications.cc +++ b/sync/tools/sync_listen_notifications.cc @@ -45,7 +45,6 @@ const char kTokenSwitch[] = "token"; const char kHostPortSwitch[] = "host-port"; const char kTrySslTcpFirstSwitch[] = "try-ssltcp-first"; const char kAllowInsecureConnectionSwitch[] = "allow-insecure-connection"; -const char kNotificationMethodSwitch[] = "notification-method"; // Class to print received notifications events. class NotificationPrinter : public InvalidationHandler { |