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

Side by Side Diff: sync/sessions/data_type_tracker.cc

Issue 2130453004: [Sync] Move //sync to //components/sync. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Rebase. Created 4 years, 4 months 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
« no previous file with comments | « sync/sessions/data_type_tracker.h ('k') | sync/sessions/debug_info_getter.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright 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/sessions/data_type_tracker.h"
6
7 #include <stddef.h>
8
9 #include <algorithm>
10
11 #include "base/logging.h"
12 #include "sync/internal_api/public/base/invalidation_interface.h"
13 #include "sync/sessions/nudge_tracker.h"
14
15 namespace syncer {
16 namespace sessions {
17
18 DataTypeTracker::DataTypeTracker()
19 : local_nudge_count_(0),
20 local_refresh_request_count_(0),
21 payload_buffer_size_(NudgeTracker::kDefaultMaxPayloadsPerType),
22 initial_sync_required_(false),
23 sync_required_to_resolve_conflict_(false) {
24 }
25
26 DataTypeTracker::~DataTypeTracker() { }
27
28 base::TimeDelta DataTypeTracker::RecordLocalChange() {
29 local_nudge_count_++;
30 return nudge_delay_;
31 }
32
33 void DataTypeTracker::RecordLocalRefreshRequest() {
34 local_refresh_request_count_++;
35 }
36
37 void DataTypeTracker::RecordRemoteInvalidation(
38 std::unique_ptr<InvalidationInterface> incoming) {
39 DCHECK(incoming);
40
41 // Merge the incoming invalidation into our list of pending invalidations.
42 //
43 // We won't use STL algorithms here because our concept of equality doesn't
44 // quite fit the expectations of set_intersection. In particular, two
45 // invalidations can be equal according to the SingleObjectInvalidationSet's
46 // rules (ie. have equal versions), but still have different AckHandle values
47 // and need to be acknowledged separately.
48 //
49 // The invalidations service can only track one outsanding invalidation per
50 // type and version, so the acknowledgement here should be redundant. We'll
51 // acknowledge them anyway since it should do no harm, and makes this code a
52 // bit easier to test.
53 //
54 // Overlaps should be extremely rare for most invalidations. They can happen
55 // for unknown version invalidations, though.
56
57 ScopedVector<InvalidationInterface>::iterator it =
58 pending_invalidations_.begin();
59
60 // Find the lower bound.
61 while (it != pending_invalidations_.end() &&
62 InvalidationInterface::LessThanByVersion(**it, *incoming)) {
63 it++;
64 }
65
66 if (it != pending_invalidations_.end() &&
67 !InvalidationInterface::LessThanByVersion(*incoming, **it) &&
68 !InvalidationInterface::LessThanByVersion(**it, *incoming)) {
69 // Incoming overlaps with existing. Either both are unknown versions
70 // (likely) or these two have the same version number (very unlikely).
71 // Acknowledge and overwrite existing.
72
73 // Insert before the existing and get iterator to inserted.
74 ScopedVector<InvalidationInterface>::iterator it2 =
75 pending_invalidations_.insert(it, incoming.release());
76
77 // Increment that iterator to the old one, then acknowledge and remove it.
78 ++it2;
79 (*it2)->Acknowledge();
80 pending_invalidations_.erase(it2);
81 } else {
82 // The incoming has a version not in the pending_invalidations_ list.
83 // Add it to the list at the proper position.
84 pending_invalidations_.insert(it, incoming.release());
85 }
86
87 // The incoming invalidation may have caused us to exceed our buffer size.
88 // Trim some items from our list, if necessary.
89 while (pending_invalidations_.size() > payload_buffer_size_) {
90 last_dropped_invalidation_.reset(pending_invalidations_.front());
91 last_dropped_invalidation_->Drop();
92 pending_invalidations_.weak_erase(pending_invalidations_.begin());
93 }
94 }
95
96 void DataTypeTracker::RecordInitialSyncRequired() {
97 initial_sync_required_ = true;
98 }
99
100 void DataTypeTracker::RecordCommitConflict() {
101 sync_required_to_resolve_conflict_ = true;
102 }
103
104 void DataTypeTracker::RecordSuccessfulSyncCycle() {
105 // If we were throttled, then we would have been excluded from this cycle's
106 // GetUpdates and Commit actions. Our state remains unchanged.
107 if (IsThrottled())
108 return;
109
110 local_nudge_count_ = 0;
111 local_refresh_request_count_ = 0;
112
113 // TODO(rlarocque): If we want this to be correct even if we should happen to
114 // crash before writing all our state, we should wait until the results of
115 // this sync cycle have been written to disk before updating the invalidations
116 // state. See crbug.com/324996.
117 for (ScopedVector<InvalidationInterface>::const_iterator it =
118 pending_invalidations_.begin();
119 it != pending_invalidations_.end();
120 ++it) {
121 (*it)->Acknowledge();
122 }
123 pending_invalidations_.clear();
124
125 if (last_dropped_invalidation_) {
126 last_dropped_invalidation_->Acknowledge();
127 last_dropped_invalidation_.reset();
128 }
129
130 initial_sync_required_ = false;
131 sync_required_to_resolve_conflict_ = false;
132 }
133
134 // This limit will take effect on all future invalidations received.
135 void DataTypeTracker::UpdatePayloadBufferSize(size_t new_size) {
136 payload_buffer_size_ = new_size;
137 }
138
139 bool DataTypeTracker::IsSyncRequired() const {
140 return !IsThrottled() && (HasLocalChangePending() || IsGetUpdatesRequired());
141 }
142
143 bool DataTypeTracker::IsGetUpdatesRequired() const {
144 return !IsThrottled() &&
145 (HasRefreshRequestPending() || HasPendingInvalidation() ||
146 IsInitialSyncRequired() || IsSyncRequiredToResolveConflict());
147 }
148
149 bool DataTypeTracker::HasLocalChangePending() const {
150 return local_nudge_count_ > 0;
151 }
152
153 bool DataTypeTracker::HasRefreshRequestPending() const {
154 return local_refresh_request_count_ > 0;
155 }
156
157 bool DataTypeTracker::HasPendingInvalidation() const {
158 return !pending_invalidations_.empty() || last_dropped_invalidation_;
159 }
160
161 bool DataTypeTracker::IsInitialSyncRequired() const {
162 return initial_sync_required_;
163 }
164
165 bool DataTypeTracker::IsSyncRequiredToResolveConflict() const {
166 return sync_required_to_resolve_conflict_;
167 }
168
169 void DataTypeTracker::SetLegacyNotificationHint(
170 sync_pb::DataTypeProgressMarker* progress) const {
171 DCHECK(!IsThrottled())
172 << "We should not make requests if the type is throttled.";
173
174 if (!pending_invalidations_.empty() &&
175 !pending_invalidations_.back()->IsUnknownVersion()) {
176 // The old-style source info can contain only one hint per type. We grab
177 // the most recent, to mimic the old coalescing behaviour.
178 progress->set_notification_hint(
179 pending_invalidations_.back()->GetPayload());
180 } else if (HasLocalChangePending()) {
181 // The old-style source info sent up an empty string (as opposed to
182 // nothing at all) when the type was locally nudged, but had not received
183 // any invalidations.
184 progress->set_notification_hint(std::string());
185 }
186 }
187
188 void DataTypeTracker::FillGetUpdatesTriggersMessage(
189 sync_pb::GetUpdateTriggers* msg) const {
190 // Fill the list of payloads, if applicable. The payloads must be ordered
191 // oldest to newest, so we insert them in the same order as we've been storing
192 // them internally.
193 for (ScopedVector<InvalidationInterface>::const_iterator it =
194 pending_invalidations_.begin();
195 it != pending_invalidations_.end();
196 ++it) {
197 if (!(*it)->IsUnknownVersion()) {
198 msg->add_notification_hint((*it)->GetPayload());
199 }
200 }
201
202 msg->set_server_dropped_hints(
203 !pending_invalidations_.empty() &&
204 (*pending_invalidations_.begin())->IsUnknownVersion());
205 msg->set_client_dropped_hints(!!last_dropped_invalidation_);
206 msg->set_local_modification_nudges(local_nudge_count_);
207 msg->set_datatype_refresh_nudges(local_refresh_request_count_);
208 msg->set_initial_sync_in_progress(initial_sync_required_);
209 msg->set_sync_for_resolve_conflict_in_progress(
210 sync_required_to_resolve_conflict_);
211 }
212
213 bool DataTypeTracker::IsThrottled() const {
214 return !unthrottle_time_.is_null();
215 }
216
217 base::TimeDelta DataTypeTracker::GetTimeUntilUnthrottle(
218 base::TimeTicks now) const {
219 if (!IsThrottled()) {
220 NOTREACHED();
221 return base::TimeDelta::FromSeconds(0);
222 }
223 return std::max(base::TimeDelta::FromSeconds(0),
224 unthrottle_time_ - now);
225 }
226
227 void DataTypeTracker::ThrottleType(base::TimeDelta duration,
228 base::TimeTicks now) {
229 unthrottle_time_ = std::max(unthrottle_time_, now + duration);
230 }
231
232 void DataTypeTracker::UpdateThrottleState(base::TimeTicks now) {
233 if (now >= unthrottle_time_) {
234 unthrottle_time_ = base::TimeTicks();
235 }
236 }
237
238 void DataTypeTracker::UpdateLocalNudgeDelay(base::TimeDelta delay) {
239 nudge_delay_ = delay;
240 }
241
242 } // namespace sessions
243 } // namespace syncer
OLDNEW
« no previous file with comments | « sync/sessions/data_type_tracker.h ('k') | sync/sessions/debug_info_getter.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698