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

Side by Side Diff: components/sync/core/processor_entity_tracker.cc

Issue 2412193002: [Sync] Move SharedModelTypeProcessor to model_impl/. (Closed)
Patch Set: Address comment from Sky. Created 4 years, 2 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
OLDNEW
(Empty)
1 // Copyright 2014 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 "components/sync/core/processor_entity_tracker.h"
6
7 #include "base/base64.h"
8 #include "base/sha1.h"
9 #include "components/sync/base/time.h"
10 #include "components/sync/core/non_blocking_sync_common.h"
11 #include "components/sync/syncable/syncable_util.h"
12
13 namespace syncer {
14
15 namespace {
16
17 void HashSpecifics(const sync_pb::EntitySpecifics& specifics,
18 std::string* hash) {
19 DCHECK_GT(specifics.ByteSize(), 0);
20 base::Base64Encode(base::SHA1HashString(specifics.SerializeAsString()), hash);
21 }
22
23 } // namespace
24
25 std::unique_ptr<ProcessorEntityTracker> ProcessorEntityTracker::CreateNew(
26 const std::string& storage_key,
27 const std::string& client_tag_hash,
28 const std::string& id,
29 base::Time creation_time) {
30 // Initialize metadata
31 sync_pb::EntityMetadata metadata;
32 metadata.set_client_tag_hash(client_tag_hash);
33 if (!id.empty())
34 metadata.set_server_id(id);
35 metadata.set_sequence_number(0);
36 metadata.set_acked_sequence_number(0);
37 metadata.set_server_version(kUncommittedVersion);
38 metadata.set_creation_time(TimeToProtoTime(creation_time));
39
40 return std::unique_ptr<ProcessorEntityTracker>(
41 new ProcessorEntityTracker(storage_key, &metadata));
42 }
43
44 std::unique_ptr<ProcessorEntityTracker>
45 ProcessorEntityTracker::CreateFromMetadata(const std::string& storage_key,
46 sync_pb::EntityMetadata* metadata) {
47 return std::unique_ptr<ProcessorEntityTracker>(
48 new ProcessorEntityTracker(storage_key, metadata));
49 }
50
51 ProcessorEntityTracker::ProcessorEntityTracker(
52 const std::string& storage_key,
53 sync_pb::EntityMetadata* metadata)
54 : storage_key_(storage_key),
55 commit_requested_sequence_number_(metadata->acked_sequence_number()) {
56 DCHECK(metadata->has_client_tag_hash());
57 DCHECK(metadata->has_creation_time());
58 metadata_.Swap(metadata);
59 }
60
61 ProcessorEntityTracker::~ProcessorEntityTracker() {}
62
63 void ProcessorEntityTracker::CacheCommitData(EntityData* data) {
64 DCHECK(data);
65 if (data->client_tag_hash.empty()) {
66 data->client_tag_hash = metadata_.client_tag_hash();
67 }
68 CacheCommitData(data->PassToPtr());
69 }
70
71 void ProcessorEntityTracker::CacheCommitData(const EntityDataPtr& data_ptr) {
72 DCHECK(RequiresCommitData());
73 commit_data_ = data_ptr;
74 DCHECK(HasCommitData());
75 }
76
77 bool ProcessorEntityTracker::HasCommitData() const {
78 return !commit_data_->client_tag_hash.empty();
79 }
80
81 bool ProcessorEntityTracker::MatchesData(const EntityData& data) const {
82 return metadata_.is_deleted() ? data.is_deleted()
83 : MatchesSpecificsHash(data.specifics);
84 }
85
86 bool ProcessorEntityTracker::MatchesBaseData(const EntityData& data) const {
87 DCHECK(IsUnsynced());
88 if (data.is_deleted() || metadata_.base_specifics_hash().empty()) {
89 return false;
90 }
91 std::string hash;
92 HashSpecifics(data.specifics, &hash);
93 return hash == metadata_.base_specifics_hash();
94 }
95
96 bool ProcessorEntityTracker::IsUnsynced() const {
97 return metadata_.sequence_number() > metadata_.acked_sequence_number();
98 }
99
100 bool ProcessorEntityTracker::RequiresCommitRequest() const {
101 return metadata_.sequence_number() > commit_requested_sequence_number_;
102 }
103
104 bool ProcessorEntityTracker::RequiresCommitData() const {
105 return RequiresCommitRequest() && !HasCommitData() && !metadata_.is_deleted();
106 }
107
108 bool ProcessorEntityTracker::CanClearMetadata() const {
109 return metadata_.is_deleted() && !IsUnsynced();
110 }
111
112 bool ProcessorEntityTracker::UpdateIsReflection(int64_t update_version) const {
113 return metadata_.server_version() >= update_version;
114 }
115
116 void ProcessorEntityTracker::RecordIgnoredUpdate(
117 const UpdateResponseData& update) {
118 DCHECK(metadata_.server_id().empty() ||
119 metadata_.server_id() == update.entity->id);
120 metadata_.set_server_id(update.entity->id);
121 metadata_.set_server_version(update.response_version);
122 // Either these already matched, acked was just bumped to squash a pending
123 // commit and this should follow, or the pending commit needs to be requeued.
124 commit_requested_sequence_number_ = metadata_.acked_sequence_number();
125 }
126
127 void ProcessorEntityTracker::RecordAcceptedUpdate(
128 const UpdateResponseData& update) {
129 DCHECK(!IsUnsynced());
130 RecordIgnoredUpdate(update);
131 metadata_.set_is_deleted(update.entity->is_deleted());
132 metadata_.set_modification_time(
133 TimeToProtoTime(update.entity->modification_time));
134 UpdateSpecificsHash(update.entity->specifics);
135 }
136
137 void ProcessorEntityTracker::RecordForcedUpdate(
138 const UpdateResponseData& update) {
139 DCHECK(IsUnsynced());
140 // There was a conflict and the server just won it. Explicitly ack all
141 // pending commits so they are never enqueued again.
142 metadata_.set_acked_sequence_number(metadata_.sequence_number());
143 commit_data_.reset();
144 RecordAcceptedUpdate(update);
145 }
146
147 void ProcessorEntityTracker::MakeLocalChange(std::unique_ptr<EntityData> data) {
148 DCHECK(!metadata_.client_tag_hash().empty());
149 DCHECK_EQ(metadata_.client_tag_hash(), data->client_tag_hash);
150
151 if (data->modification_time.is_null()) {
152 data->modification_time = base::Time::Now();
153 }
154
155 IncrementSequenceNumber();
156 UpdateSpecificsHash(data->specifics);
157 metadata_.set_modification_time(TimeToProtoTime(data->modification_time));
158 metadata_.set_is_deleted(false);
159
160 data->id = metadata_.server_id();
161 data->creation_time = ProtoTimeToTime(metadata_.creation_time());
162 commit_data_.reset();
163 CacheCommitData(data.get());
164 }
165
166 void ProcessorEntityTracker::Delete() {
167 IncrementSequenceNumber();
168 metadata_.set_modification_time(TimeToProtoTime(base::Time::Now()));
169 metadata_.set_is_deleted(true);
170 metadata_.clear_specifics_hash();
171 // Clear any cached pending commit data.
172 commit_data_.reset();
173 }
174
175 void ProcessorEntityTracker::InitializeCommitRequestData(
176 CommitRequestData* request) {
177 if (!metadata_.is_deleted()) {
178 DCHECK(HasCommitData());
179 DCHECK_EQ(commit_data_->client_tag_hash, metadata_.client_tag_hash());
180 request->entity = commit_data_;
181 } else {
182 // Make an EntityData with empty specifics to indicate deletion. This is
183 // done lazily here to simplify loading a pending deletion on startup.
184 EntityData data;
185 data.client_tag_hash = metadata_.client_tag_hash();
186 data.id = metadata_.server_id();
187 data.creation_time = ProtoTimeToTime(metadata_.creation_time());
188 data.modification_time = ProtoTimeToTime(metadata_.modification_time());
189 request->entity = data.PassToPtr();
190 }
191
192 request->sequence_number = metadata_.sequence_number();
193 request->base_version = metadata_.server_version();
194 request->specifics_hash = metadata_.specifics_hash();
195 commit_requested_sequence_number_ = metadata_.sequence_number();
196 }
197
198 void ProcessorEntityTracker::ReceiveCommitResponse(
199 const CommitResponseData& data) {
200 DCHECK_EQ(metadata_.client_tag_hash(), data.client_tag_hash);
201 DCHECK_GT(data.sequence_number, metadata_.acked_sequence_number());
202 DCHECK_GT(data.response_version, metadata_.server_version());
203
204 // The server can assign us a new ID in a commit response.
205 metadata_.set_server_id(data.id);
206 metadata_.set_acked_sequence_number(data.sequence_number);
207 metadata_.set_server_version(data.response_version);
208 if (!IsUnsynced()) {
209 // Clear pending commit data if there hasn't been another commit request
210 // since the one that is currently getting acked.
211 commit_data_.reset();
212 metadata_.clear_base_specifics_hash();
213 } else {
214 metadata_.set_base_specifics_hash(data.specifics_hash);
215 }
216 }
217
218 void ProcessorEntityTracker::ClearTransientSyncState() {
219 // If we have any unacknowledged commit requests outstanding, they've been
220 // dropped and we should forget about them.
221 commit_requested_sequence_number_ = metadata_.acked_sequence_number();
222 }
223
224 void ProcessorEntityTracker::IncrementSequenceNumber() {
225 DCHECK(metadata_.has_sequence_number());
226 if (!IsUnsynced()) {
227 // Update the base specifics hash if this entity wasn't already out of sync.
228 metadata_.set_base_specifics_hash(metadata_.specifics_hash());
229 }
230 metadata_.set_sequence_number(metadata_.sequence_number() + 1);
231 }
232
233 bool ProcessorEntityTracker::MatchesSpecificsHash(
234 const sync_pb::EntitySpecifics& specifics) const {
235 DCHECK(!metadata_.is_deleted());
236 std::string hash;
237 HashSpecifics(specifics, &hash);
238 return hash == metadata_.specifics_hash();
239 }
240
241 void ProcessorEntityTracker::UpdateSpecificsHash(
242 const sync_pb::EntitySpecifics& specifics) {
243 if (specifics.ByteSize() > 0) {
244 HashSpecifics(specifics, metadata_.mutable_specifics_hash());
245 } else {
246 metadata_.clear_specifics_hash();
247 }
248 }
249
250 } // namespace syncer
OLDNEW
« no previous file with comments | « components/sync/core/processor_entity_tracker.h ('k') | components/sync/core/processor_entity_tracker_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698