summaryrefslogtreecommitdiffstats
path: root/chrome/browser/sync/engine/update_applicator.cc
diff options
context:
space:
mode:
Diffstat (limited to 'chrome/browser/sync/engine/update_applicator.cc')
-rw-r--r--chrome/browser/sync/engine/update_applicator.cc98
1 files changed, 98 insertions, 0 deletions
diff --git a/chrome/browser/sync/engine/update_applicator.cc b/chrome/browser/sync/engine/update_applicator.cc
new file mode 100644
index 0000000..17e6b36
--- /dev/null
+++ b/chrome/browser/sync/engine/update_applicator.cc
@@ -0,0 +1,98 @@
+// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/sync/engine/update_applicator.h"
+
+#include <vector>
+
+#include "base/logging.h"
+#include "chrome/browser/sync/engine/syncer_util.h"
+#include "chrome/browser/sync/syncable/syncable.h"
+#include "chrome/browser/sync/syncable/syncable_id.h"
+
+using std::vector;
+
+namespace browser_sync {
+
+UpdateApplicator::UpdateApplicator(SyncerSession* session,
+ const vi64iter& begin,
+ const vi64iter& end)
+ : session_(session), begin_(begin), end_(end), pointer_(begin),
+ progress_(false) {
+ size_t item_count = end - begin;
+ LOG(INFO) << "UpdateApplicator created for " << item_count << " items.";
+ successful_ids_.reserve(item_count);
+ }
+
+// returns true if there's more to do.
+bool UpdateApplicator::AttemptOneApplication(
+ syncable::WriteTransaction* trans) {
+ // If there are no updates left to consider, we're done.
+ if (end_ == begin_)
+ return false;
+ if (pointer_ == end_) {
+ if (!progress_)
+ return false;
+
+ LOG(INFO) << "UpdateApplicator doing additional pass.";
+ pointer_ = begin_;
+ progress_ = false;
+
+ // Clear the tracked failures to avoid double-counting.
+ conflicting_ids_.clear();
+ blocked_ids_.clear();
+ }
+ syncable::MutableEntry entry(trans, syncable::GET_BY_HANDLE, *pointer_);
+ UpdateAttemptResponse updateResponse =
+ SyncerUtil::AttemptToUpdateEntry(trans, &entry, session_);
+ switch (updateResponse) {
+ case SUCCESS:
+ --end_;
+ *pointer_ = *end_;
+ progress_ = true;
+ successful_ids_.push_back(entry.Get(syncable::ID));
+ break;
+ case CONFLICT:
+ pointer_++;
+ conflicting_ids_.push_back(entry.Get(syncable::ID));
+ break;
+ case BLOCKED:
+ pointer_++;
+ blocked_ids_.push_back(entry.Get(syncable::ID));
+ break;
+ }
+ LOG(INFO) << "Apply Status for " << entry.Get(syncable::META_HANDLE)
+ << " is " << updateResponse;
+
+ return true;
+}
+
+bool UpdateApplicator::AllUpdatesApplied() const {
+ return conflicting_ids_.empty() && blocked_ids_.empty() &&
+ begin_ == end_;
+}
+
+void UpdateApplicator::SaveProgressIntoSessionState() {
+ DCHECK(begin_ == end_ || ((pointer_ == end_) && !progress_))
+ << "SaveProgress called before updates exhausted.";
+
+ vector<syncable::Id>::const_iterator i;
+ for (i = conflicting_ids_.begin(); i != conflicting_ids_.end(); ++i) {
+ session_->EraseBlockedItem(*i);
+ session_->AddCommitConflict(*i);
+ session_->AddAppliedUpdate(CONFLICT, *i);
+ }
+ for (i = blocked_ids_.begin(); i != blocked_ids_.end(); ++i) {
+ session_->AddBlockedItem(*i);
+ session_->EraseCommitConflict(*i);
+ session_->AddAppliedUpdate(BLOCKED, *i);
+ }
+ for (i = successful_ids_.begin(); i != successful_ids_.end(); ++i) {
+ session_->EraseCommitConflict(*i);
+ session_->EraseBlockedItem(*i);
+ session_->AddAppliedUpdate(SUCCESS, *i);
+ }
+}
+
+} // namespace browser_sync