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

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

Issue 7042028: Detect & destroy dead conflictresolver paths. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 9 years, 7 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 | Annotate | Revision Log
« no previous file with comments | « chrome/browser/sync/engine/conflict_resolver.h ('k') | chrome/browser/sync/engine/syncer.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 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 <algorithm> 7 #include <algorithm>
8 #include <map> 8 #include <map>
9 #include <set> 9 #include <set>
10 10
11 #include "base/metrics/histogram.h"
11 #include "chrome/browser/sync/engine/syncer.h" 12 #include "chrome/browser/sync/engine/syncer.h"
12 #include "chrome/browser/sync/engine/syncer_util.h" 13 #include "chrome/browser/sync/engine/syncer_util.h"
13 #include "chrome/browser/sync/protocol/service_constants.h" 14 #include "chrome/browser/sync/protocol/service_constants.h"
14 #include "chrome/browser/sync/sessions/status_controller.h" 15 #include "chrome/browser/sync/sessions/status_controller.h"
15 #include "chrome/browser/sync/syncable/directory_manager.h" 16 #include "chrome/browser/sync/syncable/directory_manager.h"
16 #include "chrome/browser/sync/syncable/syncable.h" 17 #include "chrome/browser/sync/syncable/syncable.h"
17 #include "chrome/common/deprecated/event_sys-inl.h" 18 #include "chrome/common/deprecated/event_sys-inl.h"
18 19
19 using std::map; 20 using std::map;
20 using std::set; 21 using std::set;
(...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after
176 std::stringstream rv; 177 std::stringstream rv;
177 for (ConflictSet::iterator i = set->begin() ; i != set->end() ; ++i ) 178 for (ConflictSet::iterator i = set->begin() ; i != set->end() ; ++i )
178 rv << *i << "."; 179 rv << *i << ".";
179 return rv.str(); 180 return rv.str();
180 } 181 }
181 182
182 namespace { 183 namespace {
183 184
184 bool AttemptToFixCircularConflict(WriteTransaction* trans, 185 bool AttemptToFixCircularConflict(WriteTransaction* trans,
185 ConflictSet* conflict_set) { 186 ConflictSet* conflict_set) {
187 UMA_HISTOGRAM_COUNTS("Sync.ConflictFixCircularity", 1);
186 ConflictSet::const_iterator i, j; 188 ConflictSet::const_iterator i, j;
187 for (i = conflict_set->begin() ; i != conflict_set->end() ; ++i) { 189 for (i = conflict_set->begin() ; i != conflict_set->end() ; ++i) {
188 MutableEntry entryi(trans, syncable::GET_BY_ID, *i); 190 MutableEntry entryi(trans, syncable::GET_BY_ID, *i);
189 if (entryi.Get(syncable::PARENT_ID) == 191 if (entryi.Get(syncable::PARENT_ID) ==
190 entryi.Get(syncable::SERVER_PARENT_ID) || 192 entryi.Get(syncable::SERVER_PARENT_ID) ||
191 !entryi.Get(syncable::IS_UNAPPLIED_UPDATE) || 193 !entryi.Get(syncable::IS_UNAPPLIED_UPDATE) ||
192 !entryi.Get(syncable::IS_DIR)) { 194 !entryi.Get(syncable::IS_DIR)) {
193 continue; 195 continue;
194 } 196 }
195 Id parentid = entryi.Get(syncable::SERVER_PARENT_ID); 197 Id parentid = entryi.Get(syncable::SERVER_PARENT_ID);
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after
340 entry.Put(syncable::PARENT_ID, parent_id); 342 entry.Put(syncable::PARENT_ID, parent_id);
341 entry.Put(syncable::IS_DEL, false); 343 entry.Put(syncable::IS_DEL, false);
342 id = entry.Get(syncable::PARENT_ID); 344 id = entry.Get(syncable::PARENT_ID);
343 // METRIC conflict resolved by recreating dir tree. 345 // METRIC conflict resolved by recreating dir tree.
344 } 346 }
345 return true; 347 return true;
346 } 348 }
347 349
348 bool AttemptToFixRemovedDirectoriesWithContent(WriteTransaction* trans, 350 bool AttemptToFixRemovedDirectoriesWithContent(WriteTransaction* trans,
349 ConflictSet* conflict_set) { 351 ConflictSet* conflict_set) {
352 UMA_HISTOGRAM_COUNTS("Sync.ConflictFixRemovedDirectoriesWithContent", 1);
350 ConflictSet::const_iterator i, j; 353 ConflictSet::const_iterator i, j;
351 for (i = conflict_set->begin() ; i != conflict_set->end() ; ++i) { 354 for (i = conflict_set->begin() ; i != conflict_set->end() ; ++i) {
352 Entry entry(trans, syncable::GET_BY_ID, *i); 355 Entry entry(trans, syncable::GET_BY_ID, *i);
353 if (AttemptToFixUnsyncedEntryInDeletedServerTree(trans, 356 if (AttemptToFixUnsyncedEntryInDeletedServerTree(trans,
354 conflict_set, entry)) { 357 conflict_set, entry)) {
355 return true; 358 return true;
356 } 359 }
357 if (AttemptToFixUpdateEntryInDeletedLocalTree(trans, conflict_set, entry)) 360 if (AttemptToFixUpdateEntryInDeletedLocalTree(trans, conflict_set, entry))
358 return true; 361 return true;
359 } 362 }
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
412 << end - begin << " items:"; 415 << end - begin << " items:";
413 for (InputIt i = begin ; i != end ; ++i) { 416 for (InputIt i = begin ; i != end ; ++i) {
414 Entry e(trans, syncable::GET_BY_ID, *i); 417 Entry e(trans, syncable::GET_BY_ID, *i);
415 if (e.good()) 418 if (e.good())
416 LOG(ERROR) << " " << e; 419 LOG(ERROR) << " " << e;
417 else 420 else
418 LOG(ERROR) << " Bad ID:" << *i; 421 LOG(ERROR) << " Bad ID:" << *i;
419 } 422 }
420 423
421 status->set_syncer_stuck(true); 424 status->set_syncer_stuck(true);
425 UMA_HISTOGRAM_COUNTS("Sync.SyncerConflictStuck", 1);
422 426
423 return true; 427 return true;
424 // TODO(sync): If we're stuck for a while we need to alert the user, clear 428 // TODO(sync): If we're stuck for a while we need to alert the user, clear
425 // cache or reset syncing. At the very least we should stop trying something 429 // cache or reset syncing. At the very least we should stop trying something
426 // that's obviously not working. 430 // that's obviously not working.
427 } 431 }
428 432
429 bool ConflictResolver::ResolveSimpleConflicts(const ScopedDirLookup& dir, 433 bool ConflictResolver::ResolveSimpleConflicts(const ScopedDirLookup& dir,
430 StatusController* status) { 434 StatusController* status) {
431 WriteTransaction trans(dir, syncable::SYNCER, __FILE__, __LINE__); 435 WriteTransaction trans(dir, syncable::SYNCER, __FILE__, __LINE__);
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
467 return forward_progress; 471 return forward_progress;
468 } 472 }
469 473
470 bool ConflictResolver::ResolveConflicts(const ScopedDirLookup& dir, 474 bool ConflictResolver::ResolveConflicts(const ScopedDirLookup& dir,
471 StatusController* status) { 475 StatusController* status) {
472 const ConflictProgress& progress = status->conflict_progress(); 476 const ConflictProgress& progress = status->conflict_progress();
473 bool rv = false; 477 bool rv = false;
474 if (ResolveSimpleConflicts(dir, status)) 478 if (ResolveSimpleConflicts(dir, status))
475 rv = true; 479 rv = true;
476 WriteTransaction trans(dir, syncable::SYNCER, __FILE__, __LINE__); 480 WriteTransaction trans(dir, syncable::SYNCER, __FILE__, __LINE__);
477 set<Id> children_of_dirs_merged_last_round;
478 std::swap(children_of_merged_dirs_, children_of_dirs_merged_last_round);
479 set<ConflictSet*>::const_iterator set_it; 481 set<ConflictSet*>::const_iterator set_it;
480 for (set_it = progress.ConflictSetsBegin(); 482 for (set_it = progress.ConflictSetsBegin();
481 set_it != progress.ConflictSetsEnd(); 483 set_it != progress.ConflictSetsEnd();
482 set_it++) { 484 set_it++) {
483 ConflictSet* conflict_set = *set_it; 485 ConflictSet* conflict_set = *set_it;
484 ConflictSetCountMapKey key = GetSetKey(conflict_set); 486 ConflictSetCountMapKey key = GetSetKey(conflict_set);
485 conflict_set_count_map_[key] += 2; 487 conflict_set_count_map_[key] += 2;
486 int conflict_count = conflict_set_count_map_[key]; 488 int conflict_count = conflict_set_count_map_[key];
487 // Keep a metric for new sets. 489 // Keep a metric for new sets.
488 if (2 == conflict_count) { 490 if (2 == conflict_count) {
489 // METRIC conflict sets seen ++ 491 // METRIC conflict sets seen ++
490 } 492 }
491 // See if this set contains entries whose parents were merged last round.
492 if (SortedCollectionsIntersect(children_of_dirs_merged_last_round.begin(),
493 children_of_dirs_merged_last_round.end(),
494 conflict_set->begin(),
495 conflict_set->end())) {
496 VLOG(1) << "Accelerating resolution for hierarchical merge.";
497 conflict_count += 2;
498 }
499 // See if we should process this set. 493 // See if we should process this set.
500 if (ProcessConflictSet(&trans, conflict_set, conflict_count)) { 494 if (ProcessConflictSet(&trans, conflict_set, conflict_count)) {
501 rv = true; 495 rv = true;
502 } 496 }
503 LogAndSignalIfConflictStuck(&trans, conflict_count, 497 LogAndSignalIfConflictStuck(&trans, conflict_count,
504 conflict_set->begin(), 498 conflict_set->begin(),
505 conflict_set->end(), status); 499 conflict_set->end(), status);
506 } 500 }
507 if (rv) { 501 if (rv) {
508 // This code means we don't signal that syncing is stuck when any conflict 502 // This code means we don't signal that syncing is stuck when any conflict
(...skipping 10 matching lines...) Expand all
519 conflict_set_count_map_.erase(i++); 513 conflict_set_count_map_.erase(i++);
520 // METRIC self resolved conflict sets ++. 514 // METRIC self resolved conflict sets ++.
521 } else { 515 } else {
522 ++i; 516 ++i;
523 } 517 }
524 } 518 }
525 return rv; 519 return rv;
526 } 520 }
527 521
528 } // namespace browser_sync 522 } // namespace browser_sync
OLDNEW
« no previous file with comments | « chrome/browser/sync/engine/conflict_resolver.h ('k') | chrome/browser/sync/engine/syncer.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698