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

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

Issue 386030: Relieve SyncerSession,SyncCycleState, SyncProcessState, SyncerSession, Syncer... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 11 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2006-2009 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2006-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/build_and_process_conflict_sets_command.h" 5 #include "chrome/browser/sync/engine/build_and_process_conflict_sets_command.h"
6 6
7 #include <string> 7 #include <string>
8 #include <sstream> 8 #include <sstream>
9 #include <vector> 9 #include <vector>
10 10
11 #include "base/basictypes.h" 11 #include "base/basictypes.h"
12 #include "base/format_macros.h" 12 #include "base/format_macros.h"
13 #include "base/rand_util.h" 13 #include "base/rand_util.h"
14 #include "chrome/browser/sync/engine/conflict_resolution_view.h"
15 #include "chrome/browser/sync/engine/syncer_util.h" 14 #include "chrome/browser/sync/engine/syncer_util.h"
16 #include "chrome/browser/sync/engine/update_applicator.h" 15 #include "chrome/browser/sync/engine/update_applicator.h"
16 #include "chrome/browser/sync/sessions/sync_session.h"
17 #include "chrome/browser/sync/syncable/directory_manager.h" 17 #include "chrome/browser/sync/syncable/directory_manager.h"
18 18
19 namespace browser_sync { 19 namespace browser_sync {
20 20
21 using sessions::ConflictProgress;
22 using sessions::StatusController;
23 using sessions::SyncSession;
24 using sessions::UpdateProgress;
21 using std::set; 25 using std::set;
22 using std::string; 26 using std::string;
23 using std::vector; 27 using std::vector;
24 28
25 BuildAndProcessConflictSetsCommand::BuildAndProcessConflictSetsCommand() {} 29 BuildAndProcessConflictSetsCommand::BuildAndProcessConflictSetsCommand() {}
26 BuildAndProcessConflictSetsCommand::~BuildAndProcessConflictSetsCommand() {} 30 BuildAndProcessConflictSetsCommand::~BuildAndProcessConflictSetsCommand() {}
27 31
28 void BuildAndProcessConflictSetsCommand::ModelChangingExecuteImpl( 32 void BuildAndProcessConflictSetsCommand::ModelChangingExecuteImpl(
29 SyncerSession* session) { 33 SyncSession* session) {
30 session->set_conflict_sets_built(BuildAndProcessConflictSets(session)); 34 session->status_controller()->set_conflict_sets_built(
35 BuildAndProcessConflictSets(session));
31 } 36 }
32 37
33 bool BuildAndProcessConflictSetsCommand::BuildAndProcessConflictSets( 38 bool BuildAndProcessConflictSetsCommand::BuildAndProcessConflictSets(
34 SyncerSession* session) { 39 SyncSession* session) {
35 syncable::ScopedDirLookup dir(session->dirman(), session->account_name()); 40 syncable::ScopedDirLookup dir(session->context()->directory_manager(),
41 session->context()->account_name());
36 if (!dir.good()) 42 if (!dir.good())
37 return false; 43 return false;
38 bool had_single_direction_sets = false; 44 bool had_single_direction_sets = false;
39 { // Scope for transaction. 45 { // Scope for transaction.
40 syncable::WriteTransaction trans(dir, syncable::SYNCER, __FILE__, __LINE__); 46 syncable::WriteTransaction trans(dir, syncable::SYNCER, __FILE__, __LINE__);
41 ConflictResolutionView conflict_view(session); 47 BuildConflictSets(&trans,
42 BuildConflictSets(&trans, &conflict_view); 48 session->status_controller()->mutable_conflict_progress());
43 had_single_direction_sets = 49 had_single_direction_sets = ProcessSingleDirectionConflictSets(&trans,
44 ProcessSingleDirectionConflictSets(&trans, session); 50 session->context()->resolver(), session->status_controller());
45 // We applied some updates transactionally, lets try syncing again. 51 // We applied some updates transactionally, lets try syncing again.
46 if (had_single_direction_sets) 52 if (had_single_direction_sets)
47 return true; 53 return true;
48 } 54 }
49 return false; 55 return false;
50 } 56 }
51 57
52 bool BuildAndProcessConflictSetsCommand::ProcessSingleDirectionConflictSets( 58 bool BuildAndProcessConflictSetsCommand::ProcessSingleDirectionConflictSets(
53 syncable::WriteTransaction* trans, SyncerSession* const session) { 59 syncable::WriteTransaction* trans, ConflictResolver* resolver,
60 StatusController* status) {
54 bool rv = false; 61 bool rv = false;
55 ConflictResolutionView conflict_view(session);
56 set<ConflictSet*>::const_iterator all_sets_iterator; 62 set<ConflictSet*>::const_iterator all_sets_iterator;
57 for (all_sets_iterator = conflict_view.ConflictSetsBegin(); 63 for (all_sets_iterator = status->conflict_progress()->ConflictSetsBegin();
58 all_sets_iterator != conflict_view.ConflictSetsEnd(); ) { 64 all_sets_iterator != status->conflict_progress()->ConflictSetsEnd();) {
59 const ConflictSet* conflict_set = *all_sets_iterator; 65 const ConflictSet* conflict_set = *all_sets_iterator;
60 CHECK(conflict_set->size() >= 2); 66 CHECK(conflict_set->size() >= 2);
61 // We scan the set to see if it consists of changes of only one type. 67 // We scan the set to see if it consists of changes of only one type.
62 ConflictSet::const_iterator i; 68 ConflictSet::const_iterator i;
63 size_t unsynced_count = 0, unapplied_count = 0; 69 size_t unsynced_count = 0, unapplied_count = 0;
64 for (i = conflict_set->begin(); i != conflict_set->end(); ++i) { 70 for (i = conflict_set->begin(); i != conflict_set->end(); ++i) {
65 syncable::Entry entry(trans, syncable::GET_BY_ID, *i); 71 syncable::Entry entry(trans, syncable::GET_BY_ID, *i);
66 CHECK(entry.good()); 72 CHECK(entry.good());
67 if (entry.Get(syncable::IS_UNSYNCED)) 73 if (entry.Get(syncable::IS_UNSYNCED))
68 unsynced_count++; 74 unsynced_count++;
69 if (entry.Get(syncable::IS_UNAPPLIED_UPDATE)) 75 if (entry.Get(syncable::IS_UNAPPLIED_UPDATE))
70 unapplied_count++; 76 unapplied_count++;
71 } 77 }
72 if (conflict_set->size() == unsynced_count && 0 == unapplied_count) { 78 if (conflict_set->size() == unsynced_count && 0 == unapplied_count) {
73 LOG(INFO) << "Skipped transactional commit attempt."; 79 LOG(INFO) << "Skipped transactional commit attempt.";
74 } else if (conflict_set->size() == unapplied_count && 80 } else if (conflict_set->size() == unapplied_count && 0 == unsynced_count &&
75 0 == unsynced_count && 81 ApplyUpdatesTransactionally(trans, conflict_set, resolver, status)) {
76 ApplyUpdatesTransactionally(trans, conflict_set, session)) {
77 rv = true; 82 rv = true;
78 } 83 }
79 ++all_sets_iterator; 84 ++all_sets_iterator;
80 } 85 }
81 return rv; 86 return rv;
82 } 87 }
83 88
84 namespace { 89 namespace {
85 90
86 void StoreLocalDataForUpdateRollback(syncable::Entry* entry, 91 void StoreLocalDataForUpdateRollback(syncable::Entry* entry,
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
118 entry.Put(syncable::BASE_VERSION, backup->ref(syncable::BASE_VERSION)); 123 entry.Put(syncable::BASE_VERSION, backup->ref(syncable::BASE_VERSION));
119 entry.Put(syncable::IS_DIR, backup->ref(syncable::IS_DIR)); 124 entry.Put(syncable::IS_DIR, backup->ref(syncable::IS_DIR));
120 entry.Put(syncable::IS_DEL, backup->ref(syncable::IS_DEL)); 125 entry.Put(syncable::IS_DEL, backup->ref(syncable::IS_DEL));
121 entry.Put(syncable::ID, backup->ref(syncable::ID)); 126 entry.Put(syncable::ID, backup->ref(syncable::ID));
122 entry.Put(syncable::IS_UNAPPLIED_UPDATE, 127 entry.Put(syncable::IS_UNAPPLIED_UPDATE,
123 backup->ref(syncable::IS_UNAPPLIED_UPDATE)); 128 backup->ref(syncable::IS_UNAPPLIED_UPDATE));
124 return true; 129 return true;
125 } 130 }
126 131
127 void PlaceEntriesAtRoot(syncable::WriteTransaction* trans, 132 void PlaceEntriesAtRoot(syncable::WriteTransaction* trans,
128 const vector<syncable::Id>* ids) { 133 const vector<syncable::Id>* ids) {
129 vector<syncable::Id>::const_iterator it; 134 vector<syncable::Id>::const_iterator it;
130 for (it = ids->begin(); it != ids->end(); ++it) { 135 for (it = ids->begin(); it != ids->end(); ++it) {
131 syncable::MutableEntry entry(trans, syncable::GET_BY_ID, *it); 136 syncable::MutableEntry entry(trans, syncable::GET_BY_ID, *it);
132 entry.Put(syncable::PARENT_ID, trans->root_id()); 137 entry.Put(syncable::PARENT_ID, trans->root_id());
138 }
133 } 139 }
134 }
135 140
136 } // namespace 141 } // namespace
137 142
138 bool BuildAndProcessConflictSetsCommand::ApplyUpdatesTransactionally( 143 bool BuildAndProcessConflictSetsCommand::ApplyUpdatesTransactionally(
139 syncable::WriteTransaction* trans, 144 syncable::WriteTransaction* trans,
140 const vector<syncable::Id>* const update_set, 145 const vector<syncable::Id>* const update_set,
141 SyncerSession* const session) { 146 ConflictResolver* resolver, StatusController* status) {
142 // The handles in the |update_set| order. 147 // The handles in the |update_set| order.
143 vector<int64> handles; 148 vector<int64> handles;
144 149
145 // Holds the same Ids as update_set, but sorted so that runs of adjacent 150 // Holds the same Ids as update_set, but sorted so that runs of adjacent
146 // nodes appear in order. 151 // nodes appear in order.
147 vector<syncable::Id> rollback_ids; 152 vector<syncable::Id> rollback_ids;
148 rollback_ids.reserve(update_set->size()); 153 rollback_ids.reserve(update_set->size());
149 154
150 // Tracks what's added to |rollback_ids|. 155 // Tracks what's added to |rollback_ids|.
151 syncable::MetahandleSet rollback_ids_inserted_items; 156 syncable::MetahandleSet rollback_ids_inserted_items;
(...skipping 24 matching lines...) Expand all
176 181
177 // 4. Use the preparer to move things to an initial starting state where 182 // 4. Use the preparer to move things to an initial starting state where
178 // nothing in the set is a child of anything else. If 183 // nothing in the set is a child of anything else. If
179 // we've correctly calculated the set, the server tree is valid and no 184 // we've correctly calculated the set, the server tree is valid and no
180 // changes have occurred locally we should be able to apply updates from this 185 // changes have occurred locally we should be able to apply updates from this
181 // state. 186 // state.
182 PlaceEntriesAtRoot(trans, update_set); 187 PlaceEntriesAtRoot(trans, update_set);
183 188
184 // 5. Use the usual apply updates from the special start state we've just 189 // 5. Use the usual apply updates from the special start state we've just
185 // prepared. 190 // prepared.
186 UpdateApplicator applicator(session->resolver(), handles.begin(), 191 UpdateApplicator applicator(resolver, handles.begin(), handles.end());
187 handles.end());
188 while (applicator.AttemptOneApplication(trans)) { 192 while (applicator.AttemptOneApplication(trans)) {
189 // Keep going till all updates are applied. 193 // Keep going till all updates are applied.
190 } 194 }
191 if (!applicator.AllUpdatesApplied()) { 195 if (!applicator.AllUpdatesApplied()) {
192 LOG(ERROR) << "Transactional Apply Failed, Rolling back."; 196 LOG(ERROR) << "Transactional Apply Failed, Rolling back.";
193 // We have to move entries into the temp dir again. e.g. if a swap was in a 197 // We have to move entries into the temp dir again. e.g. if a swap was in a
194 // set with other failing updates, the swap may have gone through, meaning 198 // set with other failing updates, the swap may have gone through, meaning
195 // the roll back needs to be transactional. But as we're going to a known 199 // the roll back needs to be transactional. But as we're going to a known
196 // good state we should always succeed. 200 // good state we should always succeed.
197 PlaceEntriesAtRoot(trans, update_set); 201 PlaceEntriesAtRoot(trans, update_set);
198 202
199 // Rollback all entries. 203 // Rollback all entries.
200 for (size_t i = 0; i < rollback_data.size(); ++i) { 204 for (size_t i = 0; i < rollback_data.size(); ++i) {
201 CHECK(RollbackEntry(trans, &rollback_data[i])); 205 CHECK(RollbackEntry(trans, &rollback_data[i]));
202 } 206 }
203 return false; // Don't save progress -- we just undid it. 207 return false; // Don't save progress -- we just undid it.
204 } 208 }
205 applicator.SaveProgressIntoSessionState(session); 209 applicator.SaveProgressIntoSessionState(status->mutable_conflict_progress(),
210 status->mutable_update_progress());
206 return true; 211 return true;
207 } 212 }
208 213
209 void BuildAndProcessConflictSetsCommand::BuildConflictSets( 214 void BuildAndProcessConflictSetsCommand::BuildConflictSets(
210 syncable::BaseTransaction* trans, 215 syncable::BaseTransaction* trans,
211 ConflictResolutionView* view) { 216 ConflictProgress* conflict_progress) {
212 view->CleanupSets(); 217 conflict_progress->CleanupSets();
213 set<syncable::Id>::iterator i = view->CommitConflictsBegin(); 218 set<syncable::Id>::iterator i = conflict_progress->ConflictingItemsBegin();
214 while (i != view->CommitConflictsEnd()) { 219 while (i != conflict_progress->ConflictingItemsEnd()) {
215 syncable::Entry entry(trans, syncable::GET_BY_ID, *i); 220 syncable::Entry entry(trans, syncable::GET_BY_ID, *i);
216 CHECK(entry.good()); 221 CHECK(entry.good());
217 if (!entry.Get(syncable::IS_UNSYNCED) && 222 if (!entry.Get(syncable::IS_UNSYNCED) &&
218 !entry.Get(syncable::IS_UNAPPLIED_UPDATE)) { 223 !entry.Get(syncable::IS_UNAPPLIED_UPDATE)) {
219 // This can happen very rarely. It means we had a simply conflicting item 224 // This can happen very rarely. It means we had a simply conflicting item
220 // that randomly committed. We drop the entry as it's no longer 225 // that randomly committed. We drop the entry as it's no longer
221 // conflicting. 226 // conflicting.
222 view->EraseCommitConflict(i++); 227 conflict_progress->EraseConflictingItemById(*(i++));
223 continue; 228 continue;
224 } 229 }
225 if (entry.ExistsOnClientBecauseNameIsNonEmpty() && 230 if (entry.ExistsOnClientBecauseNameIsNonEmpty() &&
226 (entry.Get(syncable::IS_DEL) || entry.Get(syncable::SERVER_IS_DEL))) { 231 (entry.Get(syncable::IS_DEL) || entry.Get(syncable::SERVER_IS_DEL))) {
227 // If we're deleted on client or server we can't be in a complex set. 232 // If we're deleted on client or server we can't be in a complex set.
228 ++i; 233 ++i;
229 continue; 234 continue;
230 } 235 }
231 bool new_parent = 236 bool new_parent =
232 entry.Get(syncable::PARENT_ID) != entry.Get(syncable::SERVER_PARENT_ID); 237 entry.Get(syncable::PARENT_ID) != entry.Get(syncable::SERVER_PARENT_ID);
233 if (new_parent) 238 if (new_parent)
234 MergeSetsForIntroducedLoops(trans, &entry, view); 239 MergeSetsForIntroducedLoops(trans, &entry, conflict_progress);
235 MergeSetsForNonEmptyDirectories(trans, &entry, view); 240 MergeSetsForNonEmptyDirectories(trans, &entry, conflict_progress);
236 ++i; 241 ++i;
237 } 242 }
238 } 243 }
239 244
240 void BuildAndProcessConflictSetsCommand::MergeSetsForIntroducedLoops( 245 void BuildAndProcessConflictSetsCommand::MergeSetsForIntroducedLoops(
241 syncable::BaseTransaction* trans, syncable::Entry* entry, 246 syncable::BaseTransaction* trans, syncable::Entry* entry,
242 ConflictResolutionView* view) { 247 ConflictProgress* conflict_progress) {
243 // This code crawls up from the item in question until it gets to the root 248 // This code crawls up from the item in question until it gets to the root
244 // or itself. If it gets to the root it does nothing. If it finds a loop all 249 // or itself. If it gets to the root it does nothing. If it finds a loop all
245 // moved unsynced entries in the list of crawled entries have their sets 250 // moved unsynced entries in the list of crawled entries have their sets
246 // merged with the entry. 251 // merged with the entry.
247 // TODO(sync): Build test cases to cover this function when the argument list 252 // TODO(sync): Build test cases to cover this function when the argument list
248 // has settled. 253 // has settled.
249 syncable::Id parent_id = entry->Get(syncable::SERVER_PARENT_ID); 254 syncable::Id parent_id = entry->Get(syncable::SERVER_PARENT_ID);
250 syncable::Entry parent(trans, syncable::GET_BY_ID, parent_id); 255 syncable::Entry parent(trans, syncable::GET_BY_ID, parent_id);
251 if (!parent.good()) { 256 if (!parent.good()) {
252 return; 257 return;
(...skipping 13 matching lines...) Expand all
266 entry->Get(syncable::PARENT_ID) != 271 entry->Get(syncable::PARENT_ID) !=
267 entry->Get(syncable::SERVER_PARENT_ID)) 272 entry->Get(syncable::SERVER_PARENT_ID))
268 conflicting_entries.push_back(parent_id); 273 conflicting_entries.push_back(parent_id);
269 parent_id = parent.Get(syncable::PARENT_ID); 274 parent_id = parent.Get(syncable::PARENT_ID);
270 if (parent_id == entry->Get(syncable::ID)) 275 if (parent_id == entry->Get(syncable::ID))
271 break; 276 break;
272 } 277 }
273 if (parent_id.IsRoot()) 278 if (parent_id.IsRoot())
274 return; 279 return;
275 for (size_t i = 0; i < conflicting_entries.size(); i++) { 280 for (size_t i = 0; i < conflicting_entries.size(); i++) {
276 view->MergeSets(entry->Get(syncable::ID), conflicting_entries[i]); 281 conflict_progress->MergeSets(entry->Get(syncable::ID),
282 conflicting_entries[i]);
277 } 283 }
278 } 284 }
279 285
280 namespace { 286 namespace {
281 287
282 class ServerDeletedPathChecker { 288 class ServerDeletedPathChecker {
283 public: 289 public:
284 static bool CausingConflict(const syncable::Entry& e, 290 static bool CausingConflict(const syncable::Entry& e,
285 const syncable::Entry& log_entry) { 291 const syncable::Entry& log_entry) {
286 CHECK(e.good()) << "Missing parent in path of: " << log_entry; 292 CHECK(e.good()) << "Missing parent in path of: " << log_entry;
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
329 syncable::Id parent_id = parent.Get(syncable::PARENT_ID); 335 syncable::Id parent_id = parent.Get(syncable::PARENT_ID);
330 if (parent_id == check_id) 336 if (parent_id == check_id)
331 return syncable::kNullId; 337 return syncable::kNullId;
332 return parent_id; 338 return parent_id;
333 } 339 }
334 }; 340 };
335 341
336 template <typename Checker> 342 template <typename Checker>
337 void CrawlDeletedTreeMergingSets(syncable::BaseTransaction* trans, 343 void CrawlDeletedTreeMergingSets(syncable::BaseTransaction* trans,
338 const syncable::Entry& entry, 344 const syncable::Entry& entry,
339 ConflictResolutionView* view, 345 ConflictProgress* conflict_progress,
340 Checker checker) { 346 Checker checker) {
341 syncable::Id parent_id = entry.Get(syncable::PARENT_ID); 347 syncable::Id parent_id = entry.Get(syncable::PARENT_ID);
342 syncable::Id double_step_parent_id = parent_id; 348 syncable::Id double_step_parent_id = parent_id;
343 // This block builds sets where we've got an entry in a directory the server 349 // This block builds sets where we've got an entry in a directory the server
344 // wants to delete. 350 // wants to delete.
345 // 351 //
346 // Here we're walking up the tree to find all entries that the pass checks 352 // Here we're walking up the tree to find all entries that the pass checks
347 // deleted. We can be extremely strict here as anything unexpected means 353 // deleted. We can be extremely strict here as anything unexpected means
348 // invariants in the local hierarchy have been broken. 354 // invariants in the local hierarchy have been broken.
349 while (!parent_id.IsRoot()) { 355 while (!parent_id.IsRoot()) {
350 if (!double_step_parent_id.IsRoot()) { 356 if (!double_step_parent_id.IsRoot()) {
351 // Checks to ensure we don't loop. 357 // Checks to ensure we don't loop.
352 double_step_parent_id = checker.GetAndExamineParent( 358 double_step_parent_id = checker.GetAndExamineParent(
353 trans, double_step_parent_id, parent_id, entry); 359 trans, double_step_parent_id, parent_id, entry);
354 double_step_parent_id = checker.GetAndExamineParent( 360 double_step_parent_id = checker.GetAndExamineParent(
355 trans, double_step_parent_id, parent_id, entry); 361 trans, double_step_parent_id, parent_id, entry);
356 } 362 }
357 syncable::Entry parent(trans, syncable::GET_BY_ID, parent_id); 363 syncable::Entry parent(trans, syncable::GET_BY_ID, parent_id);
358 if (checker.CausingConflict(parent, entry)) 364 if (checker.CausingConflict(parent, entry)) {
359 view->MergeSets(entry.Get(syncable::ID), parent.Get(syncable::ID)); 365 conflict_progress->MergeSets(entry.Get(syncable::ID),
360 else 366 parent.Get(syncable::ID));
367 } else {
361 break; 368 break;
369 }
362 parent_id = parent.Get(syncable::PARENT_ID); 370 parent_id = parent.Get(syncable::PARENT_ID);
363 } 371 }
364 } 372 }
365 373
366 } // namespace 374 } // namespace
367 375
368 void BuildAndProcessConflictSetsCommand::MergeSetsForNonEmptyDirectories( 376 void BuildAndProcessConflictSetsCommand::MergeSetsForNonEmptyDirectories(
369 syncable::BaseTransaction* trans, syncable::Entry* entry, 377 syncable::BaseTransaction* trans, syncable::Entry* entry,
370 ConflictResolutionView* view) { 378 ConflictProgress* conflict_progress) {
371 if (entry->Get(syncable::IS_UNSYNCED) && !entry->Get(syncable::IS_DEL)) { 379 if (entry->Get(syncable::IS_UNSYNCED) && !entry->Get(syncable::IS_DEL)) {
372 ServerDeletedPathChecker checker; 380 ServerDeletedPathChecker checker;
373 CrawlDeletedTreeMergingSets(trans, *entry, view, checker); 381 CrawlDeletedTreeMergingSets(trans, *entry, conflict_progress, checker);
374 } 382 }
375 if (entry->Get(syncable::IS_UNAPPLIED_UPDATE) && 383 if (entry->Get(syncable::IS_UNAPPLIED_UPDATE) &&
376 !entry->Get(syncable::SERVER_IS_DEL)) { 384 !entry->Get(syncable::SERVER_IS_DEL)) {
377 syncable::Entry parent(trans, syncable::GET_BY_ID, 385 syncable::Entry parent(trans, syncable::GET_BY_ID,
378 entry->Get(syncable::SERVER_PARENT_ID)); 386 entry->Get(syncable::SERVER_PARENT_ID));
379 syncable::Id parent_id = entry->Get(syncable::SERVER_PARENT_ID); 387 syncable::Id parent_id = entry->Get(syncable::SERVER_PARENT_ID);
380 if (!parent.good()) 388 if (!parent.good())
381 return; 389 return;
382 LocallyDeletedPathChecker checker; 390 LocallyDeletedPathChecker checker;
383 if (!checker.CausingConflict(parent, *entry)) 391 if (!checker.CausingConflict(parent, *entry))
384 return; 392 return;
385 view->MergeSets(entry->Get(syncable::ID), parent.Get(syncable::ID)); 393 conflict_progress->MergeSets(entry->Get(syncable::ID),
386 CrawlDeletedTreeMergingSets(trans, parent, view, checker); 394 parent.Get(syncable::ID));
395 CrawlDeletedTreeMergingSets(trans, parent, conflict_progress, checker);
387 } 396 }
388 } 397 }
389 398
390 } // namespace browser_sync 399 } // namespace browser_sync
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698