Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "sync/sessions/sync_session.h" | 5 #include "sync/sessions/sync_session.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <iterator> | 8 #include <iterator> |
| 9 | 9 |
| 10 #include "base/logging.h" | 10 #include "base/logging.h" |
| 11 #include "sync/internal_api/public/base/model_type.h" | 11 #include "sync/internal_api/public/base/model_type.h" |
| 12 #include "sync/internal_api/public/engine/model_safe_worker.h" | 12 #include "sync/internal_api/public/engine/model_safe_worker.h" |
| 13 #include "sync/syncable/directory.h" | 13 #include "sync/syncable/directory.h" |
| 14 | 14 |
| 15 namespace syncer { | 15 namespace syncer { |
| 16 namespace sessions { | 16 namespace sessions { |
| 17 | 17 |
| 18 namespace { | 18 namespace { |
| 19 | 19 |
| 20 std::set<ModelSafeGroup> ComputeEnabledGroups( | 20 std::set<ModelSafeGroup> ComputeEnabledGroups( |
| 21 const ModelSafeRoutingInfo& routing_info, | 21 const ModelSafeRoutingInfo& routing_info) { |
| 22 const std::vector<ModelSafeWorker*>& workers) { | |
| 23 std::set<ModelSafeGroup> enabled_groups; | 22 std::set<ModelSafeGroup> enabled_groups; |
| 24 // Project the list of enabled types (i.e., types in the routing | 23 // Project the list of enabled types (i.e., types in the routing |
| 25 // info) to a list of enabled groups. | 24 // info) to a list of enabled groups. |
| 26 for (ModelSafeRoutingInfo::const_iterator it = routing_info.begin(); | 25 for (ModelSafeRoutingInfo::const_iterator it = routing_info.begin(); |
| 27 it != routing_info.end(); ++it) { | 26 it != routing_info.end(); ++it) { |
| 28 enabled_groups.insert(it->second); | 27 enabled_groups.insert(it->second); |
| 29 } | 28 } |
| 30 // GROUP_PASSIVE is always enabled, since that's the group that | 29 // GROUP_PASSIVE is always enabled, since that's the group that |
| 31 // top-level folders map to. | 30 // top-level folders map to. |
| 32 enabled_groups.insert(GROUP_PASSIVE); | 31 enabled_groups.insert(GROUP_PASSIVE); |
| 33 if (DCHECK_IS_ON()) { | |
| 34 // We sometimes create dummy SyncSession objects (see | |
| 35 // SyncScheduler::InitialSnapshot) so don't check in that case. | |
| 36 if (!routing_info.empty() || !workers.empty()) { | |
| 37 std::set<ModelSafeGroup> groups_with_workers; | |
| 38 for (std::vector<ModelSafeWorker*>::const_iterator it = workers.begin(); | |
| 39 it != workers.end(); ++it) { | |
| 40 groups_with_workers.insert((*it)->GetModelSafeGroup()); | |
| 41 } | |
| 42 // All enabled groups should have a corresponding worker. | |
| 43 DCHECK(std::includes( | |
| 44 groups_with_workers.begin(), groups_with_workers.end(), | |
| 45 enabled_groups.begin(), enabled_groups.end())); | |
| 46 } | |
| 47 } | |
| 48 return enabled_groups; | 32 return enabled_groups; |
| 49 } | 33 } |
| 50 | 34 |
| 51 void PurgeStaleStates(ModelTypeStateMap* original, | 35 void PurgeStaleStates(ModelTypeStateMap* original, |
| 52 const ModelSafeRoutingInfo& routing_info) { | 36 const ModelSafeRoutingInfo& routing_info) { |
| 53 std::vector<ModelTypeStateMap::iterator> iterators_to_delete; | 37 std::vector<ModelTypeStateMap::iterator> iterators_to_delete; |
| 54 for (ModelTypeStateMap::iterator i = original->begin(); | 38 for (ModelTypeStateMap::iterator i = original->begin(); |
| 55 i != original->end(); ++i) { | 39 i != original->end(); ++i) { |
| 56 if (routing_info.end() == routing_info.find(i->first)) { | 40 if (routing_info.end() == routing_info.find(i->first)) { |
| 57 iterators_to_delete.push_back(i); | 41 iterators_to_delete.push_back(i); |
| 58 } | 42 } |
| 59 } | 43 } |
| 60 | 44 |
| 61 for (std::vector<ModelTypeStateMap::iterator>::iterator | 45 for (std::vector<ModelTypeStateMap::iterator>::iterator |
| 62 it = iterators_to_delete.begin(); it != iterators_to_delete.end(); | 46 it = iterators_to_delete.begin(); it != iterators_to_delete.end(); |
| 63 ++it) { | 47 ++it) { |
| 64 original->erase(*it); | 48 original->erase(*it); |
| 65 } | 49 } |
| 66 } | 50 } |
| 67 | 51 |
| 68 } // namesepace | 52 } // namesepace |
| 69 | 53 |
| 70 SyncSession::SyncSession(SyncSessionContext* context, Delegate* delegate, | 54 SyncSession::SyncSession(SyncSessionContext* context, Delegate* delegate, |
| 71 const SyncSourceInfo& source, | 55 const SyncSourceInfo& source, |
| 72 const ModelSafeRoutingInfo& routing_info, | 56 const ModelSafeRoutingInfo& routing_info) |
| 73 const std::vector<ModelSafeWorker*>& workers) | |
| 74 : context_(context), | 57 : context_(context), |
| 75 source_(source), | 58 source_(source), |
| 76 write_transaction_(NULL), | 59 write_transaction_(NULL), |
| 77 delegate_(delegate), | 60 delegate_(delegate), |
| 78 workers_(workers), | |
|
rlarocque
2012/09/19 20:39:21
What will be the effect of sync sessions with no w
| |
| 79 routing_info_(routing_info), | 61 routing_info_(routing_info), |
| 80 enabled_groups_(ComputeEnabledGroups(routing_info_, workers_)), | 62 enabled_groups_(ComputeEnabledGroups(routing_info_)), |
| 81 finished_(false) { | 63 finished_(false) { |
| 82 status_controller_.reset(new StatusController(routing_info_)); | 64 status_controller_.reset(new StatusController(routing_info_)); |
| 83 std::sort(workers_.begin(), workers_.end()); | |
| 84 } | 65 } |
| 85 | 66 |
| 86 SyncSession::~SyncSession() {} | 67 SyncSession::~SyncSession() {} |
| 87 | 68 |
| 88 void SyncSession::Coalesce(const SyncSession& session) { | 69 void SyncSession::Coalesce(const SyncSession& session) { |
| 89 if (context_ != session.context() || delegate_ != session.delegate_) { | 70 if (context_ != session.context() || delegate_ != session.delegate_) { |
| 90 NOTREACHED(); | 71 NOTREACHED(); |
| 91 return; | 72 return; |
| 92 } | 73 } |
| 93 | 74 |
| 94 // When we coalesce sessions, the sync update source gets overwritten with the | 75 // When we coalesce sessions, the sync update source gets overwritten with the |
| 95 // most recent, while the type/state map gets merged. | 76 // most recent, while the type/state map gets merged. |
| 96 CoalesceStates(&source_.types, session.source_.types); | 77 CoalesceStates(&source_.types, session.source_.types); |
| 97 source_.updates_source = session.source_.updates_source; | 78 source_.updates_source = session.source_.updates_source; |
| 98 | 79 |
| 99 std::vector<ModelSafeWorker*> temp; | |
| 100 std::set_union(workers_.begin(), workers_.end(), | |
| 101 session.workers_.begin(), session.workers_.end(), | |
| 102 std::back_inserter(temp)); | |
| 103 workers_.swap(temp); | |
| 104 | |
| 105 // We have to update the model safe routing info to the union. In case the | 80 // We have to update the model safe routing info to the union. In case the |
| 106 // same key is present in both pick the one from session. | 81 // same key is present in both pick the one from session. |
| 107 for (ModelSafeRoutingInfo::const_iterator it = | 82 for (ModelSafeRoutingInfo::const_iterator it = |
| 108 session.routing_info_.begin(); | 83 session.routing_info_.begin(); |
| 109 it != session.routing_info_.end(); | 84 it != session.routing_info_.end(); |
| 110 ++it) { | 85 ++it) { |
| 111 routing_info_[it->first] = it->second; | 86 routing_info_[it->first] = it->second; |
| 112 } | 87 } |
| 113 | 88 |
| 114 // Now update enabled groups. | 89 // Now update enabled groups. |
| 115 enabled_groups_ = ComputeEnabledGroups(routing_info_, workers_); | 90 enabled_groups_ = ComputeEnabledGroups(routing_info_); |
| 116 } | 91 } |
| 117 | 92 |
| 118 void SyncSession::RebaseRoutingInfoWithLatest(const SyncSession& session) { | 93 void SyncSession::RebaseRoutingInfoWithLatest(const SyncSession& session) { |
| 119 ModelSafeRoutingInfo temp_routing_info; | 94 ModelSafeRoutingInfo temp_routing_info; |
| 120 | 95 |
| 121 // Take the intersecion and also set the routing info(it->second) from the | 96 // Take the intersecion and also set the routing info(it->second) from the |
| 122 // passed in session. | 97 // passed in session. |
| 123 for (ModelSafeRoutingInfo::const_iterator it = | 98 for (ModelSafeRoutingInfo::const_iterator it = |
| 124 session.routing_info_.begin(); it != session.routing_info_.end(); | 99 session.routing_info_.begin(); it != session.routing_info_.end(); |
| 125 ++it) { | 100 ++it) { |
| 126 if (routing_info_.find(it->first) != routing_info_.end()) { | 101 if (routing_info_.find(it->first) != routing_info_.end()) { |
| 127 temp_routing_info[it->first] = it->second; | 102 temp_routing_info[it->first] = it->second; |
| 128 } | 103 } |
| 129 } | 104 } |
| 130 | 105 |
| 131 // Now swap it. | 106 // Now swap it. |
| 132 routing_info_.swap(temp_routing_info); | 107 routing_info_.swap(temp_routing_info); |
| 133 | 108 |
| 134 // Now update the payload map. | 109 // Now update the payload map. |
| 135 PurgeStaleStates(&source_.types, session.routing_info_); | 110 PurgeStaleStates(&source_.types, session.routing_info_); |
| 136 | 111 |
| 137 // Now update the workers. | |
| 138 std::vector<ModelSafeWorker*> temp; | |
| 139 std::set_intersection(workers_.begin(), workers_.end(), | |
| 140 session.workers_.begin(), session.workers_.end(), | |
| 141 std::back_inserter(temp)); | |
| 142 workers_.swap(temp); | |
| 143 | |
| 144 // Now update enabled groups. | 112 // Now update enabled groups. |
| 145 enabled_groups_ = ComputeEnabledGroups(routing_info_, workers_); | 113 enabled_groups_ = ComputeEnabledGroups(routing_info_); |
| 146 } | 114 } |
| 147 | 115 |
| 148 void SyncSession::PrepareForAnotherSyncCycle() { | 116 void SyncSession::PrepareForAnotherSyncCycle() { |
| 149 finished_ = false; | 117 finished_ = false; |
| 150 source_.updates_source = | 118 source_.updates_source = |
| 151 sync_pb::GetUpdatesCallerInfo::SYNC_CYCLE_CONTINUATION; | 119 sync_pb::GetUpdatesCallerInfo::SYNC_CYCLE_CONTINUATION; |
| 152 status_controller_.reset(new StatusController(routing_info_)); | 120 status_controller_.reset(new StatusController(routing_info_)); |
| 153 } | 121 } |
| 154 | 122 |
| 155 SyncSessionSnapshot SyncSession::TakeSnapshot() const { | 123 SyncSessionSnapshot SyncSession::TakeSnapshot() const { |
| (...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 267 // with the server. Therefore, we verify no errors and at least one SYNCER_OK. | 235 // with the server. Therefore, we verify no errors and at least one SYNCER_OK. |
| 268 return reached_server && !HadErrors(state); | 236 return reached_server && !HadErrors(state); |
| 269 } | 237 } |
| 270 | 238 |
| 271 void SyncSession::SetFinished() { | 239 void SyncSession::SetFinished() { |
| 272 finished_ = true; | 240 finished_ = true; |
| 273 } | 241 } |
| 274 | 242 |
| 275 } // namespace sessions | 243 } // namespace sessions |
| 276 } // namespace syncer | 244 } // namespace syncer |
| OLD | NEW |