| 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
|
|
|
|
|