Index: chrome/browser/sync/engine/sync_process_state.cc |
=================================================================== |
--- chrome/browser/sync/engine/sync_process_state.cc (revision 0) |
+++ chrome/browser/sync/engine/sync_process_state.cc (revision 0) |
@@ -0,0 +1,325 @@ |
+// Copyright (c) 2006-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. |
+ |
+// |
+// THIS CLASS PROVIDES NO SYNCHRONIZATION GUARANTEES. |
+ |
+#include "chrome/browser/sync/engine/sync_process_state.h" |
+ |
+#include <map> |
+#include <set> |
+#include <vector> |
+ |
+#include "base/basictypes.h" |
+#include "chrome/browser/sync/syncable/directory_manager.h" |
+#include "chrome/browser/sync/syncable/syncable.h" |
+ |
+using std::map; |
+using std::set; |
+using std::vector; |
+ |
+namespace browser_sync { |
+ |
+SyncProcessState::SyncProcessState(const SyncProcessState& counts) |
+ : account_name_(counts.account_name_), |
+ dirman_(counts.dirman_), |
+ syncer_event_channel_(counts.syncer_event_channel_), |
+ connection_manager_(counts.connection_manager_), |
+ resolver_(counts.resolver_), |
+ model_safe_worker_(counts.model_safe_worker_) { |
+ *this = counts; |
+} |
+ |
+SyncProcessState::SyncProcessState(syncable::DirectoryManager* dirman, |
+ PathString account_name, |
+ ServerConnectionManager* connection_manager, |
+ ConflictResolver* const resolver, |
+ SyncerEventChannel* syncer_event_channel, |
+ ModelSafeWorker* model_safe_worker) |
+ : account_name_(account_name), |
+ dirman_(dirman), |
+ syncer_event_channel_(syncer_event_channel), |
+ connection_manager_(connection_manager), |
+ model_safe_worker_(model_safe_worker), |
+ resolver_(resolver), |
+ syncer_stuck_(false), |
+ num_sync_cycles_(0), |
+ silenced_until_(0), |
+ error_rate_(0), |
+ current_sync_timestamp_(0), |
+ servers_latest_timestamp_(0), |
+ error_commits_(0), |
+ stalled_commits_(0), |
+ conflicting_commits_(0), |
+ consecutive_problem_get_updates_(0), |
+ consecutive_problem_commits_(0), |
+ consecutive_transient_error_commits_(0), |
+ consecutive_errors_(0), |
+ successful_commits_(0), |
+ dirty_(false), |
+ auth_dirty_(false), |
+ auth_failed_(false), |
+ invalid_store_(false) { |
+ syncable::ScopedDirLookup dir(dirman_, account_name_); |
+ |
+ // The directory must be good here. |
+ LOG_IF(ERROR, !dir.good()); |
+ syncing_ = !dir->initial_sync_ended(); |
+ |
+ // If we have never synced then we are invalid until made otherwise. |
+ set_invalid_store((dir->last_sync_timestamp() <= 0)); |
+} |
+ |
+SyncProcessState& SyncProcessState::operator=(const SyncProcessState& counts) { |
+ if (this == &counts) { |
+ return *this; |
+ } |
+ CleanupSets(); |
+ num_sync_cycles_ = counts.num_sync_cycles_; |
+ silenced_until_ = counts.silenced_until_; |
+ error_rate_ = counts.error_rate_; |
+ current_sync_timestamp_ = counts.current_sync_timestamp_; |
+ servers_latest_timestamp_ = counts.servers_latest_timestamp_; |
+ error_commits_ = counts.error_commits_; |
+ stalled_commits_ = counts.stalled_commits_; |
+ conflicting_commits_ = counts.conflicting_commits_; |
+ consecutive_problem_get_updates_ = |
+ counts.consecutive_problem_get_updates_; |
+ consecutive_problem_commits_ = |
+ counts.consecutive_problem_commits_; |
+ consecutive_transient_error_commits_ = |
+ counts.consecutive_transient_error_commits_; |
+ consecutive_errors_ = counts.consecutive_errors_; |
+ conflicting_item_ids_ = counts.conflicting_item_ids_; |
+ blocked_item_ids_ = counts.blocked_item_ids_; |
+ successful_commits_ = counts.successful_commits_; |
+ syncer_stuck_ = counts.syncer_stuck_; |
+ |
+ // TODO(chron): Is it safe to set these? |
+ // |
+ // Pointers: |
+ // |
+ // connection_manager_ |
+ // account_name_ |
+ // dirman_ |
+ // model_safe_worker_ |
+ // syncer_event_channel_ |
+ // |
+ // Status members: |
+ // syncing_ |
+ // invalid_store_ |
+ // syncer_stuck_ |
+ // got_zero_updates_ |
+ // dirty_ |
+ // auth_dirty_ |
+ // auth_failed_ |
+ |
+ for (set<ConflictSet*>::const_iterator it = |
+ counts.ConflictSetsBegin(); |
+ counts.ConflictSetsEnd() != it; ++it) { |
+ const ConflictSet* old_set = *it; |
+ ConflictSet* const new_set = new ConflictSet(*old_set); |
+ conflict_sets_.insert(new_set); |
+ |
+ for (ConflictSet::const_iterator setit = new_set->begin(); |
+ new_set->end() != setit; ++setit) { |
+ id_to_conflict_set_[*setit] = new_set; |
+ } |
+ } |
+ return *this; |
+} |
+ |
+// status maintenance functions |
+void SyncProcessState::set_invalid_store(const bool val) { |
+ UpdateDirty(val != invalid_store_); |
+ invalid_store_ = val; |
+} |
+ |
+void SyncProcessState::set_syncer_stuck(const bool val) { |
+ UpdateDirty(val != syncer_stuck_); |
+ syncer_stuck_ = val; |
+} |
+ |
+void SyncProcessState::set_syncing(const bool val) { |
+ UpdateDirty(val != syncing_); |
+ syncing_ = val; |
+} |
+ |
+// Returns true if got zero updates has been set on the directory. |
+bool SyncProcessState::IsShareUsable() const { |
+ syncable::ScopedDirLookup dir(dirman(), account_name()); |
+ if (!dir.good()) { |
+ LOG(ERROR) << "Scoped dir lookup failed!"; |
+ return false; |
+ } |
+ return dir->initial_sync_ended(); |
+} |
+ |
+void SyncProcessState::set_current_sync_timestamp(const int64 val) { |
+ UpdateDirty(val != current_sync_timestamp_); |
+ current_sync_timestamp_ = val; |
+} |
+ |
+void SyncProcessState::set_servers_latest_timestamp(const int64 val) { |
+ UpdateDirty(val != servers_latest_timestamp_); |
+ servers_latest_timestamp_ = val; |
+} |
+ |
+void SyncProcessState::set_error_commits(const int val) { |
+ UpdateDirty(val != error_commits_); |
+ error_commits_ = val; |
+} |
+ |
+void SyncProcessState::set_stalled_commits(const int val) { |
+ UpdateDirty(val != conflicting_commits_); |
+ conflicting_commits_ = val; |
+} |
+ |
+void SyncProcessState::set_conflicting_commits(const int val) { |
+ UpdateDirty(val != stalled_commits_); |
+ stalled_commits_ = val; |
+} |
+ |
+// WEIRD COUNTER functions |
+void SyncProcessState::increment_consecutive_problem_get_updates() { |
+ UpdateDirty(true); |
+ ++consecutive_problem_get_updates_; |
+} |
+ |
+void SyncProcessState::zero_consecutive_problem_get_updates() { |
+ UpdateDirty(0 != consecutive_problem_get_updates_); |
+ consecutive_problem_get_updates_ = 0; |
+} |
+ |
+void SyncProcessState::increment_consecutive_problem_commits() { |
+ UpdateDirty(true); |
+ ++consecutive_problem_commits_; |
+} |
+ |
+void SyncProcessState::zero_consecutive_problem_commits() { |
+ UpdateDirty(0 != consecutive_problem_commits_); |
+ consecutive_problem_commits_ = 0; |
+} |
+ |
+void SyncProcessState::increment_consecutive_transient_error_commits_by( |
+ int value) { |
+ UpdateDirty(0 != value); |
+ consecutive_transient_error_commits_ += value; |
+} |
+ |
+void SyncProcessState::zero_consecutive_transient_error_commits() { |
+ UpdateDirty(0 != consecutive_transient_error_commits_); |
+ consecutive_transient_error_commits_ = 0; |
+} |
+ |
+void SyncProcessState::increment_consecutive_errors_by(int value) { |
+ UpdateDirty(0 != value); |
+ consecutive_errors_ += value; |
+} |
+ |
+void SyncProcessState::zero_consecutive_errors() { |
+ UpdateDirty(0 != consecutive_errors_); |
+ consecutive_errors_ = 0; |
+} |
+ |
+void SyncProcessState::increment_successful_commits() { |
+ UpdateDirty(true); |
+ ++successful_commits_; |
+} |
+ |
+void SyncProcessState::zero_successful_commits() { |
+ UpdateDirty(0 != successful_commits_); |
+ successful_commits_ = 0; |
+} |
+ |
+// Methods for managing error rate tracking |
+void SyncProcessState::TallyNewError() { |
+ UpdateDirty(true); |
+ error_rate_ += (65536 - error_rate_) >> 2; |
+} |
+ |
+void SyncProcessState::TallyBigNewError() { |
+ UpdateDirty(true); |
+ error_rate_ += (65536 - error_rate_) >> 2; |
+} |
+ |
+void SyncProcessState::ForgetOldError() { |
+ error_rate_ -= error_rate_ >> 2; |
+} |
+ |
+void SyncProcessState::CheckErrorRateTooHigh() { |
+ UpdateDirty(error_rate_ > ERROR_THRESHOLD); |
+} |
+ |
+ |
+void SyncProcessState::MergeSets(const syncable::Id& id1, |
+ const syncable::Id& id2) { |
+ // There are no single item sets, we just leave those entries == 0 |
+ vector<syncable::Id>* set1 = id_to_conflict_set_[id1]; |
+ vector<syncable::Id>* set2 = id_to_conflict_set_[id2]; |
+ vector<syncable::Id>* rv = 0; |
+ if (0 == set1 && 0 == set2) { |
+ // neither item currently has a set so we build one. |
+ rv = new vector<syncable::Id>(); |
+ rv->push_back(id1); |
+ if (id1 != id2) { |
+ rv->push_back(id2); |
+ } else { |
+ LOG(WARNING) << "[BUG] Attempting to merge two identical conflict ids."; |
+ } |
+ conflict_sets_.insert(rv); |
+ } else if (0 == set1) { |
+ // add the item to the existing set. |
+ rv = set2; |
+ rv->push_back(id1); |
+ } else if (0 == set2) { |
+ // add the item to the existing set. |
+ rv = set1; |
+ rv->push_back(id2); |
+ } else if (set1 == set2) { |
+ // It's the same set already |
+ return; |
+ } else { |
+ // merge the two sets. |
+ rv = set1; |
+ // point all the second sets id's back to the first. |
+ vector<syncable::Id>::iterator i; |
+ for (i = set2->begin() ; i != set2->end() ; ++i) { |
+ id_to_conflict_set_[*i] = rv; |
+ } |
+ // copy the second set to the first. |
+ rv->insert(rv->end(), set2->begin(), set2->end()); |
+ conflict_sets_.erase(set2); |
+ delete set2; |
+ } |
+ id_to_conflict_set_[id1] = id_to_conflict_set_[id2] = rv; |
+} |
+ |
+void SyncProcessState::CleanupSets() { |
+ // Clean up all the sets. |
+ set<ConflictSet*>::iterator i; |
+ for (i = conflict_sets_.begin(); i != conflict_sets_.end(); i++) { |
+ delete *i; |
+ } |
+ conflict_sets_.clear(); |
+ id_to_conflict_set_.clear(); |
+} |
+ |
+SyncProcessState::~SyncProcessState() { |
+ CleanupSets(); |
+} |
+ |
+void SyncProcessState::AuthFailed() { |
+ // dirty if the last one DIDN'T fail. |
+ UpdateAuthDirty(true != auth_failed_); |
+ auth_failed_ = true; |
+} |
+ |
+void SyncProcessState::AuthSucceeded() { |
+ // dirty if the last one DID fail. |
+ UpdateAuthDirty(false != auth_failed_); |
+ auth_failed_ = false; |
+} |
+ |
+} // namespace browser_sync |
Property changes on: chrome\browser\sync\engine\sync_process_state.cc |
___________________________________________________________________ |
Added: svn:eol-style |
+ LF |