OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 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 | 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/syncable/model_neutral_mutable_entry.h" | 5 #include "components/sync/syncable/model_neutral_mutable_entry.h" |
6 | 6 |
7 #include <stddef.h> | 7 #include <stddef.h> |
8 #include <stdint.h> | 8 #include <stdint.h> |
9 | 9 |
10 #include <string> | 10 #include <string> |
11 | 11 |
12 #include "sync/internal_api/public/base/unique_position.h" | 12 #include "components/sync/base/unique_position.h" |
13 #include "sync/syncable/directory.h" | 13 #include "components/sync/syncable/directory.h" |
14 #include "sync/syncable/scoped_kernel_lock.h" | 14 #include "components/sync/syncable/scoped_kernel_lock.h" |
15 #include "sync/syncable/syncable_changes_version.h" | 15 #include "components/sync/syncable/syncable_changes_version.h" |
16 #include "sync/syncable/syncable_util.h" | 16 #include "components/sync/syncable/syncable_util.h" |
17 #include "sync/syncable/syncable_write_transaction.h" | 17 #include "components/sync/syncable/syncable_write_transaction.h" |
18 | 18 |
19 using std::string; | 19 using std::string; |
20 | 20 |
21 namespace syncer { | 21 namespace syncer { |
22 | 22 |
23 namespace syncable { | 23 namespace syncable { |
24 | 24 |
25 ModelNeutralMutableEntry::ModelNeutralMutableEntry(BaseWriteTransaction* trans, | 25 ModelNeutralMutableEntry::ModelNeutralMutableEntry(BaseWriteTransaction* trans, |
26 CreateNewUpdateItem, | 26 CreateNewUpdateItem, |
27 const Id& id) | 27 const Id& id) |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
79 | 79 |
80 if (!trans->directory()->InsertEntry(trans, kernel.get())) { | 80 if (!trans->directory()->InsertEntry(trans, kernel.get())) { |
81 return; // Failed inserting. | 81 return; // Failed inserting. |
82 } | 82 } |
83 | 83 |
84 trans->TrackChangesTo(kernel.get()); | 84 trans->TrackChangesTo(kernel.get()); |
85 | 85 |
86 kernel_ = kernel.release(); | 86 kernel_ = kernel.release(); |
87 } | 87 } |
88 | 88 |
89 ModelNeutralMutableEntry::ModelNeutralMutableEntry( | 89 ModelNeutralMutableEntry::ModelNeutralMutableEntry(BaseWriteTransaction* trans, |
90 BaseWriteTransaction* trans, GetById, const Id& id) | 90 GetById, |
91 : Entry(trans, GET_BY_ID, id), base_write_transaction_(trans) { | 91 const Id& id) |
92 } | 92 : Entry(trans, GET_BY_ID, id), base_write_transaction_(trans) {} |
93 | 93 |
94 ModelNeutralMutableEntry::ModelNeutralMutableEntry(BaseWriteTransaction* trans, | 94 ModelNeutralMutableEntry::ModelNeutralMutableEntry(BaseWriteTransaction* trans, |
95 GetByHandle, | 95 GetByHandle, |
96 int64_t metahandle) | 96 int64_t metahandle) |
97 : Entry(trans, GET_BY_HANDLE, metahandle), base_write_transaction_(trans) {} | 97 : Entry(trans, GET_BY_HANDLE, metahandle), base_write_transaction_(trans) {} |
98 | 98 |
99 ModelNeutralMutableEntry::ModelNeutralMutableEntry( | 99 ModelNeutralMutableEntry::ModelNeutralMutableEntry(BaseWriteTransaction* trans, |
100 BaseWriteTransaction* trans, GetByClientTag, const std::string& tag) | 100 GetByClientTag, |
101 : Entry(trans, GET_BY_CLIENT_TAG, tag), base_write_transaction_(trans) { | 101 const std::string& tag) |
102 } | 102 : Entry(trans, GET_BY_CLIENT_TAG, tag), base_write_transaction_(trans) {} |
103 | 103 |
104 ModelNeutralMutableEntry::ModelNeutralMutableEntry( | 104 ModelNeutralMutableEntry::ModelNeutralMutableEntry(BaseWriteTransaction* trans, |
105 BaseWriteTransaction* trans, GetTypeRoot, ModelType type) | 105 GetTypeRoot, |
106 : Entry(trans, GET_TYPE_ROOT, type), base_write_transaction_(trans) { | 106 ModelType type) |
107 } | 107 : Entry(trans, GET_TYPE_ROOT, type), base_write_transaction_(trans) {} |
108 | 108 |
109 void ModelNeutralMutableEntry::PutBaseVersion(int64_t value) { | 109 void ModelNeutralMutableEntry::PutBaseVersion(int64_t value) { |
110 DCHECK(kernel_); | 110 DCHECK(kernel_); |
111 if (kernel_->ref(BASE_VERSION) != value) { | 111 if (kernel_->ref(BASE_VERSION) != value) { |
112 base_write_transaction_->TrackChangesTo(kernel_); | 112 base_write_transaction_->TrackChangesTo(kernel_); |
113 kernel_->put(BASE_VERSION, value); | 113 kernel_->put(BASE_VERSION, value); |
114 MarkDirty(); | 114 MarkDirty(); |
115 } | 115 } |
116 } | 116 } |
117 | 117 |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
165 | 165 |
166 bool ModelNeutralMutableEntry::PutIsUnsynced(bool value) { | 166 bool ModelNeutralMutableEntry::PutIsUnsynced(bool value) { |
167 DCHECK(kernel_); | 167 DCHECK(kernel_); |
168 if (kernel_->ref(IS_UNSYNCED) != value) { | 168 if (kernel_->ref(IS_UNSYNCED) != value) { |
169 base_write_transaction_->TrackChangesTo(kernel_); | 169 base_write_transaction_->TrackChangesTo(kernel_); |
170 MetahandleSet* index = &dir()->kernel()->unsynced_metahandles; | 170 MetahandleSet* index = &dir()->kernel()->unsynced_metahandles; |
171 | 171 |
172 ScopedKernelLock lock(dir()); | 172 ScopedKernelLock lock(dir()); |
173 if (value) { | 173 if (value) { |
174 if (!SyncAssert(index->insert(kernel_->ref(META_HANDLE)).second, | 174 if (!SyncAssert(index->insert(kernel_->ref(META_HANDLE)).second, |
175 FROM_HERE, | 175 FROM_HERE, "Could not insert", |
176 "Could not insert", | |
177 base_write_transaction())) { | 176 base_write_transaction())) { |
178 return false; | 177 return false; |
179 } | 178 } |
180 } else { | 179 } else { |
181 if (!SyncAssert(1U == index->erase(kernel_->ref(META_HANDLE)), | 180 if (!SyncAssert(1U == index->erase(kernel_->ref(META_HANDLE)), FROM_HERE, |
182 FROM_HERE, | |
183 "Entry Not succesfully erased", | 181 "Entry Not succesfully erased", |
184 base_write_transaction())) { | 182 base_write_transaction())) { |
185 return false; | 183 return false; |
186 } | 184 } |
187 } | 185 } |
188 kernel_->put(IS_UNSYNCED, value); | 186 kernel_->put(IS_UNSYNCED, value); |
189 MarkDirty(); | 187 MarkDirty(); |
190 } | 188 } |
191 return true; | 189 return true; |
192 } | 190 } |
193 | 191 |
194 bool ModelNeutralMutableEntry::PutIsUnappliedUpdate(bool value) { | 192 bool ModelNeutralMutableEntry::PutIsUnappliedUpdate(bool value) { |
195 DCHECK(kernel_); | 193 DCHECK(kernel_); |
196 if (kernel_->ref(IS_UNAPPLIED_UPDATE) != value) { | 194 if (kernel_->ref(IS_UNAPPLIED_UPDATE) != value) { |
197 base_write_transaction_->TrackChangesTo(kernel_); | 195 base_write_transaction_->TrackChangesTo(kernel_); |
198 // Use kernel_->GetServerModelType() instead of | 196 // Use kernel_->GetServerModelType() instead of |
199 // GetServerModelType() as we may trigger some DCHECKs in the | 197 // GetServerModelType() as we may trigger some DCHECKs in the |
200 // latter. | 198 // latter. |
201 MetahandleSet* index = &dir()->kernel()->unapplied_update_metahandles[ | 199 MetahandleSet* index = |
202 kernel_->GetServerModelType()]; | 200 &dir() |
| 201 ->kernel() |
| 202 ->unapplied_update_metahandles[kernel_->GetServerModelType()]; |
203 | 203 |
204 ScopedKernelLock lock(dir()); | 204 ScopedKernelLock lock(dir()); |
205 if (value) { | 205 if (value) { |
206 if (!SyncAssert(index->insert(kernel_->ref(META_HANDLE)).second, | 206 if (!SyncAssert(index->insert(kernel_->ref(META_HANDLE)).second, |
207 FROM_HERE, | 207 FROM_HERE, "Could not insert", |
208 "Could not insert", | |
209 base_write_transaction())) { | 208 base_write_transaction())) { |
210 return false; | 209 return false; |
211 } | 210 } |
212 } else { | 211 } else { |
213 if (!SyncAssert(1U == index->erase(kernel_->ref(META_HANDLE)), | 212 if (!SyncAssert(1U == index->erase(kernel_->ref(META_HANDLE)), FROM_HERE, |
214 FROM_HERE, | |
215 "Entry Not succesfully erased", | 213 "Entry Not succesfully erased", |
216 base_write_transaction())) { | 214 base_write_transaction())) { |
217 return false; | 215 return false; |
218 } | 216 } |
219 } | 217 } |
220 kernel_->put(IS_UNAPPLIED_UPDATE, value); | 218 kernel_->put(IS_UNAPPLIED_UPDATE, value); |
221 MarkDirty(); | 219 MarkDirty(); |
222 } | 220 } |
223 return true; | 221 return true; |
224 } | 222 } |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
273 } | 271 } |
274 | 272 |
275 base_write_transaction_->TrackChangesTo(kernel_); | 273 base_write_transaction_->TrackChangesTo(kernel_); |
276 ScopedKernelLock lock(dir()); | 274 ScopedKernelLock lock(dir()); |
277 // Make sure your new value is not in there already. | 275 // Make sure your new value is not in there already. |
278 if (dir()->kernel()->server_tags_map.find(new_tag) != | 276 if (dir()->kernel()->server_tags_map.find(new_tag) != |
279 dir()->kernel()->server_tags_map.end()) { | 277 dir()->kernel()->server_tags_map.end()) { |
280 DVLOG(1) << "Detected duplicate server tag"; | 278 DVLOG(1) << "Detected duplicate server tag"; |
281 return false; | 279 return false; |
282 } | 280 } |
283 dir()->kernel()->server_tags_map.erase( | 281 dir()->kernel()->server_tags_map.erase(kernel_->ref(UNIQUE_SERVER_TAG)); |
284 kernel_->ref(UNIQUE_SERVER_TAG)); | |
285 kernel_->put(UNIQUE_SERVER_TAG, new_tag); | 282 kernel_->put(UNIQUE_SERVER_TAG, new_tag); |
286 MarkDirty(); | 283 MarkDirty(); |
287 if (!new_tag.empty()) { | 284 if (!new_tag.empty()) { |
288 dir()->kernel()->server_tags_map[new_tag] = kernel_; | 285 dir()->kernel()->server_tags_map[new_tag] = kernel_; |
289 } | 286 } |
290 | 287 |
291 return true; | 288 return true; |
292 } | 289 } |
293 | 290 |
294 bool ModelNeutralMutableEntry::PutUniqueClientTag(const string& new_tag) { | 291 bool ModelNeutralMutableEntry::PutUniqueClientTag(const string& new_tag) { |
295 if (new_tag == kernel_->ref(UNIQUE_CLIENT_TAG)) { | 292 if (new_tag == kernel_->ref(UNIQUE_CLIENT_TAG)) { |
296 return true; | 293 return true; |
297 } | 294 } |
298 | 295 |
299 base_write_transaction_->TrackChangesTo(kernel_); | 296 base_write_transaction_->TrackChangesTo(kernel_); |
300 ScopedKernelLock lock(dir()); | 297 ScopedKernelLock lock(dir()); |
301 // Make sure your new value is not in there already. | 298 // Make sure your new value is not in there already. |
302 if (dir()->kernel()->client_tags_map.find(new_tag) != | 299 if (dir()->kernel()->client_tags_map.find(new_tag) != |
303 dir()->kernel()->client_tags_map.end()) { | 300 dir()->kernel()->client_tags_map.end()) { |
304 DVLOG(1) << "Detected duplicate client tag"; | 301 DVLOG(1) << "Detected duplicate client tag"; |
305 return false; | 302 return false; |
306 } | 303 } |
307 dir()->kernel()->client_tags_map.erase( | 304 dir()->kernel()->client_tags_map.erase(kernel_->ref(UNIQUE_CLIENT_TAG)); |
308 kernel_->ref(UNIQUE_CLIENT_TAG)); | |
309 kernel_->put(UNIQUE_CLIENT_TAG, new_tag); | 305 kernel_->put(UNIQUE_CLIENT_TAG, new_tag); |
310 MarkDirty(); | 306 MarkDirty(); |
311 if (!new_tag.empty()) { | 307 if (!new_tag.empty()) { |
312 dir()->kernel()->client_tags_map[new_tag] = kernel_; | 308 dir()->kernel()->client_tags_map[new_tag] = kernel_; |
313 } | 309 } |
314 | 310 |
315 return true; | 311 return true; |
316 } | 312 } |
317 | 313 |
318 void ModelNeutralMutableEntry::PutUniqueBookmarkTag(const std::string& tag) { | 314 void ModelNeutralMutableEntry::PutUniqueBookmarkTag(const std::string& tag) { |
319 // This unique tag will eventually be used as the unique suffix when adjusting | 315 // This unique tag will eventually be used as the unique suffix when adjusting |
320 // this bookmark's position. Let's make sure it's a valid suffix. | 316 // this bookmark's position. Let's make sure it's a valid suffix. |
321 if (!UniquePosition::IsValidSuffix(tag)) { | 317 if (!UniquePosition::IsValidSuffix(tag)) { |
322 NOTREACHED(); | 318 NOTREACHED(); |
323 return; | 319 return; |
324 } | 320 } |
325 | 321 |
326 // TODO(stanisc): Does this need a call to TrackChangesTo? | 322 // TODO(stanisc): Does this need a call to TrackChangesTo? |
327 | 323 |
328 if (!kernel_->ref(UNIQUE_BOOKMARK_TAG).empty() && | 324 if (!kernel_->ref(UNIQUE_BOOKMARK_TAG).empty() && |
329 tag != kernel_->ref(UNIQUE_BOOKMARK_TAG)) { | 325 tag != kernel_->ref(UNIQUE_BOOKMARK_TAG)) { |
330 // There is only one scenario where our tag is expected to change. That | 326 // There is only one scenario where our tag is expected to change. That |
331 // scenario occurs when our current tag is a non-correct tag assigned during | 327 // scenario occurs when our current tag is a non-correct tag assigned during |
332 // the UniquePosition migration. | 328 // the UniquePosition migration. |
333 std::string migration_generated_tag = | 329 std::string migration_generated_tag = GenerateSyncableBookmarkHash( |
334 GenerateSyncableBookmarkHash(std::string(), | 330 std::string(), kernel_->ref(ID).GetServerId()); |
335 kernel_->ref(ID).GetServerId()); | |
336 DCHECK_EQ(migration_generated_tag, kernel_->ref(UNIQUE_BOOKMARK_TAG)); | 331 DCHECK_EQ(migration_generated_tag, kernel_->ref(UNIQUE_BOOKMARK_TAG)); |
337 } | 332 } |
338 | 333 |
339 kernel_->put(UNIQUE_BOOKMARK_TAG, tag); | 334 kernel_->put(UNIQUE_BOOKMARK_TAG, tag); |
340 MarkDirty(); | 335 MarkDirty(); |
341 } | 336 } |
342 | 337 |
343 void ModelNeutralMutableEntry::PutServerSpecifics( | 338 void ModelNeutralMutableEntry::PutServerSpecifics( |
344 const sync_pb::EntitySpecifics& value) { | 339 const sync_pb::EntitySpecifics& value) { |
345 DCHECK(kernel_); | 340 DCHECK(kernel_); |
346 CHECK(!value.password().has_client_only_encrypted_data()); | 341 CHECK(!value.password().has_client_only_encrypted_data()); |
347 // TODO(ncarter): This is unfortunately heavyweight. Can we do | 342 // TODO(ncarter): This is unfortunately heavyweight. Can we do |
348 // better? | 343 // better? |
349 const std::string& serialized_value = value.SerializeAsString(); | 344 const std::string& serialized_value = value.SerializeAsString(); |
350 if (serialized_value != kernel_->ref(SERVER_SPECIFICS).SerializeAsString()) { | 345 if (serialized_value != kernel_->ref(SERVER_SPECIFICS).SerializeAsString()) { |
351 base_write_transaction_->TrackChangesTo(kernel_); | 346 base_write_transaction_->TrackChangesTo(kernel_); |
352 if (kernel_->ref(IS_UNAPPLIED_UPDATE)) { | 347 if (kernel_->ref(IS_UNAPPLIED_UPDATE)) { |
353 // Remove ourselves from unapplied_update_metahandles with our | 348 // Remove ourselves from unapplied_update_metahandles with our |
354 // old server type. | 349 // old server type. |
355 const ModelType old_server_type = kernel_->GetServerModelType(); | 350 const ModelType old_server_type = kernel_->GetServerModelType(); |
356 const int64_t metahandle = kernel_->ref(META_HANDLE); | 351 const int64_t metahandle = kernel_->ref(META_HANDLE); |
357 size_t erase_count = | 352 size_t erase_count = |
358 dir()->kernel()->unapplied_update_metahandles[old_server_type] | 353 dir()->kernel()->unapplied_update_metahandles[old_server_type].erase( |
359 .erase(metahandle); | 354 metahandle); |
360 DCHECK_EQ(erase_count, 1u); | 355 DCHECK_EQ(erase_count, 1u); |
361 } | 356 } |
362 | 357 |
363 // Check for potential sharing - SERVER_SPECIFICS is often | 358 // Check for potential sharing - SERVER_SPECIFICS is often |
364 // copied from SPECIFICS. | 359 // copied from SPECIFICS. |
365 if (serialized_value == kernel_->ref(SPECIFICS).SerializeAsString()) { | 360 if (serialized_value == kernel_->ref(SPECIFICS).SerializeAsString()) { |
366 kernel_->copy(SPECIFICS, SERVER_SPECIFICS); | 361 kernel_->copy(SPECIFICS, SERVER_SPECIFICS); |
367 } else { | 362 } else { |
368 kernel_->put(SERVER_SPECIFICS, value); | 363 kernel_->put(SERVER_SPECIFICS, value); |
369 } | 364 } |
370 MarkDirty(); | 365 MarkDirty(); |
371 | 366 |
372 if (kernel_->ref(IS_UNAPPLIED_UPDATE)) { | 367 if (kernel_->ref(IS_UNAPPLIED_UPDATE)) { |
373 // Add ourselves back into unapplied_update_metahandles with our | 368 // Add ourselves back into unapplied_update_metahandles with our |
374 // new server type. | 369 // new server type. |
375 const ModelType new_server_type = kernel_->GetServerModelType(); | 370 const ModelType new_server_type = kernel_->GetServerModelType(); |
376 const int64_t metahandle = kernel_->ref(META_HANDLE); | 371 const int64_t metahandle = kernel_->ref(META_HANDLE); |
377 dir()->kernel()->unapplied_update_metahandles[new_server_type] | 372 dir()->kernel()->unapplied_update_metahandles[new_server_type].insert( |
378 .insert(metahandle); | 373 metahandle); |
379 } | 374 } |
380 } | 375 } |
381 } | 376 } |
382 | 377 |
383 void ModelNeutralMutableEntry::PutBaseServerSpecifics( | 378 void ModelNeutralMutableEntry::PutBaseServerSpecifics( |
384 const sync_pb::EntitySpecifics& value) { | 379 const sync_pb::EntitySpecifics& value) { |
385 DCHECK(kernel_); | 380 DCHECK(kernel_); |
386 CHECK(!value.password().has_client_only_encrypted_data()); | 381 CHECK(!value.password().has_client_only_encrypted_data()); |
387 // TODO(ncarter): This is unfortunately heavyweight. Can we do | 382 // TODO(ncarter): This is unfortunately heavyweight. Can we do |
388 // better? | 383 // better? |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
448 dir()->ReindexParentId(base_write_transaction(), kernel_, parent_id); | 443 dir()->ReindexParentId(base_write_transaction(), kernel_, parent_id); |
449 MarkDirty(); | 444 MarkDirty(); |
450 } | 445 } |
451 | 446 |
452 void ModelNeutralMutableEntry::UpdateTransactionVersion(int64_t value) { | 447 void ModelNeutralMutableEntry::UpdateTransactionVersion(int64_t value) { |
453 kernel_->put(TRANSACTION_VERSION, value); | 448 kernel_->put(TRANSACTION_VERSION, value); |
454 MarkDirty(); | 449 MarkDirty(); |
455 } | 450 } |
456 | 451 |
457 ModelNeutralMutableEntry::ModelNeutralMutableEntry(BaseWriteTransaction* trans) | 452 ModelNeutralMutableEntry::ModelNeutralMutableEntry(BaseWriteTransaction* trans) |
458 : Entry(trans), base_write_transaction_(trans) {} | 453 : Entry(trans), base_write_transaction_(trans) {} |
459 | 454 |
460 void ModelNeutralMutableEntry::MarkDirty() { | 455 void ModelNeutralMutableEntry::MarkDirty() { |
461 kernel_->mark_dirty(&dir()->kernel()->dirty_metahandles); | 456 kernel_->mark_dirty(&dir()->kernel()->dirty_metahandles); |
462 } | 457 } |
463 | 458 |
464 } // namespace syncable | 459 } // namespace syncable |
465 | 460 |
466 } // namespace syncer | 461 } // namespace syncer |
OLD | NEW |