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

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

Issue 11192071: sync: Merge apply updates and resolve conflicts (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 8 years, 2 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
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/apply_updates_command.h" 5 #include "sync/engine/apply_updates_command.h"
6 6
7 #include "base/location.h" 7 #include "base/location.h"
8 #include "sync/engine/conflict_resolver.h"
8 #include "sync/engine/update_applicator.h" 9 #include "sync/engine/update_applicator.h"
9 #include "sync/sessions/sync_session.h" 10 #include "sync/sessions/sync_session.h"
10 #include "sync/syncable/directory.h" 11 #include "sync/syncable/directory.h"
11 #include "sync/syncable/read_transaction.h" 12 #include "sync/syncable/read_transaction.h"
12 #include "sync/syncable/write_transaction.h" 13 #include "sync/syncable/write_transaction.h"
13 14
14 namespace syncer { 15 namespace syncer {
15 16
16 using sessions::SyncSession; 17 using sessions::SyncSession;
17 18
(...skipping 16 matching lines...) Expand all
34 server_types_with_unapplied_updates.First(); it.Good(); it.Inc()) { 35 server_types_with_unapplied_updates.First(); it.Good(); it.Inc()) {
35 groups_with_unapplied_updates.insert( 36 groups_with_unapplied_updates.insert(
36 GetGroupForModelType(it.Get(), session.routing_info())); 37 GetGroupForModelType(it.Get(), session.routing_info()));
37 } 38 }
38 39
39 return groups_with_unapplied_updates; 40 return groups_with_unapplied_updates;
40 } 41 }
41 42
42 SyncerError ApplyUpdatesCommand::ModelChangingExecuteImpl( 43 SyncerError ApplyUpdatesCommand::ModelChangingExecuteImpl(
43 SyncSession* session) { 44 SyncSession* session) {
45 sessions::StatusController* status = session->mutable_status_controller();
44 syncable::Directory* dir = session->context()->directory(); 46 syncable::Directory* dir = session->context()->directory();
45 syncable::WriteTransaction trans(FROM_HERE, syncable::SYNCER, dir); 47 syncable::WriteTransaction trans(FROM_HERE, syncable::SYNCER, dir);
46 48
47 // Compute server types with unapplied updates that fall under our 49 // Compute server types with unapplied updates that fall under our
48 // group restriction. 50 // group restriction.
49 const FullModelTypeSet server_types_with_unapplied_updates = 51 const FullModelTypeSet server_types_with_unapplied_updates =
50 dir->GetServerTypesWithUnappliedUpdates(&trans); 52 dir->GetServerTypesWithUnappliedUpdates(&trans);
51 FullModelTypeSet server_type_restriction; 53 FullModelTypeSet server_type_restriction;
52 for (FullModelTypeSet::Iterator it = 54 for (FullModelTypeSet::Iterator it =
53 server_types_with_unapplied_updates.First(); it.Good(); it.Inc()) { 55 server_types_with_unapplied_updates.First(); it.Good(); it.Inc()) {
54 if (GetGroupForModelType(it.Get(), session->routing_info()) == 56 if (GetGroupForModelType(it.Get(), session->routing_info()) ==
55 session->status_controller().group_restriction()) { 57 status->group_restriction()) {
56 server_type_restriction.Put(it.Get()); 58 server_type_restriction.Put(it.Get());
57 } 59 }
58 } 60 }
59 61
60 // Don't process control type updates here. They will be handled elsewhere. 62 // Don't process control type updates here. They will be handled elsewhere.
61 FullModelTypeSet control_types = ToFullModelTypeSet(ControlTypes()); 63 FullModelTypeSet control_types = ToFullModelTypeSet(ControlTypes());
62 server_type_restriction.RemoveAll(control_types); 64 server_type_restriction.RemoveAll(control_types);
63 65
64 std::vector<int64> handles; 66 std::vector<int64> handles;
65 dir->GetUnappliedUpdateMetaHandles( 67 dir->GetUnappliedUpdateMetaHandles(
66 &trans, server_type_restriction, &handles); 68 &trans, server_type_restriction, &handles);
67 69
70 // First set of update application passes.
68 UpdateApplicator applicator( 71 UpdateApplicator applicator(
69 dir->GetCryptographer(&trans), 72 dir->GetCryptographer(&trans),
70 session->routing_info(), 73 session->routing_info(),
71 session->status_controller().group_restriction()); 74 status->group_restriction());
72 applicator.AttemptApplications(&trans, handles, 75 applicator.AttemptApplications(&trans, handles);
73 session->mutable_status_controller()); 76 status->increment_num_updates_applied_by(applicator.updates_applied());
77 status->increment_num_hierarchy_conflicts_by(
78 applicator.hierarchy_conflicts());
79 status->increment_num_encryption_conflicts_by(
80 applicator.encryption_conflicts());
81
82 if (applicator.simple_conflict_ids().size() != 0) {
83 // Resolve the simple conflicts we just detected.
tim (not reviewing) 2012/10/24 20:29:08 In the interest of writing short and simple functi
rlarocque 2012/10/24 21:21:22 It looks big, but there's very little code in here
tim (not reviewing) 2012/10/24 22:34:24 Fair enough. Note though based on several readabil
84 ConflictResolver resolver;
85 resolver.ResolveConflicts(&trans,
86 dir->GetCryptographer(&trans),
87 applicator.simple_conflict_ids(),
88 status);
89
90 // Conflict resolution sometimes results in more updates to apply.
91 handles.clear();
92 dir->GetUnappliedUpdateMetaHandles(
93 &trans, server_type_restriction, &handles);
94
95 UpdateApplicator conflict_applicator(
96 dir->GetCryptographer(&trans),
97 session->routing_info(),
98 status->group_restriction());
99 conflict_applicator.AttemptApplications(&trans, handles);
100
101 // We count the number of updates from both applicator passes.
102 status->increment_num_updates_applied_by(
103 conflict_applicator.updates_applied());
104
105 // Encryption conflicts should remain unchanged by the resolution of simple
106 // conflicts. Those can only be solved by updating our nigori key bag.
107 DCHECK_EQ(conflict_applicator.encryption_conflicts(),
108 applicator.encryption_conflicts());
109
110 // Hierarchy conflicts should also remain unchanged, for reasons that are
111 // more subtle. Hierarchy conflicts exist when the application of a pending
112 // update from the server would make the local folder hierarchy
113 // inconsistent. The resolution of simple conflicts could never affect the
114 // hierarchy conflicting item directly, because hierarchy conflicts are not
115 // processed by the conflict resolver. It could, in theory, modify the
116 // local hierarchy on which hierarchy conflict detection depends. However,
117 // the conflict resolution algorithm currently in use does not allow this.
118 DCHECK_EQ(conflict_applicator.hierarchy_conflicts(),
119 applicator.hierarchy_conflicts());
120
121 // There should be no simple conflicts remaining. We know this because the
122 // resolver should have resolved all the conflicts we detected last time
123 // and, by the two previous assertions, that no conflicts have been
124 // downgraded from encryption or hierarchy down to simple.
125 DCHECK(conflict_applicator.simple_conflict_ids().empty());
126 }
74 127
75 // This might be the first time we've fully completed a sync cycle, for 128 // This might be the first time we've fully completed a sync cycle, for
76 // some subset of the currently synced datatypes. 129 // some subset of the currently synced datatypes.
77 const sessions::StatusController& status(session->status_controller()); 130 if (status->ServerSaysNothingMoreToDownload()) {
78 if (status.ServerSaysNothingMoreToDownload()) {
79 for (ModelTypeSet::Iterator it = 131 for (ModelTypeSet::Iterator it =
80 status.updates_request_types().First(); it.Good(); it.Inc()) { 132 status->updates_request_types().First(); it.Good(); it.Inc()) {
81 // Don't set the flag for control types. We didn't process them here. 133 // Don't set the flag for control types. We didn't process them here.
82 if (IsControlType(it.Get())) 134 if (IsControlType(it.Get()))
83 continue; 135 continue;
84 136
85 // This gets persisted to the directory's backing store. 137 // This gets persisted to the directory's backing store.
86 dir->set_initial_sync_ended_for_type(it.Get(), true); 138 dir->set_initial_sync_ended_for_type(it.Get(), true);
87 } 139 }
88 } 140 }
89 141
90 return SYNCER_OK; 142 return SYNCER_OK;
91 } 143 }
92 144
93 } // namespace syncer 145 } // namespace syncer
OLDNEW
« no previous file with comments | « no previous file | sync/engine/apply_updates_command_unittest.cc » ('j') | sync/engine/conflict_resolver.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698