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

Unified Diff: chrome/browser/sync/syncable/syncable.cc

Issue 8637006: [Sync] Make syncer commands avoid posting tasks on threads with no work to do (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Sync to head, fix windows compile Created 9 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « chrome/browser/sync/syncable/syncable.h ('k') | chrome/browser/sync/syncable/syncable_unittest.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: chrome/browser/sync/syncable/syncable.cc
diff --git a/chrome/browser/sync/syncable/syncable.cc b/chrome/browser/sync/syncable/syncable.cc
index 0050fbf56be7544841852ee4092d13b8fd967b7f..6a931f38f7cd4ed13d2cc4af13639db84d7bee4f 100644
--- a/chrome/browser/sync/syncable/syncable.cc
+++ b/chrome/browser/sync/syncable/syncable.cc
@@ -258,6 +258,20 @@ EntryKernel::EntryKernel() : dirty_(false) {
EntryKernel::~EntryKernel() {}
+syncable::ModelType EntryKernel::GetServerModelType() const {
+ ModelType specifics_type = GetModelTypeFromSpecifics(ref(SERVER_SPECIFICS));
+ if (specifics_type != UNSPECIFIED)
+ return specifics_type;
+ if (ref(ID).IsRoot())
+ return TOP_LEVEL_FOLDER;
+ // Loose check for server-created top-level folders that aren't
+ // bound to a particular model type.
+ if (!ref(UNIQUE_SERVER_TAG).empty() && ref(SERVER_IS_DIR))
+ return TOP_LEVEL_FOLDER;
+
+ return UNSPECIFIED;
+}
+
bool EntryKernel::ContainsString(const std::string& lowercase_query) const {
// TODO(lipalani) - figure out what to do if the node is encrypted.
const sync_pb::EntitySpecifics& specifics = ref(SPECIFICS);
@@ -328,6 +342,7 @@ StringValue* IdToValue(const Id& id) {
DictionaryValue* EntryKernel::ToValue() const {
DictionaryValue* kernel_info = new DictionaryValue();
kernel_info->SetBoolean("isDirty", is_dirty());
+ kernel_info->Set("serverModelType", ModelTypeToValue(GetServerModelType()));
// Int64 fields.
SetFieldValues(*this, kernel_info,
@@ -433,7 +448,6 @@ Directory::Kernel::Kernel(
ids_index(new Directory::IdsIndex),
parent_id_child_index(new Directory::ParentIdChildIndex),
client_tag_index(new Directory::ClientTagIndex),
- unapplied_update_metahandles(new MetahandleSet),
unsynced_metahandles(new MetahandleSet),
dirty_metahandles(new MetahandleSet),
metahandles_to_purge(new MetahandleSet),
@@ -459,7 +473,6 @@ void Directory::Kernel::Release() {
Directory::Kernel::~Kernel() {
CHECK_EQ(0, refcount);
delete unsynced_metahandles;
- delete unapplied_update_metahandles;
delete dirty_metahandles;
delete metahandles_to_purge;
delete parent_id_child_index;
@@ -496,10 +509,13 @@ void Directory::InitializeIndices() {
kernel_->parent_id_child_index);
InitializeIndexEntry<IdIndexer>(entry, kernel_->ids_index);
InitializeIndexEntry<ClientTagIndexer>(entry, kernel_->client_tag_index);
+ const int64 metahandle = entry->ref(META_HANDLE);
if (entry->ref(IS_UNSYNCED))
- kernel_->unsynced_metahandles->insert(entry->ref(META_HANDLE));
- if (entry->ref(IS_UNAPPLIED_UPDATE))
- kernel_->unapplied_update_metahandles->insert(entry->ref(META_HANDLE));
+ kernel_->unsynced_metahandles->insert(metahandle);
+ if (entry->ref(IS_UNAPPLIED_UPDATE)) {
+ const ModelType type = entry->GetServerModelType();
+ kernel_->unapplied_update_metahandles[type].insert(metahandle);
+ }
DCHECK(!entry->is_dirty());
}
}
@@ -702,11 +718,12 @@ bool Directory::SafeToPurgeFromMemory(const EntryKernel* const entry) const {
!entry->ref(IS_UNSYNCED);
if (safe) {
- int64 handle = entry->ref(META_HANDLE);
+ const int64 handle = entry->ref(META_HANDLE);
+ const ModelType type = entry->GetServerModelType();
CHECK_EQ(kernel_->dirty_metahandles->count(handle), 0U);
// TODO(tim): Bug 49278.
CHECK(!kernel_->unsynced_metahandles->count(handle));
- CHECK(!kernel_->unapplied_update_metahandles->count(handle));
+ CHECK(!kernel_->unapplied_update_metahandles[type].count(handle));
}
return safe;
@@ -837,7 +854,8 @@ void Directory::PurgeEntriesWithTypeIn(const std::set<ModelType>& types) {
DCHECK_EQ(entry->ref(UNIQUE_CLIENT_TAG).empty(), !num_erased);
num_erased = kernel_->unsynced_metahandles->erase(handle);
DCHECK_EQ(entry->ref(IS_UNSYNCED), num_erased > 0);
- num_erased = kernel_->unapplied_update_metahandles->erase(handle);
+ num_erased =
+ kernel_->unapplied_update_metahandles[server_type].erase(handle);
DCHECK_EQ(entry->ref(IS_UNAPPLIED_UPDATE), num_erased > 0);
num_erased = kernel_->parent_id_child_index->erase(entry);
DCHECK_EQ(entry->ref(IS_DEL), !num_erased);
@@ -1007,13 +1025,33 @@ int64 Directory::unsynced_entity_count() const {
return kernel_->unsynced_metahandles->size();
}
-void Directory::GetUnappliedUpdateMetaHandles(BaseTransaction* trans,
+syncable::ModelTypeBitSet
+ Directory::GetServerTypesWithUnappliedUpdates(
+ BaseTransaction* trans) const {
+ syncable::ModelTypeBitSet server_types;
+ ScopedKernelLock lock(this);
+ for (int i = 0; i < MODEL_TYPE_COUNT; ++i) {
+ if (!kernel_->unapplied_update_metahandles[i].empty()) {
+ server_types.set(i);
+ }
+ }
+ return server_types;
+}
+
+void Directory::GetUnappliedUpdateMetaHandles(
+ BaseTransaction* trans,
+ syncable::ModelTypeBitSet server_types,
UnappliedUpdateMetaHandles* result) {
result->clear();
ScopedKernelLock lock(this);
- copy(kernel_->unapplied_update_metahandles->begin(),
- kernel_->unapplied_update_metahandles->end(),
- back_inserter(*result));
+ for (int i = 0; i < MODEL_TYPE_COUNT; ++i) {
+ const ModelType type = ModelTypeFromInt(i);
+ if (server_types.test(type)) {
+ std::copy(kernel_->unapplied_update_metahandles[type].begin(),
+ kernel_->unapplied_update_metahandles[type].end(),
+ back_inserter(*result));
+ }
+ }
}
@@ -1370,8 +1408,6 @@ DictionaryValue* Entry::ToValue() const {
entry_info->SetBoolean("good", good());
if (good()) {
entry_info->Set("kernel", kernel_->ToValue());
- entry_info->Set("serverModelType",
- ModelTypeToValue(GetServerModelTypeHelper()));
entry_info->Set("modelType",
ModelTypeToValue(GetModelType()));
entry_info->SetBoolean("existsOnClientBecauseNameIsNonEmpty",
@@ -1387,7 +1423,7 @@ const string& Entry::Get(StringField field) const {
}
syncable::ModelType Entry::GetServerModelType() const {
- ModelType specifics_type = GetServerModelTypeHelper();
+ ModelType specifics_type = kernel_->GetServerModelType();
if (specifics_type != UNSPECIFIED)
return specifics_type;
@@ -1403,20 +1439,6 @@ syncable::ModelType Entry::GetServerModelType() const {
return UNSPECIFIED;
}
-syncable::ModelType Entry::GetServerModelTypeHelper() const {
- ModelType specifics_type = GetModelTypeFromSpecifics(Get(SERVER_SPECIFICS));
- if (specifics_type != UNSPECIFIED)
- return specifics_type;
- if (IsRoot())
- return TOP_LEVEL_FOLDER;
- // Loose check for server-created top-level folders that aren't
- // bound to a particular model type.
- if (!Get(UNIQUE_SERVER_TAG).empty() && Get(SERVER_IS_DIR))
- return TOP_LEVEL_FOLDER;
-
- return UNSPECIFIED;
-}
-
syncable::ModelType Entry::GetModelType() const {
ModelType specifics_type = GetModelTypeFromSpecifics(Get(SPECIFICS));
if (specifics_type != UNSPECIFIED)
@@ -1603,8 +1625,32 @@ bool MutableEntry::Put(ProtoField field,
// TODO(ncarter): This is unfortunately heavyweight. Can we do
// better?
if (kernel_->ref(field).SerializeAsString() != value.SerializeAsString()) {
+ const bool update_unapplied_updates_index =
+ (field == SERVER_SPECIFICS) && kernel_->ref(IS_UNAPPLIED_UPDATE);
+ if (update_unapplied_updates_index) {
+ // Remove ourselves from unapplied_update_metahandles with our
+ // old server type.
+ const syncable::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(field, value);
kernel_->mark_dirty(dir()->kernel_->dirty_metahandles);
+
+ if (update_unapplied_updates_index) {
+ // Add ourselves back into unapplied_update_metahandles with our
+ // new server type.
+ const syncable::ModelType new_server_type =
+ kernel_->GetServerModelType();
+ const int64 metahandle = kernel_->ref(META_HANDLE);
+ dir()->kernel_->unapplied_update_metahandles[new_server_type]
+ .insert(metahandle);
+ }
}
return true;
}
@@ -1667,10 +1713,16 @@ bool MutableEntry::Put(IndexedBitField field, bool value) {
DCHECK(kernel_);
if (kernel_->ref(field) != value) {
MetahandleSet* index;
- if (IS_UNSYNCED == field)
+ if (IS_UNSYNCED == field) {
index = dir()->kernel_->unsynced_metahandles;
- else
- index = dir()->kernel_->unapplied_update_metahandles;
+ } else {
+ // Use kernel_->GetServerModelType() instead of
+ // GetServerModelType() as we may trigger some DCHECKs in the
+ // latter.
+ index =
+ &dir()->kernel_->unapplied_update_metahandles[
+ kernel_->GetServerModelType()];
+ }
ScopedKernelLock lock(dir());
if (value)
« no previous file with comments | « chrome/browser/sync/syncable/syncable.h ('k') | chrome/browser/sync/syncable/syncable_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698