Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1110)

Side by Side Diff: sync/engine/updater_list.cc

Issue 93433006: sync: Introduce ModelTypeRegistry and helpers (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Split the type manager Created 7 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright (c) 2013 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 #include "sync/engine/updater_list.h"
6
7 #include <map>
8
9 #include "sync/engine/sync_directory_update_handler.h"
10 #include "sync/protocol/sync.pb.h"
11
12 namespace syncer {
13
14 typedef std::map<ModelType, size_t> TypeToIndexMap;
15
16 UpdaterList::UpdaterList()
17 : update_handler_deleter_(&update_handler_map_) {}
18
19 UpdaterList::~UpdaterList() {}
20
21 void UpdaterList::SetEnabledSyncDirectoryTypes(
22 const std::vector<scoped_refptr<ModelSafeWorker> > workers,
23 const ModelSafeRoutingInfo& routing_info,
24 syncable::Directory* directory) {
25 std::map<ModelSafeGroup, scoped_refptr<ModelSafeWorker> > workers_map;
26 for (size_t i = 0u; i < workers.size(); ++i) {
27 workers_map.insert(
28 std::make_pair(workers[i]->GetModelSafeGroup(), workers[i]));
29 }
30
31 STLDeleteValues<UpdateHandlerMap>(&update_handler_map_);
32 for (ModelSafeRoutingInfo::const_iterator routing_iter = routing_info.begin();
33 routing_iter != routing_info.end(); ++routing_iter) {
34 ModelType type = routing_iter->first;
35 ModelSafeGroup group = routing_iter->second;
36 std::map<ModelSafeGroup, scoped_refptr<ModelSafeWorker> >::iterator
37 worker_it = workers_map.find(group);
38 DCHECK(worker_it != workers_map.end());
39 scoped_refptr<ModelSafeWorker> worker = worker_it->second;
40
41 SyncDirectoryUpdateHandler* handler =
42 new SyncDirectoryUpdateHandler(directory, type, worker);
43 update_handler_map_.insert(std::make_pair(type, handler));
44 }
45 }
46
47 void UpdaterList::PrepareGetUpdates(
48 ModelTypeSet gu_types,
49 sync_pb::GetUpdatesMessage* get_updates) {
50 for (ModelTypeSet::Iterator it = gu_types.First(); it.Good(); it.Inc()) {
51 UpdateHandlerMap::iterator handler_it = update_handler_map_.find(it.Get());
52 DCHECK(handler_it != update_handler_map_.end());
53 sync_pb::DataTypeProgressMarker* progress_marker =
54 get_updates->add_from_progress_marker();
55 handler_it->second->GetDownloadProgress(progress_marker);
56 }
57 }
58
59 namespace {
60
61 // Given a GetUpdates response, iterates over all the returned items and
62 // divides them according to their type. Outputs a map from model types to
63 // received SyncEntities. The output map will have entries (possibly empty)
64 // for all types in |requested_types|.
65 void PartitionUpdatesByType(
66 const sync_pb::GetUpdatesResponse& updates,
67 ModelTypeSet requested_types,
68 TypeSyncEntityMap* updates_by_type) {
69 int update_count = updates.entries().size();
70 for (ModelTypeSet::Iterator it = requested_types.First();
71 it.Good(); it.Inc()) {
72 updates_by_type->insert(std::make_pair(it.Get(), SyncEntityList()));
73 }
74 for (int i = 0; i < update_count; ++i) {
75 const sync_pb::SyncEntity& update = updates.entries(i);
76 ModelType type = GetModelType(update);
77 if (!IsRealDataType(type)) {
78 NOTREACHED() << "Received update with invalid type.";
79 continue;
80 }
81
82 TypeSyncEntityMap::iterator it = updates_by_type->find(type);
83 if (it == updates_by_type->end()) {
84 DLOG(WARNING) << "Skipping update for unexpected type "
Nicolas Zea 2013/12/18 22:36:10 Should this be a NOTREACHED as well?
rlarocque 2014/01/03 01:46:41 Yes, probably. Updated.
85 << ModelTypeToString(type);
86 continue;
87 }
88
89 it->second.push_back(&update);
90 }
91 }
92
93 // Builds a map of ModelTypes to indices to progress markers in the given
94 // |gu_response| message. The map is returned in the |index_map| parameter.
95 void PartitionProgressMarkersByType(
96 const sync_pb::GetUpdatesResponse& gu_response,
97 ModelTypeSet request_types,
98 TypeToIndexMap* index_map) {
99 for (int i = 0; i < gu_response.new_progress_marker_size(); ++i) {
100 int field_number = gu_response.new_progress_marker(i).data_type_id();
101 ModelType model_type = GetModelTypeFromSpecificsFieldNumber(field_number);
102 if (!IsRealDataType(model_type)) {
103 DLOG(WARNING) << "Unknown field number " << field_number;
104 continue;
105 }
106 if (!request_types.Has(model_type)) {
107 DLOG(WARNING)
108 << "Skipping unexpected progress marker for non-enabled type "
109 << ModelTypeToString(model_type);
110 continue;
111 }
112 index_map->insert(std::make_pair(model_type, i));
113 }
114 }
115
116 } // namespace
117
118 bool UpdaterList::ProcessGetUpdatesResponse(
119 ModelTypeSet gu_types,
120 const sync_pb::GetUpdatesResponse& gu_response,
121 sessions::StatusController* status_controller) {
122 TypeSyncEntityMap updates_by_type;
123 PartitionUpdatesByType(gu_response, gu_types, &updates_by_type);
124 DCHECK_EQ(gu_types.Size(), updates_by_type.size());
125
126 TypeToIndexMap progress_index_by_type;
127 PartitionProgressMarkersByType(gu_response,
128 gu_types,
129 &progress_index_by_type);
130 if (gu_types.Size() != progress_index_by_type.size()) {
131 NOTREACHED() << "Missing progress markers in GetUpdates response.";
132 return false;
133 }
134
135 // Iterate over these maps in parallel, processing updates for each type.
136 TypeToIndexMap::iterator progress_marker_iter =
137 progress_index_by_type.begin();
138 TypeSyncEntityMap::iterator updates_iter = updates_by_type.begin();
139 for ( ; (progress_marker_iter != progress_index_by_type.end()
Nicolas Zea 2013/12/18 22:36:10 nit: remove space before ;? (not sure what the sty
rlarocque 2014/01/03 01:46:41 Done.
140 && updates_iter != updates_by_type.end());
141 ++progress_marker_iter, ++updates_iter) {
142 DCHECK_EQ(progress_marker_iter->first, updates_iter->first);
143 ModelType type = progress_marker_iter->first;
144
145 UpdateHandlerMap::iterator update_handler_iter =
146 update_handler_map_.find(type);
147
148 if (update_handler_iter != update_handler_map_.end()) {
149 update_handler_iter->second->ProcessGetUpdatesResponse(
150 gu_response.new_progress_marker(progress_marker_iter->second),
151 updates_iter->second,
152 status_controller);
153 } else {
154 DLOG(WARNING)
155 << "Ignoring received updates of a type we can't handle. "
156 << "Type is: " << ModelTypeToString(type);
157 continue;
158 }
159 }
160 DCHECK(progress_marker_iter == progress_index_by_type.end()
161 && updates_iter == updates_by_type.end());
162
163 return true;
164 }
165
166 void UpdaterList::ApplyUpdatesForAllTypes(
167 sessions::StatusController* status_controller) {
168 for (UpdateHandlerMap::iterator it = update_handler_map_.begin();
169 it != update_handler_map_.end(); ++it) {
170 it->second->ApplyUpdates(status_controller);
171 }
172 }
173
174 void UpdaterList::RegisterTypeForTest(
175 ModelType type,
176 SyncDirectoryUpdateHandler* handler) {
177 bool inserted =
178 update_handler_map_.insert(std::make_pair(type, handler)).second;
179 DCHECK(inserted) << "Attempt to override existing type handler in map";
180 }
181
182 } // namespace syncer
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698