OLD | NEW |
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 |
(...skipping 29 matching lines...) Expand all Loading... |
40 syncable::ScopedDirLookup dir(session->context()->directory_manager(), | 40 syncable::ScopedDirLookup dir(session->context()->directory_manager(), |
41 session->context()->account_name()); | 41 session->context()->account_name()); |
42 if (!dir.good()) | 42 if (!dir.good()) |
43 return false; | 43 return false; |
44 bool had_single_direction_sets = false; | 44 bool had_single_direction_sets = false; |
45 { // Scope for transaction. | 45 { // Scope for transaction. |
46 syncable::WriteTransaction trans(dir, syncable::SYNCER, __FILE__, __LINE__); | 46 syncable::WriteTransaction trans(dir, syncable::SYNCER, __FILE__, __LINE__); |
47 BuildConflictSets(&trans, | 47 BuildConflictSets(&trans, |
48 session->status_controller()->mutable_conflict_progress()); | 48 session->status_controller()->mutable_conflict_progress()); |
49 had_single_direction_sets = ProcessSingleDirectionConflictSets(&trans, | 49 had_single_direction_sets = ProcessSingleDirectionConflictSets(&trans, |
50 session->context()->resolver(), session->status_controller(), | 50 session->context()->resolver(), |
51 session->routing_info()); | 51 session->context()->directory_manager()->cryptographer(), |
| 52 session->status_controller(), session->routing_info()); |
52 // We applied some updates transactionally, lets try syncing again. | 53 // We applied some updates transactionally, lets try syncing again. |
53 if (had_single_direction_sets) | 54 if (had_single_direction_sets) |
54 return true; | 55 return true; |
55 } | 56 } |
56 return false; | 57 return false; |
57 } | 58 } |
58 | 59 |
59 bool BuildAndProcessConflictSetsCommand::ProcessSingleDirectionConflictSets( | 60 bool BuildAndProcessConflictSetsCommand::ProcessSingleDirectionConflictSets( |
60 syncable::WriteTransaction* trans, ConflictResolver* resolver, | 61 syncable::WriteTransaction* trans, ConflictResolver* resolver, |
61 StatusController* status, const ModelSafeRoutingInfo& routes) { | 62 Cryptographer* cryptographer, StatusController* status, |
| 63 const ModelSafeRoutingInfo& routes) { |
62 bool rv = false; | 64 bool rv = false; |
63 set<ConflictSet*>::const_iterator all_sets_iterator; | 65 set<ConflictSet*>::const_iterator all_sets_iterator; |
64 for (all_sets_iterator = status->conflict_progress().ConflictSetsBegin(); | 66 for (all_sets_iterator = status->conflict_progress().ConflictSetsBegin(); |
65 all_sets_iterator != status->conflict_progress().ConflictSetsEnd();) { | 67 all_sets_iterator != status->conflict_progress().ConflictSetsEnd();) { |
66 const ConflictSet* conflict_set = *all_sets_iterator; | 68 const ConflictSet* conflict_set = *all_sets_iterator; |
67 CHECK(conflict_set->size() >= 2); | 69 CHECK(conflict_set->size() >= 2); |
68 // We scan the set to see if it consists of changes of only one type. | 70 // We scan the set to see if it consists of changes of only one type. |
69 ConflictSet::const_iterator i; | 71 ConflictSet::const_iterator i; |
70 size_t unsynced_count = 0, unapplied_count = 0; | 72 size_t unsynced_count = 0, unapplied_count = 0; |
71 for (i = conflict_set->begin(); i != conflict_set->end(); ++i) { | 73 for (i = conflict_set->begin(); i != conflict_set->end(); ++i) { |
72 syncable::Entry entry(trans, syncable::GET_BY_ID, *i); | 74 syncable::Entry entry(trans, syncable::GET_BY_ID, *i); |
73 CHECK(entry.good()); | 75 CHECK(entry.good()); |
74 if (entry.Get(syncable::IS_UNSYNCED)) | 76 if (entry.Get(syncable::IS_UNSYNCED)) |
75 unsynced_count++; | 77 unsynced_count++; |
76 if (entry.Get(syncable::IS_UNAPPLIED_UPDATE)) | 78 if (entry.Get(syncable::IS_UNAPPLIED_UPDATE)) |
77 unapplied_count++; | 79 unapplied_count++; |
78 } | 80 } |
79 if (conflict_set->size() == unsynced_count && 0 == unapplied_count) { | 81 if (conflict_set->size() == unsynced_count && 0 == unapplied_count) { |
80 LOG(INFO) << "Skipped transactional commit attempt."; | 82 LOG(INFO) << "Skipped transactional commit attempt."; |
81 } else if (conflict_set->size() == unapplied_count && 0 == unsynced_count && | 83 } else if (conflict_set->size() == unapplied_count && 0 == unsynced_count && |
82 ApplyUpdatesTransactionally(trans, conflict_set, resolver, routes, | 84 ApplyUpdatesTransactionally(trans, conflict_set, resolver, |
83 status)) { | 85 cryptographer, routes, status)) { |
84 rv = true; | 86 rv = true; |
85 } | 87 } |
86 ++all_sets_iterator; | 88 ++all_sets_iterator; |
87 } | 89 } |
88 return rv; | 90 return rv; |
89 } | 91 } |
90 | 92 |
91 namespace { | 93 namespace { |
92 | 94 |
93 void StoreLocalDataForUpdateRollback(syncable::Entry* entry, | 95 void StoreLocalDataForUpdateRollback(syncable::Entry* entry, |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
139 entry.Put(syncable::PARENT_ID, trans->root_id()); | 141 entry.Put(syncable::PARENT_ID, trans->root_id()); |
140 } | 142 } |
141 } | 143 } |
142 | 144 |
143 } // namespace | 145 } // namespace |
144 | 146 |
145 bool BuildAndProcessConflictSetsCommand::ApplyUpdatesTransactionally( | 147 bool BuildAndProcessConflictSetsCommand::ApplyUpdatesTransactionally( |
146 syncable::WriteTransaction* trans, | 148 syncable::WriteTransaction* trans, |
147 const vector<syncable::Id>* const update_set, | 149 const vector<syncable::Id>* const update_set, |
148 ConflictResolver* resolver, | 150 ConflictResolver* resolver, |
| 151 Cryptographer* cryptographer, |
149 const ModelSafeRoutingInfo& routes, | 152 const ModelSafeRoutingInfo& routes, |
150 StatusController* status) { | 153 StatusController* status) { |
151 // The handles in the |update_set| order. | 154 // The handles in the |update_set| order. |
152 vector<int64> handles; | 155 vector<int64> handles; |
153 | 156 |
154 // Holds the same Ids as update_set, but sorted so that runs of adjacent | 157 // Holds the same Ids as update_set, but sorted so that runs of adjacent |
155 // nodes appear in order. | 158 // nodes appear in order. |
156 vector<syncable::Id> rollback_ids; | 159 vector<syncable::Id> rollback_ids; |
157 rollback_ids.reserve(update_set->size()); | 160 rollback_ids.reserve(update_set->size()); |
158 | 161 |
(...skipping 26 matching lines...) Expand all Loading... |
185 | 188 |
186 // 4. Use the preparer to move things to an initial starting state where | 189 // 4. Use the preparer to move things to an initial starting state where |
187 // nothing in the set is a child of anything else. If | 190 // nothing in the set is a child of anything else. If |
188 // we've correctly calculated the set, the server tree is valid and no | 191 // we've correctly calculated the set, the server tree is valid and no |
189 // changes have occurred locally we should be able to apply updates from this | 192 // changes have occurred locally we should be able to apply updates from this |
190 // state. | 193 // state. |
191 PlaceEntriesAtRoot(trans, update_set); | 194 PlaceEntriesAtRoot(trans, update_set); |
192 | 195 |
193 // 5. Use the usual apply updates from the special start state we've just | 196 // 5. Use the usual apply updates from the special start state we've just |
194 // prepared. | 197 // prepared. |
195 UpdateApplicator applicator(resolver, handles.begin(), handles.end(), | 198 UpdateApplicator applicator(resolver, cryptographer, |
196 routes, status->group_restriction()); | 199 handles.begin(), handles.end(), |
| 200 routes, status->group_restriction()); |
197 while (applicator.AttemptOneApplication(trans)) { | 201 while (applicator.AttemptOneApplication(trans)) { |
198 // Keep going till all updates are applied. | 202 // Keep going till all updates are applied. |
199 } | 203 } |
200 if (!applicator.AllUpdatesApplied()) { | 204 if (!applicator.AllUpdatesApplied()) { |
201 LOG(ERROR) << "Transactional Apply Failed, Rolling back."; | 205 LOG(ERROR) << "Transactional Apply Failed, Rolling back."; |
202 // We have to move entries into the temp dir again. e.g. if a swap was in a | 206 // We have to move entries into the temp dir again. e.g. if a swap was in a |
203 // set with other failing updates, the swap may have gone through, meaning | 207 // set with other failing updates, the swap may have gone through, meaning |
204 // the roll back needs to be transactional. But as we're going to a known | 208 // the roll back needs to be transactional. But as we're going to a known |
205 // good state we should always succeed. | 209 // good state we should always succeed. |
206 PlaceEntriesAtRoot(trans, update_set); | 210 PlaceEntriesAtRoot(trans, update_set); |
(...skipping 188 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
395 LocallyDeletedPathChecker checker; | 399 LocallyDeletedPathChecker checker; |
396 if (!checker.CausingConflict(parent, *entry)) | 400 if (!checker.CausingConflict(parent, *entry)) |
397 return; | 401 return; |
398 conflict_progress->MergeSets(entry->Get(syncable::ID), | 402 conflict_progress->MergeSets(entry->Get(syncable::ID), |
399 parent.Get(syncable::ID)); | 403 parent.Get(syncable::ID)); |
400 CrawlDeletedTreeMergingSets(trans, parent, conflict_progress, checker); | 404 CrawlDeletedTreeMergingSets(trans, parent, conflict_progress, checker); |
401 } | 405 } |
402 } | 406 } |
403 | 407 |
404 } // namespace browser_sync | 408 } // namespace browser_sync |
OLD | NEW |