Index: chrome/browser/sync/engine/conflict_resolver.cc |
diff --git a/chrome/browser/sync/engine/conflict_resolver.cc b/chrome/browser/sync/engine/conflict_resolver.cc |
index a262ff72614945654b61bc009e2f5254ae40ba18..426310095652c4946f97cf101223548106faf753 100644 |
--- a/chrome/browser/sync/engine/conflict_resolver.cc |
+++ b/chrome/browser/sync/engine/conflict_resolver.cc |
@@ -77,21 +77,12 @@ ConflictResolver::ProcessSimpleConflict(WriteTransaction* trans, |
MutableEntry entry(trans, syncable::GET_BY_ID, id); |
// Must be good as the entry won't have been cleaned up. |
CHECK(entry.good()); |
- // If an update fails, locally we have to be in a set or unsynced. We're not |
- // in a set here, so we must be unsynced. |
- if (!entry.Get(syncable::IS_UNSYNCED)) { |
- return NO_SYNC_PROGRESS; |
- } |
- if (!entry.Get(syncable::IS_UNAPPLIED_UPDATE)) { |
- if (!entry.Get(syncable::PARENT_ID).ServerKnows()) { |
- DVLOG(1) << "Item conflicting because its parent not yet committed. Id: " |
- << id; |
- } else { |
- DVLOG(1) << "No set for conflicting entry id " << id << ". There should " |
- << "be an update/commit that will fix this soon. This message " |
- << "should not repeat."; |
- } |
+ // This function can only resolve simple conflicts. Simple conflicts are |
+ // both UNSYNCED and UNAPPLIED_UDPATEs. |
Nicolas Zea
2012/02/02 21:53:41
are both -> have both IS_UNSYNCED and IS_UNAPPLIED
rlarocque
2012/02/03 22:31:15
Done.
|
+ if (!entry.Get(syncable::IS_UNAPPLIED_UPDATE) || |
+ !entry.Get(syncable::IS_UNSYNCED)) { |
+ NOTREACHED(); |
return NO_SYNC_PROGRESS; |
} |
@@ -313,7 +304,10 @@ ConflictResolver::ProcessSimpleConflict(WriteTransaction* trans, |
entry.Put(syncable::BASE_SERVER_SPECIFICS, sync_pb::EntitySpecifics()); |
return SYNC_PROGRESS; |
} else { // SERVER_IS_DEL is true |
- // If a server deleted folder has local contents we should be in a set. |
+ // If a server deleted folder has local contents it should be a hierarchy |
+ // conflict. Hierarchy conflicts should not be processed by this function. |
+ // We could end up here if a change was made since we last tried to detect |
+ // conflicts, which was during update application. |
if (entry.Get(syncable::IS_DIR)) { |
Directory::ChildHandles children; |
trans->directory()->GetChildHandlesById(trans, |
@@ -321,7 +315,7 @@ ConflictResolver::ProcessSimpleConflict(WriteTransaction* trans, |
&children); |
if (0 != children.size()) { |
DVLOG(1) << "Entry is a server deleted directory with local contents, " |
- << "should be in a set. (race condition)."; |
+ << "should be a hierarchy conflict. (race condition)."; |
return NO_SYNC_PROGRESS; |
} |
} |
@@ -361,79 +355,53 @@ ConflictResolver::ProcessSimpleConflict(WriteTransaction* trans, |
} |
} |
-bool ConflictResolver::ResolveSimpleConflicts( |
- syncable::WriteTransaction* trans, |
- const Cryptographer* cryptographer, |
- const ConflictProgress& progress, |
- sessions::StatusController* status) { |
+bool ConflictResolver::ResolveConflicts(syncable::WriteTransaction* trans, |
+ const Cryptographer* cryptographer, |
+ const ConflictProgress& progress, |
+ sessions::StatusController* status) { |
bool forward_progress = false; |
- // First iterate over simple conflict items (those that belong to no set). |
+ // Iterate over simple conflict items. |
set<Id>::const_iterator conflicting_item_it; |
set<Id> processed_items; |
- for (conflicting_item_it = progress.ConflictingItemsBegin(); |
- conflicting_item_it != progress.ConflictingItemsEnd(); |
+ for (conflicting_item_it = progress.SimpleConflictingItemsBegin(); |
+ conflicting_item_it != progress.SimpleConflictingItemsEnd(); |
++conflicting_item_it) { |
Id id = *conflicting_item_it; |
if (processed_items.count(id) > 0) |
continue; |
- map<Id, ConflictSet*>::const_iterator item_set_it = |
- progress.IdToConflictSetFind(id); |
- if (item_set_it == progress.IdToConflictSetEnd() || |
- 0 == item_set_it->second) { |
- // We have a simple conflict. In order check if positions have changed, |
- // we need to process conflicting predecessors before successors. Traverse |
- // backwards through all continuous conflicting predecessors, building a |
- // stack of items to resolve in predecessor->successor order, then process |
- // each item individually. |
- list<Id> predecessors; |
- Id prev_id = id; |
- do { |
- predecessors.push_back(prev_id); |
- Entry entry(trans, syncable::GET_BY_ID, prev_id); |
- // Any entry in conflict must be valid. |
- CHECK(entry.good()); |
- Id new_prev_id = entry.Get(syncable::PREV_ID); |
- if (new_prev_id == prev_id) |
+ |
+ // We have a simple conflict. In order check if positions have changed, |
+ // we need to process conflicting predecessors before successors. Traverse |
+ // backwards through all continuous conflicting predecessors, building a |
+ // stack of items to resolve in predecessor->successor order, then process |
+ // each item individually. |
+ list<Id> predecessors; |
+ Id prev_id = id; |
+ do { |
+ predecessors.push_back(prev_id); |
+ Entry entry(trans, syncable::GET_BY_ID, prev_id); |
+ // Any entry in conflict must be valid. |
+ CHECK(entry.good()); |
+ Id new_prev_id = entry.Get(syncable::PREV_ID); |
+ if (new_prev_id == prev_id) |
+ break; |
+ prev_id = new_prev_id; |
+ } while (processed_items.count(prev_id) == 0 && |
+ progress.HasSimpleConflictItem(prev_id)); // Excludes root. |
+ while (!predecessors.empty()) { |
+ id = predecessors.back(); |
+ predecessors.pop_back(); |
+ switch (ProcessSimpleConflict(trans, id, cryptographer, status)) { |
+ case NO_SYNC_PROGRESS: |
+ break; |
+ case SYNC_PROGRESS: |
+ forward_progress = true; |
break; |
- prev_id = new_prev_id; |
- } while (processed_items.count(prev_id) == 0 && |
- progress.HasSimpleConflictItem(prev_id)); // Excludes root. |
- while (!predecessors.empty()) { |
- id = predecessors.back(); |
- predecessors.pop_back(); |
- switch (ProcessSimpleConflict(trans, id, cryptographer, status)) { |
- case NO_SYNC_PROGRESS: |
- break; |
- case SYNC_PROGRESS: |
- forward_progress = true; |
- break; |
- } |
- processed_items.insert(id); |
} |
+ processed_items.insert(id); |
} |
} |
return forward_progress; |
} |
-bool ConflictResolver::ResolveConflicts(syncable::WriteTransaction* trans, |
- const Cryptographer* cryptographer, |
- const ConflictProgress& progress, |
- sessions::StatusController* status) { |
- // TODO(rlarocque): A good amount of code related to the resolution of |
- // conflict sets has been deleted here. This was done because the code had |
- // not been used in years. An unrelated bug fix accidentally re-enabled the |
- // code, forcing us to make a decision about what we should do with the code. |
- // We decided to do the safe thing and delete it for now. This restores the |
- // behaviour we've relied on for quite some time. We should think about what |
- // that code was trying to do and consider re-enabling parts of it. |
- |
- if (progress.ConflictSetsSize() > 0) { |
- DVLOG(1) << "Detected " << progress.IdToConflictSetSize() |
- << " non-simple conflicting entries in " << progress.ConflictSetsSize() |
- << " unprocessed conflict sets."; |
- } |
- |
- return ResolveSimpleConflicts(trans, cryptographer, progress, status); |
-} |
- |
} // namespace browser_sync |