NaCl: Update revision in DEPS, r9066 -> r9086
[chromium-blink-merge.git] / sync / engine / update_applicator.cc
blob03ae08df7d8aef8e03fb4b1e335581ae7bea2358
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
3 // found in the LICENSE file.
5 #include "sync/engine/update_applicator.h"
7 #include <vector>
9 #include "base/logging.h"
10 #include "sync/engine/syncer_util.h"
11 #include "sync/sessions/session_state.h"
12 #include "sync/syncable/entry.h"
13 #include "sync/syncable/mutable_entry.h"
14 #include "sync/syncable/syncable_id.h"
15 #include "sync/syncable/write_transaction.h"
17 using std::vector;
19 namespace syncer {
21 UpdateApplicator::UpdateApplicator(ConflictResolver* resolver,
22 Cryptographer* cryptographer,
23 const UpdateIterator& begin,
24 const UpdateIterator& end,
25 const ModelSafeRoutingInfo& routes,
26 ModelSafeGroup group_filter)
27 : resolver_(resolver),
28 cryptographer_(cryptographer),
29 begin_(begin),
30 end_(end),
31 pointer_(begin),
32 group_filter_(group_filter),
33 progress_(false),
34 routing_info_(routes),
35 application_results_(end - begin) {
36 size_t item_count = end - begin;
37 DVLOG(1) << "UpdateApplicator created for " << item_count << " items.";
40 UpdateApplicator::~UpdateApplicator() {
43 // Returns true if there's more to do.
44 bool UpdateApplicator::AttemptOneApplication(
45 syncable::WriteTransaction* trans) {
46 // If there are no updates left to consider, we're done.
47 if (end_ == begin_)
48 return false;
49 if (pointer_ == end_) {
50 if (!progress_)
51 return false;
53 DVLOG(1) << "UpdateApplicator doing additional pass.";
54 pointer_ = begin_;
55 progress_ = false;
57 // Clear the tracked failures to avoid double-counting.
58 application_results_.ClearConflicts();
61 syncable::Entry read_only(trans, syncable::GET_BY_HANDLE, *pointer_);
62 if (SkipUpdate(read_only)) {
63 Advance();
64 return true;
67 syncable::MutableEntry entry(trans, syncable::GET_BY_HANDLE, *pointer_);
68 UpdateAttemptResponse updateResponse = AttemptToUpdateEntry(
69 trans, &entry, resolver_, cryptographer_);
70 switch (updateResponse) {
71 case SUCCESS:
72 Advance();
73 progress_ = true;
74 application_results_.AddSuccess(entry.Get(syncable::ID));
75 break;
76 case CONFLICT_SIMPLE:
77 pointer_++;
78 application_results_.AddSimpleConflict(entry.Get(syncable::ID));
79 break;
80 case CONFLICT_ENCRYPTION:
81 pointer_++;
82 application_results_.AddEncryptionConflict(entry.Get(syncable::ID));
83 break;
84 case CONFLICT_HIERARCHY:
85 pointer_++;
86 application_results_.AddHierarchyConflict(entry.Get(syncable::ID));
87 break;
88 default:
89 NOTREACHED();
90 break;
92 DVLOG(1) << "Apply Status for " << entry.Get(syncable::META_HANDLE)
93 << " is " << updateResponse;
95 return true;
98 void UpdateApplicator::Advance() {
99 --end_;
100 *pointer_ = *end_;
103 bool UpdateApplicator::SkipUpdate(const syncable::Entry& entry) {
104 syncer::ModelType type = entry.GetServerModelType();
105 ModelSafeGroup g = GetGroupForModelType(type, routing_info_);
106 // The set of updates passed to the UpdateApplicator should already
107 // be group-filtered.
108 if (g != group_filter_) {
109 NOTREACHED();
110 return true;
112 if (g == GROUP_PASSIVE &&
113 !routing_info_.count(type) &&
114 type != syncer::UNSPECIFIED &&
115 type != syncer::TOP_LEVEL_FOLDER) {
116 DVLOG(1) << "Skipping update application, type not permitted.";
117 return true;
119 return false;
122 bool UpdateApplicator::AllUpdatesApplied() const {
123 return application_results_.no_conflicts() && begin_ == end_;
126 void UpdateApplicator::SaveProgressIntoSessionState(
127 sessions::ConflictProgress* conflict_progress,
128 sessions::UpdateProgress* update_progress) {
129 DCHECK(begin_ == end_ || ((pointer_ == end_) && !progress_))
130 << "SaveProgress called before updates exhausted.";
132 application_results_.SaveProgress(conflict_progress, update_progress);
135 UpdateApplicator::ResultTracker::ResultTracker(size_t num_results) {
136 successful_ids_.reserve(num_results);
139 UpdateApplicator::ResultTracker::~ResultTracker() {
142 void UpdateApplicator::ResultTracker::AddSimpleConflict(syncable::Id id) {
143 conflicting_ids_.push_back(id);
146 void UpdateApplicator::ResultTracker::AddEncryptionConflict(syncable::Id id) {
147 encryption_conflict_ids_.push_back(id);
150 void UpdateApplicator::ResultTracker::AddHierarchyConflict(syncable::Id id) {
151 hierarchy_conflict_ids_.push_back(id);
154 void UpdateApplicator::ResultTracker::AddSuccess(syncable::Id id) {
155 successful_ids_.push_back(id);
158 void UpdateApplicator::ResultTracker::SaveProgress(
159 sessions::ConflictProgress* conflict_progress,
160 sessions::UpdateProgress* update_progress) {
161 vector<syncable::Id>::const_iterator i;
162 for (i = conflicting_ids_.begin(); i != conflicting_ids_.end(); ++i) {
163 conflict_progress->AddSimpleConflictingItemById(*i);
164 update_progress->AddAppliedUpdate(CONFLICT_SIMPLE, *i);
166 for (i = encryption_conflict_ids_.begin();
167 i != encryption_conflict_ids_.end(); ++i) {
168 conflict_progress->AddEncryptionConflictingItemById(*i);
169 update_progress->AddAppliedUpdate(CONFLICT_ENCRYPTION, *i);
171 for (i = hierarchy_conflict_ids_.begin();
172 i != hierarchy_conflict_ids_.end(); ++i) {
173 conflict_progress->AddHierarchyConflictingItemById(*i);
174 update_progress->AddAppliedUpdate(CONFLICT_HIERARCHY, *i);
176 for (i = successful_ids_.begin(); i != successful_ids_.end(); ++i) {
177 conflict_progress->EraseSimpleConflictingItemById(*i);
178 update_progress->AddAppliedUpdate(SUCCESS, *i);
182 void UpdateApplicator::ResultTracker::ClearConflicts() {
183 conflicting_ids_.clear();
184 encryption_conflict_ids_.clear();
185 hierarchy_conflict_ids_.clear();
188 bool UpdateApplicator::ResultTracker::no_conflicts() const {
189 return conflicting_ids_.empty();
192 } // namespace syncer