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/notifier/invalidator_registrar.h" | 5 #include "sync/notifier/invalidator_registrar.h" |
6 | 6 |
7 #include <cstddef> | 7 #include <cstddef> |
8 #include <utility> | 8 #include <utility> |
9 | 9 |
10 #include "base/logging.h" | 10 #include "base/logging.h" |
11 #include "sync/notifier/object_id_invalidation_map.h" | |
11 | 12 |
12 namespace syncer { | 13 namespace syncer { |
13 | 14 |
14 InvalidatorRegistrar::InvalidatorRegistrar() | 15 InvalidatorRegistrar::InvalidatorRegistrar() |
15 : state_(DEFAULT_INVALIDATION_ERROR) {} | 16 : state_(DEFAULT_INVALIDATION_ERROR) {} |
16 | 17 |
17 InvalidatorRegistrar::~InvalidatorRegistrar() { | 18 InvalidatorRegistrar::~InvalidatorRegistrar() { |
18 DCHECK(thread_checker_.CalledOnValidThread()); | 19 DCHECK(thread_checker_.CalledOnValidThread()); |
19 CHECK(!handlers_.might_have_observers()); | 20 CHECK(!handlers_.might_have_observers()); |
20 // |id_to_handler_map_| may be non-empty but that's okay. | 21 CHECK(handler_to_id_map_.empty()); |
tim (not reviewing)
2013/09/20 21:53:46
Hmm.. remind me what was happening here? Why was
rlarocque
2013/09/23 18:38:19
In this part of the code, "registration" is an ove
tim (not reviewing)
2013/09/24 21:16:54
I see. So the two parts are separate in your new
| |
21 } | 22 } |
22 | 23 |
23 void InvalidatorRegistrar::RegisterHandler(InvalidationHandler* handler) { | 24 void InvalidatorRegistrar::RegisterHandler(InvalidationHandler* handler) { |
24 DCHECK(thread_checker_.CalledOnValidThread()); | 25 DCHECK(thread_checker_.CalledOnValidThread()); |
25 CHECK(handler); | 26 CHECK(handler); |
26 CHECK(!handlers_.HasObserver(handler)); | 27 CHECK(!handlers_.HasObserver(handler)); |
27 handlers_.AddObserver(handler); | 28 handlers_.AddObserver(handler); |
28 } | 29 } |
29 | 30 |
30 void InvalidatorRegistrar::UpdateRegisteredIds( | 31 void InvalidatorRegistrar::UpdateRegisteredIds( |
31 InvalidationHandler* handler, | 32 InvalidationHandler* handler, |
32 const ObjectIdSet& ids) { | 33 const ObjectIdSet& ids) { |
33 DCHECK(thread_checker_.CalledOnValidThread()); | 34 DCHECK(thread_checker_.CalledOnValidThread()); |
34 CHECK(handler); | 35 CHECK(handler); |
35 CHECK(handlers_.HasObserver(handler)); | 36 CHECK(handlers_.HasObserver(handler)); |
36 // Remove all existing entries for |handler|. | 37 |
37 for (IdHandlerMap::iterator it = id_to_handler_map_.begin(); | 38 for (HandlerIdMap::const_iterator it = handler_to_id_map_.begin(); |
38 it != id_to_handler_map_.end(); ) { | 39 it != handler_to_id_map_.end(); ++it) { |
39 if (it->second == handler) { | 40 if (it->first == handler) { |
40 IdHandlerMap::iterator erase_it = it; | 41 continue; |
41 ++it; | |
42 id_to_handler_map_.erase(erase_it); | |
43 } else { | |
44 ++it; | |
45 } | 42 } |
43 | |
44 std::vector<invalidation::ObjectId> intersection; | |
45 std::set_intersection( | |
46 it->second.begin(), it->second.end(), | |
47 ids.begin(), ids.end(), | |
48 intersection.begin(), ObjectIdLessThan()); | |
49 CHECK(intersection.empty()) | |
50 << "Duplicate registration: trying to register " | |
51 << ObjectIdToString(*intersection.begin()) << " for " | |
52 << handler << " when it's already registered for " | |
53 << it->first; | |
46 } | 54 } |
47 | 55 |
48 // Now add the entries for |handler|. We keep track of the last insertion | 56 if (ids.empty()) { |
49 // point so we only traverse the map once to insert all the new entries. | 57 handler_to_id_map_.erase(handler); |
50 IdHandlerMap::iterator insert_it = id_to_handler_map_.begin(); | 58 } else { |
51 for (ObjectIdSet::const_iterator it = ids.begin(); it != ids.end(); ++it) { | 59 handler_to_id_map_[handler] = ids; |
52 insert_it = | |
53 id_to_handler_map_.insert(insert_it, std::make_pair(*it, handler)); | |
54 CHECK_EQ(handler, insert_it->second) | |
55 << "Duplicate registration: trying to register " | |
56 << ObjectIdToString(insert_it->first) << " for " | |
57 << handler << " when it's already registered for " | |
58 << insert_it->second; | |
59 } | 60 } |
60 } | 61 } |
61 | 62 |
62 void InvalidatorRegistrar::UnregisterHandler(InvalidationHandler* handler) { | 63 void InvalidatorRegistrar::UnregisterHandler(InvalidationHandler* handler) { |
63 DCHECK(thread_checker_.CalledOnValidThread()); | 64 DCHECK(thread_checker_.CalledOnValidThread()); |
64 CHECK(handler); | 65 CHECK(handler); |
65 CHECK(handlers_.HasObserver(handler)); | 66 CHECK(handlers_.HasObserver(handler)); |
66 handlers_.RemoveObserver(handler); | 67 handlers_.RemoveObserver(handler); |
68 handler_to_id_map_.erase(handler); | |
67 } | 69 } |
68 | 70 |
69 ObjectIdSet InvalidatorRegistrar::GetRegisteredIds( | 71 ObjectIdSet InvalidatorRegistrar::GetRegisteredIds( |
70 InvalidationHandler* handler) const { | 72 InvalidationHandler* handler) const { |
71 DCHECK(thread_checker_.CalledOnValidThread()); | 73 DCHECK(thread_checker_.CalledOnValidThread()); |
72 ObjectIdSet registered_ids; | 74 HandlerIdMap::const_iterator lookup = handler_to_id_map_.find(handler); |
73 for (IdHandlerMap::const_iterator it = id_to_handler_map_.begin(); | 75 if (lookup != handler_to_id_map_.end()) { |
74 it != id_to_handler_map_.end(); ++it) { | 76 return lookup->second; |
75 if (it->second == handler) { | 77 } else { |
76 registered_ids.insert(it->first); | 78 return ObjectIdSet(); |
77 } | |
78 } | 79 } |
79 return registered_ids; | |
80 } | 80 } |
81 | 81 |
82 ObjectIdSet InvalidatorRegistrar::GetAllRegisteredIds() const { | 82 ObjectIdSet InvalidatorRegistrar::GetAllRegisteredIds() const { |
83 DCHECK(thread_checker_.CalledOnValidThread()); | 83 DCHECK(thread_checker_.CalledOnValidThread()); |
84 ObjectIdSet registered_ids; | 84 ObjectIdSet registered_ids; |
85 for (IdHandlerMap::const_iterator it = id_to_handler_map_.begin(); | 85 for (HandlerIdMap::const_iterator it = handler_to_id_map_.begin(); |
86 it != id_to_handler_map_.end(); ++it) { | 86 it != handler_to_id_map_.end(); ++it) { |
87 registered_ids.insert(it->first); | 87 registered_ids.insert(it->second.begin(), it->second.end()); |
88 } | 88 } |
89 return registered_ids; | 89 return registered_ids; |
90 } | 90 } |
91 | 91 |
92 void InvalidatorRegistrar::DispatchInvalidationsToHandlers( | 92 void InvalidatorRegistrar::DispatchInvalidationsToHandlers( |
93 const ObjectIdInvalidationMap& invalidation_map) { | 93 const ObjectIdInvalidationMap& invalidation_map) { |
tim (not reviewing)
2013/09/20 21:53:46
So, |invalidation_map| contains all the invalidati
rlarocque
2013/09/23 18:38:19
Correct.
| |
94 DCHECK(thread_checker_.CalledOnValidThread()); | 94 DCHECK(thread_checker_.CalledOnValidThread()); |
95 // If we have no handlers, there's nothing to do. | 95 // If we have no handlers, there's nothing to do. |
96 if (!handlers_.might_have_observers()) { | 96 if (!handlers_.might_have_observers()) { |
97 return; | 97 return; |
98 } | 98 } |
99 | 99 |
100 typedef std::map<InvalidationHandler*, ObjectIdInvalidationMap> DispatchMap; | 100 for (HandlerIdMap::iterator it = handler_to_id_map_.begin(); |
101 DispatchMap dispatch_map; | 101 it != handler_to_id_map_.end(); ++it) { |
102 for (ObjectIdInvalidationMap::const_iterator it = invalidation_map.begin(); | 102 ObjectIdInvalidationMap to_emit = invalidation_map.WithObjects(it->second); |
103 it != invalidation_map.end(); ++it) { | 103 if (!to_emit.Empty()) { |
104 InvalidationHandler* const handler = ObjectIdToHandler(it->first); | 104 it->first->OnIncomingInvalidation(to_emit); |
105 // Filter out invalidations for IDs with no handler. | 105 } |
106 if (handler) | |
107 dispatch_map[handler].insert(*it); | |
108 } | |
109 | |
110 // Emit invalidations only for handlers in |handlers_|. | |
111 ObserverListBase<InvalidationHandler>::Iterator it(handlers_); | |
112 InvalidationHandler* handler = NULL; | |
113 while ((handler = it.GetNext()) != NULL) { | |
114 DispatchMap::const_iterator dispatch_it = dispatch_map.find(handler); | |
115 if (dispatch_it != dispatch_map.end()) | |
116 handler->OnIncomingInvalidation(dispatch_it->second); | |
117 } | 106 } |
118 } | 107 } |
119 | 108 |
120 void InvalidatorRegistrar::UpdateInvalidatorState(InvalidatorState state) { | 109 void InvalidatorRegistrar::UpdateInvalidatorState(InvalidatorState state) { |
121 DCHECK(thread_checker_.CalledOnValidThread()); | 110 DCHECK(thread_checker_.CalledOnValidThread()); |
122 DVLOG(1) << "New invalidator state: " << InvalidatorStateToString(state_) | 111 DVLOG(1) << "New invalidator state: " << InvalidatorStateToString(state_) |
123 << " -> " << InvalidatorStateToString(state); | 112 << " -> " << InvalidatorStateToString(state); |
124 state_ = state; | 113 state_ = state; |
125 FOR_EACH_OBSERVER(InvalidationHandler, handlers_, | 114 FOR_EACH_OBSERVER(InvalidationHandler, handlers_, |
126 OnInvalidatorStateChange(state)); | 115 OnInvalidatorStateChange(state)); |
127 } | 116 } |
128 | 117 |
129 InvalidatorState InvalidatorRegistrar::GetInvalidatorState() const { | 118 InvalidatorState InvalidatorRegistrar::GetInvalidatorState() const { |
130 DCHECK(thread_checker_.CalledOnValidThread()); | 119 DCHECK(thread_checker_.CalledOnValidThread()); |
131 return state_; | 120 return state_; |
132 } | 121 } |
133 | 122 |
134 bool InvalidatorRegistrar::IsHandlerRegisteredForTest( | 123 bool InvalidatorRegistrar::IsHandlerRegisteredForTest( |
135 InvalidationHandler* handler) const { | 124 InvalidationHandler* handler) const { |
136 DCHECK(thread_checker_.CalledOnValidThread()); | 125 DCHECK(thread_checker_.CalledOnValidThread()); |
137 return handlers_.HasObserver(handler); | 126 return handlers_.HasObserver(handler); |
138 } | 127 } |
139 | 128 |
140 void InvalidatorRegistrar::DetachFromThreadForTest() { | 129 void InvalidatorRegistrar::DetachFromThreadForTest() { |
141 DCHECK(thread_checker_.CalledOnValidThread()); | 130 DCHECK(thread_checker_.CalledOnValidThread()); |
142 thread_checker_.DetachFromThread(); | 131 thread_checker_.DetachFromThread(); |
143 } | 132 } |
144 | 133 |
145 InvalidationHandler* InvalidatorRegistrar::ObjectIdToHandler( | |
146 const invalidation::ObjectId& id) { | |
147 DCHECK(thread_checker_.CalledOnValidThread()); | |
148 IdHandlerMap::const_iterator it = id_to_handler_map_.find(id); | |
149 return (it == id_to_handler_map_.end()) ? NULL : it->second; | |
150 } | |
151 | |
152 } // namespace syncer | 134 } // namespace syncer |
OLD | NEW |