summaryrefslogtreecommitdiffstats
path: root/sync/engine/get_updates_processor.cc
diff options
context:
space:
mode:
authorrlarocque@chromium.org <rlarocque@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-01-17 23:21:59 +0000
committerrlarocque@chromium.org <rlarocque@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-01-17 23:21:59 +0000
commit2fdf6199cda564079bf743bf98e6c7b8205fc9c4 (patch)
tree26cb5feaaf3800771b98355450d0a1e37bb0753c /sync/engine/get_updates_processor.cc
parent0e416c45ad5b75728e696b73651f444135c9748f (diff)
downloadchromium_src-2fdf6199cda564079bf743bf98e6c7b8205fc9c4.zip
chromium_src-2fdf6199cda564079bf743bf98e6c7b8205fc9c4.tar.gz
chromium_src-2fdf6199cda564079bf743bf98e6c7b8205fc9c4.tar.bz2
sync: Introduce ModelTypeRegistry and helpers
Introduce the ModelTypeRegistry class and use it to manage the creation of UpdateHandlers and CommitContributors. The ModelTypeRegistry also gets some help from the newly introduced UpdaterList and CommitterList classes. This lets us move the verbose iteration logic out of the code that's focused on building and executing commits and updates, which should make those functions easier to read. It gives us more freedom to experiment with other ways to manage the lists of commit contributors and update handlers, should we choose to do so. It prevents us from leaking the set of enabled types through the per-type maps. This patch is one of the last in the stack related to building a per-type abstraction into the sync engine, and also one of the first steps towards implementing run-time enable and disable logic for the new-style sync types. BUG=278484 Review URL: https://codereview.chromium.org/93433006 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@245654 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'sync/engine/get_updates_processor.cc')
-rw-r--r--sync/engine/get_updates_processor.cc148
1 files changed, 148 insertions, 0 deletions
diff --git a/sync/engine/get_updates_processor.cc b/sync/engine/get_updates_processor.cc
new file mode 100644
index 0000000..b85329a
--- /dev/null
+++ b/sync/engine/get_updates_processor.cc
@@ -0,0 +1,148 @@
+// Copyright 2014 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.
+
+#include "sync/engine/get_updates_processor.h"
+
+#include <map>
+
+#include "sync/engine/sync_directory_update_handler.h"
+#include "sync/protocol/sync.pb.h"
+
+namespace syncer {
+
+typedef std::map<ModelType, size_t> TypeToIndexMap;
+
+namespace {
+
+// Given a GetUpdates response, iterates over all the returned items and
+// divides them according to their type. Outputs a map from model types to
+// received SyncEntities. The output map will have entries (possibly empty)
+// for all types in |requested_types|.
+void PartitionUpdatesByType(
+ const sync_pb::GetUpdatesResponse& updates,
+ ModelTypeSet requested_types,
+ TypeSyncEntityMap* updates_by_type) {
+ int update_count = updates.entries().size();
+ for (ModelTypeSet::Iterator it = requested_types.First();
+ it.Good(); it.Inc()) {
+ updates_by_type->insert(std::make_pair(it.Get(), SyncEntityList()));
+ }
+ for (int i = 0; i < update_count; ++i) {
+ const sync_pb::SyncEntity& update = updates.entries(i);
+ ModelType type = GetModelType(update);
+ if (!IsRealDataType(type)) {
+ NOTREACHED() << "Received update with invalid type.";
+ continue;
+ }
+
+ TypeSyncEntityMap::iterator it = updates_by_type->find(type);
+ if (it == updates_by_type->end()) {
+ NOTREACHED() << "Received update for unexpected type "
+ << ModelTypeToString(type);
+ continue;
+ }
+
+ it->second.push_back(&update);
+ }
+}
+
+// Builds a map of ModelTypes to indices to progress markers in the given
+// |gu_response| message. The map is returned in the |index_map| parameter.
+void PartitionProgressMarkersByType(
+ const sync_pb::GetUpdatesResponse& gu_response,
+ ModelTypeSet request_types,
+ TypeToIndexMap* index_map) {
+ for (int i = 0; i < gu_response.new_progress_marker_size(); ++i) {
+ int field_number = gu_response.new_progress_marker(i).data_type_id();
+ ModelType model_type = GetModelTypeFromSpecificsFieldNumber(field_number);
+ if (!IsRealDataType(model_type)) {
+ DLOG(WARNING) << "Unknown field number " << field_number;
+ continue;
+ }
+ if (!request_types.Has(model_type)) {
+ DLOG(WARNING)
+ << "Skipping unexpected progress marker for non-enabled type "
+ << ModelTypeToString(model_type);
+ continue;
+ }
+ index_map->insert(std::make_pair(model_type, i));
+ }
+}
+
+} // namespace
+
+GetUpdatesProcessor::GetUpdatesProcessor(UpdateHandlerMap* update_handler_map)
+ : update_handler_map_(update_handler_map) {}
+
+GetUpdatesProcessor::~GetUpdatesProcessor() {}
+
+void GetUpdatesProcessor::PrepareGetUpdates(
+ ModelTypeSet gu_types,
+ sync_pb::GetUpdatesMessage* get_updates) {
+ for (ModelTypeSet::Iterator it = gu_types.First(); it.Good(); it.Inc()) {
+ UpdateHandlerMap::iterator handler_it = update_handler_map_->find(it.Get());
+ DCHECK(handler_it != update_handler_map_->end());
+ sync_pb::DataTypeProgressMarker* progress_marker =
+ get_updates->add_from_progress_marker();
+ handler_it->second->GetDownloadProgress(progress_marker);
+ }
+}
+
+bool GetUpdatesProcessor::ProcessGetUpdatesResponse(
+ ModelTypeSet gu_types,
+ const sync_pb::GetUpdatesResponse& gu_response,
+ sessions::StatusController* status_controller) {
+ TypeSyncEntityMap updates_by_type;
+ PartitionUpdatesByType(gu_response, gu_types, &updates_by_type);
+ DCHECK_EQ(gu_types.Size(), updates_by_type.size());
+
+ TypeToIndexMap progress_index_by_type;
+ PartitionProgressMarkersByType(gu_response,
+ gu_types,
+ &progress_index_by_type);
+ if (gu_types.Size() != progress_index_by_type.size()) {
+ NOTREACHED() << "Missing progress markers in GetUpdates response.";
+ return false;
+ }
+
+ // Iterate over these maps in parallel, processing updates for each type.
+ TypeToIndexMap::iterator progress_marker_iter =
+ progress_index_by_type.begin();
+ TypeSyncEntityMap::iterator updates_iter = updates_by_type.begin();
+ for (; (progress_marker_iter != progress_index_by_type.end()
+ && updates_iter != updates_by_type.end());
+ ++progress_marker_iter, ++updates_iter) {
+ DCHECK_EQ(progress_marker_iter->first, updates_iter->first);
+ ModelType type = progress_marker_iter->first;
+
+ UpdateHandlerMap::iterator update_handler_iter =
+ update_handler_map_->find(type);
+
+ if (update_handler_iter != update_handler_map_->end()) {
+ update_handler_iter->second->ProcessGetUpdatesResponse(
+ gu_response.new_progress_marker(progress_marker_iter->second),
+ updates_iter->second,
+ status_controller);
+ } else {
+ DLOG(WARNING)
+ << "Ignoring received updates of a type we can't handle. "
+ << "Type is: " << ModelTypeToString(type);
+ continue;
+ }
+ }
+ DCHECK(progress_marker_iter == progress_index_by_type.end() &&
+ updates_iter == updates_by_type.end());
+
+ return true;
+}
+
+void GetUpdatesProcessor::ApplyUpdatesForAllTypes(
+ sessions::StatusController* status_controller) {
+ for (UpdateHandlerMap::iterator it = update_handler_map_->begin();
+ it != update_handler_map_->end(); ++it) {
+ it->second->ApplyUpdates(status_controller);
+ }
+}
+
+} // namespace syncer