Index: sync/notifier/invalidator_registrar.cc |
diff --git a/sync/notifier/invalidator_registrar.cc b/sync/notifier/invalidator_registrar.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..334505287d20de79c9993c35682a4ec6fbe3b003 |
--- /dev/null |
+++ b/sync/notifier/invalidator_registrar.cc |
@@ -0,0 +1,149 @@ |
+// Copyright (c) 2012 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/notifier/invalidator_registrar.h" |
+ |
+#include <cstddef> |
+#include <iterator> |
+#include <utility> |
+ |
+#include "base/logging.h" |
+#include "sync/notifier/object_id_invalidation_map.h" |
+ |
+namespace syncer { |
+ |
+InvalidatorRegistrar::InvalidatorRegistrar() |
+ : state_(DEFAULT_INVALIDATION_ERROR) {} |
+ |
+InvalidatorRegistrar::~InvalidatorRegistrar() { |
+ DCHECK(thread_checker_.CalledOnValidThread()); |
+ CHECK(!handlers_.might_have_observers()); |
+ CHECK(handler_to_ids_map_.empty()); |
+} |
+ |
+void InvalidatorRegistrar::RegisterHandler(InvalidationHandler* handler) { |
+ DCHECK(thread_checker_.CalledOnValidThread()); |
+ CHECK(handler); |
+ CHECK(!handlers_.HasObserver(handler)); |
+ handlers_.AddObserver(handler); |
+} |
+ |
+void InvalidatorRegistrar::UpdateRegisteredIds( |
+ InvalidationHandler* handler, |
+ const ObjectIdSet& ids) { |
+ DCHECK(thread_checker_.CalledOnValidThread()); |
+ CHECK(handler); |
+ CHECK(handlers_.HasObserver(handler)); |
+ |
+ for (HandlerIdsMap::const_iterator it = handler_to_ids_map_.begin(); |
+ it != handler_to_ids_map_.end(); ++it) { |
+ if (it->first == handler) { |
+ continue; |
+ } |
+ |
+ std::vector<invalidation::ObjectId> intersection; |
+ std::set_intersection( |
+ it->second.begin(), it->second.end(), |
+ ids.begin(), ids.end(), |
+ std::inserter(intersection, intersection.end()), |
+ ObjectIdLessThan()); |
+ CHECK(intersection.empty()) |
+ << "Duplicate registration: trying to register " |
+ << ObjectIdToString(*intersection.begin()) << " for " |
+ << handler << " when it's already registered for " |
+ << it->first; |
+ } |
+ |
+ if (ids.empty()) { |
+ handler_to_ids_map_.erase(handler); |
+ } else { |
+ handler_to_ids_map_[handler] = ids; |
+ } |
+} |
+ |
+void InvalidatorRegistrar::UnregisterHandler(InvalidationHandler* handler) { |
+ DCHECK(thread_checker_.CalledOnValidThread()); |
+ CHECK(handler); |
+ CHECK(handlers_.HasObserver(handler)); |
+ handlers_.RemoveObserver(handler); |
+ handler_to_ids_map_.erase(handler); |
+} |
+ |
+ObjectIdSet InvalidatorRegistrar::GetRegisteredIds( |
+ InvalidationHandler* handler) const { |
+ DCHECK(thread_checker_.CalledOnValidThread()); |
+ HandlerIdsMap::const_iterator lookup = handler_to_ids_map_.find(handler); |
+ if (lookup != handler_to_ids_map_.end()) { |
+ return lookup->second; |
+ } else { |
+ return ObjectIdSet(); |
+ } |
+} |
+ |
+ObjectIdSet InvalidatorRegistrar::GetAllRegisteredIds() const { |
+ DCHECK(thread_checker_.CalledOnValidThread()); |
+ ObjectIdSet registered_ids; |
+ for (HandlerIdsMap::const_iterator it = handler_to_ids_map_.begin(); |
+ it != handler_to_ids_map_.end(); ++it) { |
+ registered_ids.insert(it->second.begin(), it->second.end()); |
+ } |
+ return registered_ids; |
+} |
+ |
+void InvalidatorRegistrar::DispatchInvalidationsToHandlers( |
+ const ObjectIdInvalidationMap& invalidation_map) { |
+ DCHECK(thread_checker_.CalledOnValidThread()); |
+ // If we have no handlers, there's nothing to do. |
+ if (!handlers_.might_have_observers()) { |
+ return; |
+ } |
+ |
+ for (HandlerIdsMap::iterator it = handler_to_ids_map_.begin(); |
+ it != handler_to_ids_map_.end(); ++it) { |
+ ObjectIdInvalidationMap to_emit = |
+ invalidation_map.GetSubsetWithObjectIds(it->second); |
+ if (!to_emit.Empty()) { |
+ it->first->OnIncomingInvalidation(to_emit); |
+ } |
+ } |
+} |
+ |
+void InvalidatorRegistrar::UpdateInvalidatorState(InvalidatorState state) { |
+ DCHECK(thread_checker_.CalledOnValidThread()); |
+ DVLOG(1) << "New invalidator state: " << InvalidatorStateToString(state_) |
+ << " -> " << InvalidatorStateToString(state); |
+ state_ = state; |
+ FOR_EACH_OBSERVER(InvalidationHandler, handlers_, |
+ OnInvalidatorStateChange(state)); |
+} |
+ |
+InvalidatorState InvalidatorRegistrar::GetInvalidatorState() const { |
+ DCHECK(thread_checker_.CalledOnValidThread()); |
+ return state_; |
+} |
+ |
+std::map<std::string, ObjectIdSet> |
+InvalidatorRegistrar::GetSanitizedHandlersIdsMap() { |
+ DCHECK(thread_checker_.CalledOnValidThread()); |
+ std::map<std::string, ObjectIdSet> clean_handlers_to_ids; |
+ for (HandlerIdsMap::const_iterator it = handler_to_ids_map_.begin(); |
+ it != handler_to_ids_map_.end(); |
+ ++it) { |
+ clean_handlers_to_ids[it->first->GetOwnerName()] = ObjectIdSet(it->second); |
+ } |
+ return clean_handlers_to_ids; |
+} |
+ |
+bool InvalidatorRegistrar::IsHandlerRegisteredForTest( |
+ InvalidationHandler* handler) const { |
+ DCHECK(thread_checker_.CalledOnValidThread()); |
+ return handlers_.HasObserver(handler); |
+} |
+ |
+void InvalidatorRegistrar::DetachFromThreadForTest() { |
+ DCHECK(thread_checker_.CalledOnValidThread()); |
+ thread_checker_.DetachFromThread(); |
+} |
+ |
+} // namespace syncer |