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

Side by Side Diff: chrome/browser/sync/engine/conflict_resolver.cc

Issue 2844037: Fix handling of undeletion within the syncer. (Closed) Base URL: http://src.chromium.org/git/chromium.git
Patch Set: Whitespace. Created 10 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2009 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/sync/engine/conflict_resolver.h" 5 #include "chrome/browser/sync/engine/conflict_resolver.h"
6 6
7 #include <map> 7 #include <map>
8 #include <set> 8 #include <set>
9 9
10 #include "chrome/browser/sync/engine/syncer.h" 10 #include "chrome/browser/sync/engine/syncer.h"
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
88 // we've both deleted it, so lets just drop the need to commit/update this 88 // we've both deleted it, so lets just drop the need to commit/update this
89 // entry. 89 // entry.
90 entry.Put(syncable::IS_UNSYNCED, false); 90 entry.Put(syncable::IS_UNSYNCED, false);
91 entry.Put(syncable::IS_UNAPPLIED_UPDATE, false); 91 entry.Put(syncable::IS_UNAPPLIED_UPDATE, false);
92 // we've made changes, but they won't help syncing progress. 92 // we've made changes, but they won't help syncing progress.
93 // METRIC simple conflict resolved by merge. 93 // METRIC simple conflict resolved by merge.
94 return NO_SYNC_PROGRESS; 94 return NO_SYNC_PROGRESS;
95 } 95 }
96 96
97 if (!entry.Get(syncable::SERVER_IS_DEL)) { 97 if (!entry.Get(syncable::SERVER_IS_DEL)) {
98 // TODO(chron): Should we check more fields? Since IS_UNSYNCED is 98 // This logic determines "client wins" vs. "server wins" strategy picking.
99 // turned on, this is really probably enough as fields will be overwritten. 99 // TODO(nick): The current logic is arbitrary; instead, it ought to be made
100 // Check if there's no changes. 100 // consistent with the ModelAssociator behavior for a datatype. It would
101 101 // be nice if we could route this back to ModelAssociator code to pick one
102 // Verbose but easier to debug. 102 // of three options: CLIENT, SERVER, or MERGE. Some datatypes (autofill)
103 // are easily mergeable.
103 bool name_matches = entry.Get(syncable::NON_UNIQUE_NAME) == 104 bool name_matches = entry.Get(syncable::NON_UNIQUE_NAME) ==
104 entry.Get(syncable::SERVER_NON_UNIQUE_NAME); 105 entry.Get(syncable::SERVER_NON_UNIQUE_NAME);
105 bool parent_matches = entry.Get(syncable::PARENT_ID) == 106 bool parent_matches = entry.Get(syncable::PARENT_ID) ==
106 entry.Get(syncable::SERVER_PARENT_ID); 107 entry.Get(syncable::SERVER_PARENT_ID);
107 bool entry_deleted = entry.Get(syncable::IS_DEL); 108 bool entry_deleted = entry.Get(syncable::IS_DEL);
108 109
109 if (!entry_deleted && name_matches && parent_matches) { 110 if (!entry_deleted && name_matches && parent_matches) {
110 LOG(INFO) << "Resolving simple conflict, ignoring local changes for:" 111 LOG(INFO) << "Resolving simple conflict, ignoring local changes for:"
111 << entry; 112 << entry;
112 IgnoreLocalChanges(&entry); 113 IgnoreLocalChanges(&entry);
(...skipping 10 matching lines...) Expand all
123 trans->directory()->GetChildHandles(trans, 124 trans->directory()->GetChildHandles(trans,
124 entry.Get(syncable::ID), 125 entry.Get(syncable::ID),
125 &children); 126 &children);
126 if (0 != children.size()) { 127 if (0 != children.size()) {
127 LOG(INFO) << "Entry is a server deleted directory with local contents, " 128 LOG(INFO) << "Entry is a server deleted directory with local contents, "
128 "should be in a set. (race condition)."; 129 "should be in a set. (race condition).";
129 return NO_SYNC_PROGRESS; 130 return NO_SYNC_PROGRESS;
130 } 131 }
131 } 132 }
132 133
133 // If the entry's deleted on the server, we can have a directory here. 134 // The entry is deleted on the server but still exists locally.
134 entry.Put(syncable::IS_UNSYNCED, true); 135 if (!entry.Get(syncable::UNIQUE_CLIENT_TAG).empty()) {
136 // If we've got a client-unique tag, we can undelete while retaining
137 // our present ID.
138 DCHECK_EQ(entry.Get(syncable::SERVER_VERSION), 0)
139 << "For the server to know to re-create, client-tagged items should "
140 << "revert to version 0 when server-deleted.";
141 OverwriteServerChanges(trans, &entry);
142 // Clobber the versions, just in case the above DCHECK is violated.
143 entry.Put(syncable::SERVER_VERSION, 0);
144 entry.Put(syncable::BASE_VERSION, 0);
145 } else {
146 // Otherwise, we've got to undelete by creating a new locally
147 // uncommitted entry.
148 SyncerUtil::SplitServerInformationIntoNewEntry(trans, &entry);
135 149
136 SyncerUtil::SplitServerInformationIntoNewEntry(trans, &entry); 150 MutableEntry server_update(trans, syncable::GET_BY_ID, id);
137 151 CHECK(server_update.good());
138 MutableEntry server_update(trans, syncable::GET_BY_ID, id); 152 CHECK(server_update.Get(syncable::META_HANDLE) !=
139 CHECK(server_update.good()); 153 entry.Get(syncable::META_HANDLE))
140 CHECK(server_update.Get(syncable::META_HANDLE) != 154 << server_update << entry;
141 entry.Get(syncable::META_HANDLE)) 155 }
142 << server_update << entry;
143
144 return SYNC_PROGRESS; 156 return SYNC_PROGRESS;
145 } 157 }
146 } 158 }
147 159
148 ConflictResolver::ConflictSetCountMapKey ConflictResolver::GetSetKey( 160 ConflictResolver::ConflictSetCountMapKey ConflictResolver::GetSetKey(
149 ConflictSet* set) { 161 ConflictSet* set) {
150 // TODO(sync): Come up with a better scheme for set hashing. This scheme 162 // TODO(sync): Come up with a better scheme for set hashing. This scheme
151 // will make debugging easy. 163 // will make debugging easy.
152 // If this call to sort is removed, we need to add one before we use 164 // If this call to sort is removed, we need to add one before we use
153 // binary_search in ProcessConflictSet. 165 // binary_search in ProcessConflictSet.
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after
238 SyncerUtil::ChangeEntryIDAndUpdateChildren(trans, &parent, 250 SyncerUtil::ChangeEntryIDAndUpdateChildren(trans, &parent,
239 trans->directory()->NextId()); 251 trans->directory()->NextId());
240 parent.Put(syncable::BASE_VERSION, 0); 252 parent.Put(syncable::BASE_VERSION, 0);
241 parent.Put(syncable::IS_UNSYNCED, true); 253 parent.Put(syncable::IS_UNSYNCED, true);
242 id = parent.Get(syncable::PARENT_ID); 254 id = parent.Get(syncable::PARENT_ID);
243 // METRIC conflict resolved by recreating dir tree. 255 // METRIC conflict resolved by recreating dir tree.
244 } 256 }
245 return true; 257 return true;
246 } 258 }
247 259
248
249 // TODO(chron): needs unit test badly 260 // TODO(chron): needs unit test badly
250 bool AttemptToFixUpdateEntryInDeletedLocalTree(WriteTransaction* trans, 261 bool AttemptToFixUpdateEntryInDeletedLocalTree(WriteTransaction* trans,
251 ConflictSet* conflict_set, 262 ConflictSet* conflict_set,
252 const Entry& entry) { 263 const Entry& entry) {
253 if (!entry.Get(syncable::IS_UNAPPLIED_UPDATE) || 264 if (!entry.Get(syncable::IS_UNAPPLIED_UPDATE) ||
254 entry.Get(syncable::SERVER_IS_DEL)) 265 entry.Get(syncable::SERVER_IS_DEL))
255 return false; 266 return false;
256 Id parent_id = entry.Get(syncable::SERVER_PARENT_ID); 267 Id parent_id = entry.Get(syncable::SERVER_PARENT_ID);
257 MutableEntry parent(trans, syncable::GET_BY_ID, parent_id); 268 MutableEntry parent(trans, syncable::GET_BY_ID, parent_id);
258 if (!parent.good() || !parent.Get(syncable::IS_DEL) || 269 if (!parent.good() || !parent.Get(syncable::IS_DEL) ||
(...skipping 241 matching lines...) Expand 10 before | Expand all | Expand 10 after
500 conflict_set_count_map_.erase(i++); 511 conflict_set_count_map_.erase(i++);
501 // METRIC self resolved conflict sets ++. 512 // METRIC self resolved conflict sets ++.
502 } else { 513 } else {
503 ++i; 514 ++i;
504 } 515 }
505 } 516 }
506 return rv; 517 return rv;
507 } 518 }
508 519
509 } // namespace browser_sync 520 } // namespace browser_sync
OLDNEW
« no previous file with comments | « chrome/browser/sync/engine/build_commit_command.cc ('k') | chrome/browser/sync/engine/download_updates_command.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698