summaryrefslogtreecommitdiff
path: root/sync
diff options
context:
space:
mode:
authorTorne (Richard Coles) <torne@google.com>2013-09-26 13:24:57 +0100
committerTorne (Richard Coles) <torne@google.com>2013-09-26 13:24:57 +0100
commit68043e1e95eeb07d5cae7aca370b26518b0867d6 (patch)
treecc6a216bce6aa9319a216327b73a07f49200dab5 /sync
parentcede44592cfb9ec370925d10c2df733349a94a82 (diff)
downloadchromium_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.java7
-rw-r--r--sync/engine/download_unittest.cc5
-rw-r--r--sync/engine/syncer_unittest.cc2
-rw-r--r--sync/internal_api/debug_info_event_listener.cc132
-rw-r--r--sync/internal_api/debug_info_event_listener.h6
-rw-r--r--sync/internal_api/public/data_type_debug_info_listener.h11
-rw-r--r--sync/internal_api/sync_manager_impl_unittest.cc2
-rw-r--r--sync/sessions/sync_session_context.cc3
-rw-r--r--sync/sync_core.gypi2
-rw-r--r--sync/syncable/directory.h1
-rw-r--r--sync/syncable/model_neutral_mutable_entry.cc355
-rw-r--r--sync/syncable/model_neutral_mutable_entry.h109
-rw-r--r--sync/syncable/mutable_entry.cc339
-rw-r--r--sync/syncable/mutable_entry.h79
-rw-r--r--sync/tools/sync_client.cc1
-rw-r--r--sync/tools/sync_listen_notifications.cc1
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 {