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

Side by Side Diff: sync/engine/update_applicator.cc

Issue 11192071: sync: Merge apply updates and resolve conflicts (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Retry (base files were missing) Created 8 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
« no previous file with comments | « sync/engine/update_applicator.h ('k') | sync/internal_api/debug_info_event_listener.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) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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 "sync/engine/update_applicator.h" 5 #include "sync/engine/update_applicator.h"
6 6
7 #include <vector> 7 #include <vector>
8 8
9 #include "base/logging.h" 9 #include "base/logging.h"
10 #include "sync/engine/syncer_util.h" 10 #include "sync/engine/syncer_util.h"
11 #include "sync/sessions/session_state.h"
12 #include "sync/syncable/entry.h" 11 #include "sync/syncable/entry.h"
13 #include "sync/syncable/mutable_entry.h" 12 #include "sync/syncable/mutable_entry.h"
14 #include "sync/syncable/syncable_id.h" 13 #include "sync/syncable/syncable_id.h"
15 #include "sync/syncable/write_transaction.h" 14 #include "sync/syncable/write_transaction.h"
16 15
17 using std::vector; 16 using std::vector;
18 17
19 namespace syncer { 18 namespace syncer {
20 19
21 using syncable::ID; 20 using syncable::ID;
22 21
23 UpdateApplicator::UpdateApplicator(Cryptographer* cryptographer, 22 UpdateApplicator::UpdateApplicator(Cryptographer* cryptographer,
24 const ModelSafeRoutingInfo& routes, 23 const ModelSafeRoutingInfo& routes,
25 ModelSafeGroup group_filter) 24 ModelSafeGroup group_filter)
26 : cryptographer_(cryptographer), 25 : cryptographer_(cryptographer),
27 group_filter_(group_filter), 26 group_filter_(group_filter),
28 routing_info_(routes) { 27 routing_info_(routes),
28 updates_applied_(0),
29 encryption_conflicts_(0),
30 hierarchy_conflicts_(0) {
29 } 31 }
30 32
31 UpdateApplicator::~UpdateApplicator() { 33 UpdateApplicator::~UpdateApplicator() {
32 } 34 }
33 35
34 // Attempt to apply all updates, using multiple passes if necessary. 36 // Attempt to apply all updates, using multiple passes if necessary.
35 // 37 //
36 // Some updates must be applied in order. For example, children must be created 38 // Some updates must be applied in order. For example, children must be created
37 // after their parent folder is created. This function runs an O(n^2) algorithm 39 // after their parent folder is created. This function runs an O(n^2) algorithm
38 // that will keep trying until there is nothing left to apply, or it stops 40 // that will keep trying until there is nothing left to apply, or it stops
39 // making progress, which would indicate that the hierarchy is invalid. 41 // making progress, which would indicate that the hierarchy is invalid.
40 // 42 //
41 // The update applicator also has to deal with simple conflicts, which occur 43 // The update applicator also has to deal with simple conflicts, which occur
42 // when an item is modified on both the server and the local model, and 44 // when an item is modified on both the server and the local model. We remember
43 // encryption conflicts. There's not much we can do about them here, so we 45 // their IDs so they can be passed to the conflict resolver after all the other
44 // don't bother re-processing them on subsequent passes. 46 // applications are complete.
47 //
48 // Finally, there are encryption conflicts, which can occur when we don't have
49 // access to all the Nigori keys. There's nothing we can do about them here.
45 void UpdateApplicator::AttemptApplications( 50 void UpdateApplicator::AttemptApplications(
46 syncable::WriteTransaction* trans, 51 syncable::WriteTransaction* trans,
47 const std::vector<int64>& handles, 52 const std::vector<int64>& handles) {
48 sessions::StatusController* status) {
49 std::vector<int64> to_apply = handles; 53 std::vector<int64> to_apply = handles;
50 std::set<syncable::Id>* simple_conflict_ids =
51 status->mutable_simple_conflict_ids();
52 54
53 DVLOG(1) << "UpdateApplicator running over " << to_apply.size() << " items."; 55 DVLOG(1) << "UpdateApplicator running over " << to_apply.size() << " items.";
54 while (!to_apply.empty()) { 56 while (!to_apply.empty()) {
55 std::vector<int64> to_reapply; 57 std::vector<int64> to_reapply;
56 58
57 for (UpdateIterator i = to_apply.begin(); i != to_apply.end(); ++i) { 59 for (std::vector<int64>::iterator i = to_apply.begin();
60 i != to_apply.end(); ++i) {
58 syncable::Entry read_entry(trans, syncable::GET_BY_HANDLE, *i); 61 syncable::Entry read_entry(trans, syncable::GET_BY_HANDLE, *i);
59 if (SkipUpdate(read_entry)) { 62 if (SkipUpdate(read_entry)) {
60 continue; 63 continue;
61 } 64 }
62 65
63 syncable::MutableEntry entry(trans, syncable::GET_BY_HANDLE, *i); 66 syncable::MutableEntry entry(trans, syncable::GET_BY_HANDLE, *i);
64 UpdateAttemptResponse result = AttemptToUpdateEntry( 67 UpdateAttemptResponse result = AttemptToUpdateEntry(
65 trans, &entry, cryptographer_); 68 trans, &entry, cryptographer_);
66 69
67 switch (result) { 70 switch (result) {
68 case SUCCESS: 71 case SUCCESS:
69 status->increment_num_updates_applied(); 72 updates_applied_++;
70 break; 73 break;
71 case CONFLICT_SIMPLE: 74 case CONFLICT_SIMPLE:
72 simple_conflict_ids->insert(entry.Get(ID)); 75 simple_conflict_ids_.insert(entry.Get(ID));
73 break; 76 break;
74 case CONFLICT_ENCRYPTION: 77 case CONFLICT_ENCRYPTION:
75 status->increment_num_encryption_conflicts(); 78 encryption_conflicts_++;
76 break; 79 break;
77 case CONFLICT_HIERARCHY: 80 case CONFLICT_HIERARCHY:
78 // The decision to classify these as hierarchy conflcits is tentative. 81 // The decision to classify these as hierarchy conflcits is tentative.
79 // If we make any progress this round, we'll clear the hierarchy 82 // If we make any progress this round, we'll clear the hierarchy
80 // conflict count and attempt to reapply these updates. 83 // conflict count and attempt to reapply these updates.
81 to_reapply.push_back(*i); 84 to_reapply.push_back(*i);
82 break; 85 break;
83 default: 86 default:
84 NOTREACHED(); 87 NOTREACHED();
85 break; 88 break;
86 } 89 }
87 } 90 }
88 91
89 if (to_reapply.size() == to_apply.size()) { 92 if (to_reapply.size() == to_apply.size()) {
90 // We made no progress. Must be stubborn hierarchy conflicts. 93 // We made no progress. Must be stubborn hierarchy conflicts.
91 status->set_num_hierarchy_conflicts(to_apply.size()); 94 hierarchy_conflicts_ = to_apply.size();
92 break; 95 break;
93 } 96 }
94 97
95 // We made some progress, so prepare for what might be another iteration. 98 // We made some progress, so prepare for what might be another iteration.
96 // If everything went well, to_reapply will be empty and we'll break out on 99 // If everything went well, to_reapply will be empty and we'll break out on
97 // the while condition. 100 // the while condition.
98 to_apply.swap(to_reapply); 101 to_apply.swap(to_reapply);
99 to_reapply.clear(); 102 to_reapply.clear();
100 } 103 }
101 } 104 }
(...skipping 11 matching lines...) Expand all
113 !routing_info_.count(type) && 116 !routing_info_.count(type) &&
114 type != UNSPECIFIED && 117 type != UNSPECIFIED &&
115 type != TOP_LEVEL_FOLDER) { 118 type != TOP_LEVEL_FOLDER) {
116 DVLOG(1) << "Skipping update application, type not permitted."; 119 DVLOG(1) << "Skipping update application, type not permitted.";
117 return true; 120 return true;
118 } 121 }
119 return false; 122 return false;
120 } 123 }
121 124
122 } // namespace syncer 125 } // namespace syncer
OLDNEW
« no previous file with comments | « sync/engine/update_applicator.h ('k') | sync/internal_api/debug_info_event_listener.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698