| OLD | NEW |
| (Empty) |
| 1 // Copyright (c) 2006-2009 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. | |
| 4 | |
| 5 // | |
| 6 // THIS CLASS PROVIDES NO SYNCHRONIZATION GUARANTEES. | |
| 7 | |
| 8 #include "chrome/browser/sync/engine/sync_process_state.h" | |
| 9 | |
| 10 #include <map> | |
| 11 #include <set> | |
| 12 #include <vector> | |
| 13 | |
| 14 #include "base/basictypes.h" | |
| 15 #include "chrome/browser/sync/syncable/directory_manager.h" | |
| 16 #include "chrome/browser/sync/syncable/syncable.h" | |
| 17 | |
| 18 using std::map; | |
| 19 using std::set; | |
| 20 using std::vector; | |
| 21 | |
| 22 namespace browser_sync { | |
| 23 | |
| 24 SyncProcessState::SyncProcessState(const SyncProcessState& counts) | |
| 25 : connection_manager_(counts.connection_manager_), | |
| 26 account_name_(counts.account_name_), | |
| 27 dirman_(counts.dirman_), | |
| 28 resolver_(counts.resolver_), | |
| 29 model_safe_worker_(counts.model_safe_worker_), | |
| 30 syncer_event_channel_(counts.syncer_event_channel_) { | |
| 31 *this = counts; | |
| 32 } | |
| 33 | |
| 34 SyncProcessState::SyncProcessState(syncable::DirectoryManager* dirman, | |
| 35 std::string account_name, | |
| 36 ServerConnectionManager* connection_manager, | |
| 37 ConflictResolver* const resolver, | |
| 38 SyncerEventChannel* syncer_event_channel, | |
| 39 ModelSafeWorker* model_safe_worker) | |
| 40 : connection_manager_(connection_manager), | |
| 41 account_name_(account_name), | |
| 42 dirman_(dirman), | |
| 43 resolver_(resolver), | |
| 44 model_safe_worker_(model_safe_worker), | |
| 45 syncer_event_channel_(syncer_event_channel), | |
| 46 current_sync_timestamp_(0), | |
| 47 num_server_changes_remaining_(0), | |
| 48 syncing_(false), | |
| 49 invalid_store_(false), | |
| 50 syncer_stuck_(false), | |
| 51 error_commits_(0), | |
| 52 conflicting_commits_(0), | |
| 53 consecutive_problem_get_updates_(0), | |
| 54 consecutive_problem_commits_(0), | |
| 55 consecutive_transient_error_commits_(0), | |
| 56 consecutive_errors_(0), | |
| 57 successful_commits_(0), | |
| 58 dirty_(false), | |
| 59 auth_dirty_(false), | |
| 60 auth_failed_(false) { | |
| 61 syncable::ScopedDirLookup dir(dirman_, account_name_); | |
| 62 | |
| 63 // The directory must be good here. | |
| 64 LOG_IF(ERROR, !dir.good()); | |
| 65 syncing_ = !dir->initial_sync_ended(); | |
| 66 | |
| 67 // If we have never synced then we are invalid until made otherwise. | |
| 68 set_invalid_store((dir->last_sync_timestamp() <= 0)); | |
| 69 } | |
| 70 | |
| 71 SyncProcessState& SyncProcessState::operator=(const SyncProcessState& counts) { | |
| 72 if (this == &counts) { | |
| 73 return *this; | |
| 74 } | |
| 75 CleanupSets(); | |
| 76 silenced_until_ = counts.silenced_until_; | |
| 77 current_sync_timestamp_ = counts.current_sync_timestamp_; | |
| 78 num_server_changes_remaining_ = counts.num_server_changes_remaining_; | |
| 79 error_commits_ = counts.error_commits_; | |
| 80 conflicting_commits_ = counts.conflicting_commits_; | |
| 81 consecutive_problem_get_updates_ = | |
| 82 counts.consecutive_problem_get_updates_; | |
| 83 consecutive_problem_commits_ = | |
| 84 counts.consecutive_problem_commits_; | |
| 85 consecutive_transient_error_commits_ = | |
| 86 counts.consecutive_transient_error_commits_; | |
| 87 consecutive_errors_ = counts.consecutive_errors_; | |
| 88 conflicting_item_ids_ = counts.conflicting_item_ids_; | |
| 89 successful_commits_ = counts.successful_commits_; | |
| 90 syncer_stuck_ = counts.syncer_stuck_; | |
| 91 | |
| 92 // TODO(chron): Is it safe to set these? | |
| 93 // | |
| 94 // Pointers: | |
| 95 // | |
| 96 // connection_manager_ | |
| 97 // account_name_ | |
| 98 // dirman_ | |
| 99 // model_safe_worker_ | |
| 100 // syncer_event_channel_ | |
| 101 // | |
| 102 // Status members: | |
| 103 // syncing_ | |
| 104 // invalid_store_ | |
| 105 // syncer_stuck_ | |
| 106 // got_zero_updates_ | |
| 107 // dirty_ | |
| 108 // auth_dirty_ | |
| 109 // auth_failed_ | |
| 110 | |
| 111 for (set<ConflictSet*>::const_iterator it = | |
| 112 counts.ConflictSetsBegin(); | |
| 113 counts.ConflictSetsEnd() != it; ++it) { | |
| 114 const ConflictSet* old_set = *it; | |
| 115 ConflictSet* const new_set = new ConflictSet(*old_set); | |
| 116 conflict_sets_.insert(new_set); | |
| 117 | |
| 118 for (ConflictSet::const_iterator setit = new_set->begin(); | |
| 119 new_set->end() != setit; ++setit) { | |
| 120 id_to_conflict_set_[*setit] = new_set; | |
| 121 } | |
| 122 } | |
| 123 return *this; | |
| 124 } | |
| 125 | |
| 126 void SyncProcessState::set_silenced_until(const base::TimeTicks& val) { | |
| 127 UpdateDirty(val != silenced_until_); | |
| 128 silenced_until_ = val; | |
| 129 } | |
| 130 | |
| 131 // Status maintenance functions. | |
| 132 void SyncProcessState::set_invalid_store(const bool val) { | |
| 133 UpdateDirty(val != invalid_store_); | |
| 134 invalid_store_ = val; | |
| 135 } | |
| 136 | |
| 137 void SyncProcessState::set_syncer_stuck(const bool val) { | |
| 138 UpdateDirty(val != syncer_stuck_); | |
| 139 syncer_stuck_ = val; | |
| 140 } | |
| 141 | |
| 142 void SyncProcessState::set_syncing(const bool val) { | |
| 143 UpdateDirty(val != syncing_); | |
| 144 syncing_ = val; | |
| 145 } | |
| 146 | |
| 147 // Returns true if got zero updates has been set on the directory. | |
| 148 bool SyncProcessState::IsShareUsable() const { | |
| 149 syncable::ScopedDirLookup dir(dirman(), account_name()); | |
| 150 if (!dir.good()) { | |
| 151 LOG(ERROR) << "Scoped dir lookup failed!"; | |
| 152 return false; | |
| 153 } | |
| 154 return dir->initial_sync_ended(); | |
| 155 } | |
| 156 | |
| 157 void SyncProcessState::set_current_sync_timestamp(const int64 val) { | |
| 158 UpdateDirty(val != current_sync_timestamp_); | |
| 159 current_sync_timestamp_ = val; | |
| 160 } | |
| 161 | |
| 162 void SyncProcessState::set_num_server_changes_remaining(const int64 val) { | |
| 163 UpdateDirty(val != num_server_changes_remaining_); | |
| 164 num_server_changes_remaining_ = val; | |
| 165 } | |
| 166 | |
| 167 void SyncProcessState::set_conflicting_commits(const int val) { | |
| 168 UpdateDirty(val != conflicting_commits_); | |
| 169 conflicting_commits_ = val; | |
| 170 } | |
| 171 | |
| 172 // WEIRD COUNTER functions. | |
| 173 void SyncProcessState::increment_consecutive_problem_get_updates() { | |
| 174 UpdateDirty(true); | |
| 175 ++consecutive_problem_get_updates_; | |
| 176 } | |
| 177 | |
| 178 void SyncProcessState::zero_consecutive_problem_get_updates() { | |
| 179 UpdateDirty(0 != consecutive_problem_get_updates_); | |
| 180 consecutive_problem_get_updates_ = 0; | |
| 181 } | |
| 182 | |
| 183 void SyncProcessState::increment_consecutive_problem_commits() { | |
| 184 UpdateDirty(true); | |
| 185 ++consecutive_problem_commits_; | |
| 186 } | |
| 187 | |
| 188 void SyncProcessState::zero_consecutive_problem_commits() { | |
| 189 UpdateDirty(0 != consecutive_problem_commits_); | |
| 190 consecutive_problem_commits_ = 0; | |
| 191 } | |
| 192 | |
| 193 void SyncProcessState::increment_consecutive_transient_error_commits_by( | |
| 194 int value) { | |
| 195 UpdateDirty(0 != value); | |
| 196 consecutive_transient_error_commits_ += value; | |
| 197 } | |
| 198 | |
| 199 void SyncProcessState::zero_consecutive_transient_error_commits() { | |
| 200 UpdateDirty(0 != consecutive_transient_error_commits_); | |
| 201 consecutive_transient_error_commits_ = 0; | |
| 202 } | |
| 203 | |
| 204 void SyncProcessState::increment_consecutive_errors_by(int value) { | |
| 205 UpdateDirty(0 != value); | |
| 206 consecutive_errors_ += value; | |
| 207 } | |
| 208 | |
| 209 void SyncProcessState::zero_consecutive_errors() { | |
| 210 UpdateDirty(0 != consecutive_errors_); | |
| 211 consecutive_errors_ = 0; | |
| 212 } | |
| 213 | |
| 214 void SyncProcessState::increment_successful_commits() { | |
| 215 UpdateDirty(true); | |
| 216 ++successful_commits_; | |
| 217 } | |
| 218 | |
| 219 void SyncProcessState::zero_successful_commits() { | |
| 220 UpdateDirty(0 != successful_commits_); | |
| 221 successful_commits_ = 0; | |
| 222 } | |
| 223 | |
| 224 void SyncProcessState::MergeSets(const syncable::Id& id1, | |
| 225 const syncable::Id& id2) { | |
| 226 // There are no single item sets, we just leave those entries == 0 | |
| 227 vector<syncable::Id>* set1 = id_to_conflict_set_[id1]; | |
| 228 vector<syncable::Id>* set2 = id_to_conflict_set_[id2]; | |
| 229 vector<syncable::Id>* rv = 0; | |
| 230 if (0 == set1 && 0 == set2) { | |
| 231 // Neither item currently has a set so we build one. | |
| 232 rv = new vector<syncable::Id>(); | |
| 233 rv->push_back(id1); | |
| 234 if (id1 != id2) { | |
| 235 rv->push_back(id2); | |
| 236 } else { | |
| 237 LOG(WARNING) << "[BUG] Attempting to merge two identical conflict ids."; | |
| 238 } | |
| 239 conflict_sets_.insert(rv); | |
| 240 } else if (0 == set1) { | |
| 241 // Add the item to the existing set. | |
| 242 rv = set2; | |
| 243 rv->push_back(id1); | |
| 244 } else if (0 == set2) { | |
| 245 // Add the item to the existing set. | |
| 246 rv = set1; | |
| 247 rv->push_back(id2); | |
| 248 } else if (set1 == set2) { | |
| 249 // It's the same set already. | |
| 250 return; | |
| 251 } else { | |
| 252 // Merge the two sets. | |
| 253 rv = set1; | |
| 254 // Point all the second sets id's back to the first. | |
| 255 vector<syncable::Id>::iterator i; | |
| 256 for (i = set2->begin() ; i != set2->end() ; ++i) { | |
| 257 id_to_conflict_set_[*i] = rv; | |
| 258 } | |
| 259 // Copy the second set to the first. | |
| 260 rv->insert(rv->end(), set2->begin(), set2->end()); | |
| 261 conflict_sets_.erase(set2); | |
| 262 delete set2; | |
| 263 } | |
| 264 id_to_conflict_set_[id1] = id_to_conflict_set_[id2] = rv; | |
| 265 } | |
| 266 | |
| 267 void SyncProcessState::CleanupSets() { | |
| 268 // Clean up all the sets. | |
| 269 set<ConflictSet*>::iterator i; | |
| 270 for (i = conflict_sets_.begin(); i != conflict_sets_.end(); i++) { | |
| 271 delete *i; | |
| 272 } | |
| 273 conflict_sets_.clear(); | |
| 274 id_to_conflict_set_.clear(); | |
| 275 } | |
| 276 | |
| 277 SyncProcessState::~SyncProcessState() { | |
| 278 CleanupSets(); | |
| 279 } | |
| 280 | |
| 281 void SyncProcessState::AuthFailed() { | |
| 282 // Dirty if the last one DIDN'T fail. | |
| 283 UpdateAuthDirty(true != auth_failed_); | |
| 284 auth_failed_ = true; | |
| 285 } | |
| 286 | |
| 287 } // namespace browser_sync | |
| OLD | NEW |