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 "sync/syncable/model_neutral_mutable_entry.h" |
6 | 6 |
7 #include <string> | 7 #include <string> |
8 | 8 |
9 #include "sync/internal_api/public/base/unique_position.h" | 9 #include "sync/internal_api/public/base/unique_position.h" |
10 #include "sync/syncable/directory.h" | 10 #include "sync/syncable/directory.h" |
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
98 : Entry(trans, GET_BY_CLIENT_TAG, tag), base_write_transaction_(trans) { | 98 : Entry(trans, GET_BY_CLIENT_TAG, tag), base_write_transaction_(trans) { |
99 } | 99 } |
100 | 100 |
101 ModelNeutralMutableEntry::ModelNeutralMutableEntry( | 101 ModelNeutralMutableEntry::ModelNeutralMutableEntry( |
102 BaseWriteTransaction* trans, GetTypeRoot, ModelType type) | 102 BaseWriteTransaction* trans, GetTypeRoot, ModelType type) |
103 : Entry(trans, GET_TYPE_ROOT, type), base_write_transaction_(trans) { | 103 : Entry(trans, GET_TYPE_ROOT, type), base_write_transaction_(trans) { |
104 } | 104 } |
105 | 105 |
106 void ModelNeutralMutableEntry::PutBaseVersion(int64 value) { | 106 void ModelNeutralMutableEntry::PutBaseVersion(int64 value) { |
107 DCHECK(kernel_); | 107 DCHECK(kernel_); |
108 base_write_transaction_->TrackChangesTo(kernel_); | |
109 if (kernel_->ref(BASE_VERSION) != value) { | 108 if (kernel_->ref(BASE_VERSION) != value) { |
| 109 base_write_transaction_->TrackChangesTo(kernel_); |
110 kernel_->put(BASE_VERSION, value); | 110 kernel_->put(BASE_VERSION, value); |
111 kernel_->mark_dirty(&dir()->kernel()->dirty_metahandles); | 111 MarkDirty(); |
112 } | 112 } |
113 } | 113 } |
114 | 114 |
115 void ModelNeutralMutableEntry::PutServerVersion(int64 value) { | 115 void ModelNeutralMutableEntry::PutServerVersion(int64 value) { |
116 DCHECK(kernel_); | 116 DCHECK(kernel_); |
117 base_write_transaction_->TrackChangesTo(kernel_); | |
118 if (kernel_->ref(SERVER_VERSION) != value) { | 117 if (kernel_->ref(SERVER_VERSION) != value) { |
| 118 base_write_transaction_->TrackChangesTo(kernel_); |
119 ScopedKernelLock lock(dir()); | 119 ScopedKernelLock lock(dir()); |
120 kernel_->put(SERVER_VERSION, value); | 120 kernel_->put(SERVER_VERSION, value); |
121 kernel_->mark_dirty(&dir()->kernel()->dirty_metahandles); | 121 MarkDirty(); |
122 } | 122 } |
123 } | 123 } |
124 | 124 |
125 void ModelNeutralMutableEntry::PutServerMtime(base::Time value) { | 125 void ModelNeutralMutableEntry::PutServerMtime(base::Time value) { |
126 DCHECK(kernel_); | 126 DCHECK(kernel_); |
127 base_write_transaction_->TrackChangesTo(kernel_); | |
128 if (kernel_->ref(SERVER_MTIME) != value) { | 127 if (kernel_->ref(SERVER_MTIME) != value) { |
| 128 base_write_transaction_->TrackChangesTo(kernel_); |
129 kernel_->put(SERVER_MTIME, value); | 129 kernel_->put(SERVER_MTIME, value); |
130 kernel_->mark_dirty(&dir()->kernel()->dirty_metahandles); | 130 MarkDirty(); |
131 } | 131 } |
132 } | 132 } |
133 | 133 |
134 void ModelNeutralMutableEntry::PutServerCtime(base::Time value) { | 134 void ModelNeutralMutableEntry::PutServerCtime(base::Time value) { |
135 DCHECK(kernel_); | 135 DCHECK(kernel_); |
136 base_write_transaction_->TrackChangesTo(kernel_); | |
137 if (kernel_->ref(SERVER_CTIME) != value) { | 136 if (kernel_->ref(SERVER_CTIME) != value) { |
| 137 base_write_transaction_->TrackChangesTo(kernel_); |
138 kernel_->put(SERVER_CTIME, value); | 138 kernel_->put(SERVER_CTIME, value); |
139 kernel_->mark_dirty(&dir()->kernel()->dirty_metahandles); | 139 MarkDirty(); |
140 } | 140 } |
141 } | 141 } |
142 | 142 |
143 bool ModelNeutralMutableEntry::PutId(const Id& value) { | 143 bool ModelNeutralMutableEntry::PutId(const Id& value) { |
144 DCHECK(kernel_); | 144 DCHECK(kernel_); |
145 base_write_transaction_->TrackChangesTo(kernel_); | |
146 if (kernel_->ref(ID) != value) { | 145 if (kernel_->ref(ID) != value) { |
| 146 base_write_transaction_->TrackChangesTo(kernel_); |
147 if (!dir()->ReindexId(base_write_transaction(), kernel_, value)) | 147 if (!dir()->ReindexId(base_write_transaction(), kernel_, value)) |
148 return false; | 148 return false; |
149 kernel_->mark_dirty(&dir()->kernel()->dirty_metahandles); | 149 MarkDirty(); |
150 } | 150 } |
151 return true; | 151 return true; |
152 } | 152 } |
153 | 153 |
154 void ModelNeutralMutableEntry::PutServerParentId(const Id& value) { | 154 void ModelNeutralMutableEntry::PutServerParentId(const Id& value) { |
155 DCHECK(kernel_); | 155 DCHECK(kernel_); |
156 base_write_transaction_->TrackChangesTo(kernel_); | |
157 | |
158 if (kernel_->ref(SERVER_PARENT_ID) != value) { | 156 if (kernel_->ref(SERVER_PARENT_ID) != value) { |
| 157 base_write_transaction_->TrackChangesTo(kernel_); |
159 kernel_->put(SERVER_PARENT_ID, value); | 158 kernel_->put(SERVER_PARENT_ID, value); |
160 kernel_->mark_dirty(&dir()->kernel()->dirty_metahandles); | 159 MarkDirty(); |
161 } | 160 } |
162 } | 161 } |
163 | 162 |
164 bool ModelNeutralMutableEntry::PutIsUnsynced(bool value) { | 163 bool ModelNeutralMutableEntry::PutIsUnsynced(bool value) { |
165 DCHECK(kernel_); | 164 DCHECK(kernel_); |
| 165 if (kernel_->ref(IS_UNSYNCED) != value) { |
166 base_write_transaction_->TrackChangesTo(kernel_); | 166 base_write_transaction_->TrackChangesTo(kernel_); |
167 if (kernel_->ref(IS_UNSYNCED) != value) { | |
168 MetahandleSet* index = &dir()->kernel()->unsynced_metahandles; | 167 MetahandleSet* index = &dir()->kernel()->unsynced_metahandles; |
169 | 168 |
170 ScopedKernelLock lock(dir()); | 169 ScopedKernelLock lock(dir()); |
171 if (value) { | 170 if (value) { |
172 if (!SyncAssert(index->insert(kernel_->ref(META_HANDLE)).second, | 171 if (!SyncAssert(index->insert(kernel_->ref(META_HANDLE)).second, |
173 FROM_HERE, | 172 FROM_HERE, |
174 "Could not insert", | 173 "Could not insert", |
175 base_write_transaction())) { | 174 base_write_transaction())) { |
176 return false; | 175 return false; |
177 } | 176 } |
178 } else { | 177 } else { |
179 if (!SyncAssert(1U == index->erase(kernel_->ref(META_HANDLE)), | 178 if (!SyncAssert(1U == index->erase(kernel_->ref(META_HANDLE)), |
180 FROM_HERE, | 179 FROM_HERE, |
181 "Entry Not succesfully erased", | 180 "Entry Not succesfully erased", |
182 base_write_transaction())) { | 181 base_write_transaction())) { |
183 return false; | 182 return false; |
184 } | 183 } |
185 } | 184 } |
186 kernel_->put(IS_UNSYNCED, value); | 185 kernel_->put(IS_UNSYNCED, value); |
187 kernel_->mark_dirty(&dir()->kernel()->dirty_metahandles); | 186 MarkDirty(); |
188 } | 187 } |
189 return true; | 188 return true; |
190 } | 189 } |
191 | 190 |
192 bool ModelNeutralMutableEntry::PutIsUnappliedUpdate(bool value) { | 191 bool ModelNeutralMutableEntry::PutIsUnappliedUpdate(bool value) { |
193 DCHECK(kernel_); | 192 DCHECK(kernel_); |
194 base_write_transaction_->TrackChangesTo(kernel_); | |
195 if (kernel_->ref(IS_UNAPPLIED_UPDATE) != value) { | 193 if (kernel_->ref(IS_UNAPPLIED_UPDATE) != value) { |
| 194 base_write_transaction_->TrackChangesTo(kernel_); |
196 // Use kernel_->GetServerModelType() instead of | 195 // Use kernel_->GetServerModelType() instead of |
197 // GetServerModelType() as we may trigger some DCHECKs in the | 196 // GetServerModelType() as we may trigger some DCHECKs in the |
198 // latter. | 197 // latter. |
199 MetahandleSet* index = &dir()->kernel()->unapplied_update_metahandles[ | 198 MetahandleSet* index = &dir()->kernel()->unapplied_update_metahandles[ |
200 kernel_->GetServerModelType()]; | 199 kernel_->GetServerModelType()]; |
201 | 200 |
202 ScopedKernelLock lock(dir()); | 201 ScopedKernelLock lock(dir()); |
203 if (value) { | 202 if (value) { |
204 if (!SyncAssert(index->insert(kernel_->ref(META_HANDLE)).second, | 203 if (!SyncAssert(index->insert(kernel_->ref(META_HANDLE)).second, |
205 FROM_HERE, | 204 FROM_HERE, |
206 "Could not insert", | 205 "Could not insert", |
207 base_write_transaction())) { | 206 base_write_transaction())) { |
208 return false; | 207 return false; |
209 } | 208 } |
210 } else { | 209 } else { |
211 if (!SyncAssert(1U == index->erase(kernel_->ref(META_HANDLE)), | 210 if (!SyncAssert(1U == index->erase(kernel_->ref(META_HANDLE)), |
212 FROM_HERE, | 211 FROM_HERE, |
213 "Entry Not succesfully erased", | 212 "Entry Not succesfully erased", |
214 base_write_transaction())) { | 213 base_write_transaction())) { |
215 return false; | 214 return false; |
216 } | 215 } |
217 } | 216 } |
218 kernel_->put(IS_UNAPPLIED_UPDATE, value); | 217 kernel_->put(IS_UNAPPLIED_UPDATE, value); |
219 kernel_->mark_dirty(&dir()->kernel()->dirty_metahandles); | 218 MarkDirty(); |
220 } | 219 } |
221 return true; | 220 return true; |
222 } | 221 } |
223 | 222 |
224 void ModelNeutralMutableEntry::PutServerIsDir(bool value) { | 223 void ModelNeutralMutableEntry::PutServerIsDir(bool value) { |
225 DCHECK(kernel_); | 224 DCHECK(kernel_); |
226 base_write_transaction_->TrackChangesTo(kernel_); | 225 if (kernel_->ref(SERVER_IS_DIR) != value) { |
227 bool old_value = kernel_->ref(SERVER_IS_DIR); | 226 base_write_transaction_->TrackChangesTo(kernel_); |
228 if (old_value != value) { | |
229 kernel_->put(SERVER_IS_DIR, value); | 227 kernel_->put(SERVER_IS_DIR, value); |
230 kernel_->mark_dirty(GetDirtyIndexHelper()); | 228 MarkDirty(); |
231 } | 229 } |
232 } | 230 } |
233 | 231 |
234 void ModelNeutralMutableEntry::PutServerIsDel(bool value) { | 232 void ModelNeutralMutableEntry::PutServerIsDel(bool value) { |
235 DCHECK(kernel_); | 233 DCHECK(kernel_); |
236 base_write_transaction_->TrackChangesTo(kernel_); | |
237 bool old_value = kernel_->ref(SERVER_IS_DEL); | 234 bool old_value = kernel_->ref(SERVER_IS_DEL); |
238 if (old_value != value) { | 235 if (old_value != value) { |
| 236 base_write_transaction_->TrackChangesTo(kernel_); |
239 kernel_->put(SERVER_IS_DEL, value); | 237 kernel_->put(SERVER_IS_DEL, value); |
240 kernel_->mark_dirty(GetDirtyIndexHelper()); | 238 MarkDirty(); |
241 } | 239 } |
242 | 240 |
243 if (!value || kernel_->ref(IS_UNAPPLIED_UPDATE)) { | 241 if (!value || kernel_->ref(IS_UNAPPLIED_UPDATE)) { |
244 // Update delete journal for existence status change on server side here | 242 // Update delete journal for existence status change on server side here |
245 // instead of in PutIsDel() because IS_DEL may not be updated due to | 243 // instead of in PutIsDel() because IS_DEL may not be updated due to |
246 // early returns when processing updates. And because | 244 // early returns when processing updates. And because |
247 // UpdateDeleteJournalForServerDelete() checks for SERVER_IS_DEL, it has | 245 // UpdateDeleteJournalForServerDelete() checks for SERVER_IS_DEL, it has |
248 // to be called on sync thread. | 246 // to be called on sync thread. |
249 | 247 |
250 // Please note that the delete journal applies only to the deletions | 248 // Please note that the delete journal applies only to the deletions |
251 // originating on the server side (hence the IS_UNAPPLIED_UPDATE check), | 249 // originating on the server side (hence the IS_UNAPPLIED_UPDATE check), |
252 // but it still makes sense to remove the entry from the delete journal | 250 // but it still makes sense to remove the entry from the delete journal |
253 // when it gets undeleted locally. | 251 // when it gets undeleted locally. |
254 dir()->delete_journal()->UpdateDeleteJournalForServerDelete( | 252 dir()->delete_journal()->UpdateDeleteJournalForServerDelete( |
255 base_write_transaction(), old_value, *kernel_); | 253 base_write_transaction(), old_value, *kernel_); |
256 } | 254 } |
257 } | 255 } |
258 | 256 |
259 void ModelNeutralMutableEntry::PutServerNonUniqueName( | 257 void ModelNeutralMutableEntry::PutServerNonUniqueName( |
260 const std::string& value) { | 258 const std::string& value) { |
261 DCHECK(kernel_); | 259 DCHECK(kernel_); |
262 base_write_transaction_->TrackChangesTo(kernel_); | |
263 | |
264 if (kernel_->ref(SERVER_NON_UNIQUE_NAME) != value) { | 260 if (kernel_->ref(SERVER_NON_UNIQUE_NAME) != value) { |
| 261 base_write_transaction_->TrackChangesTo(kernel_); |
265 kernel_->put(SERVER_NON_UNIQUE_NAME, value); | 262 kernel_->put(SERVER_NON_UNIQUE_NAME, value); |
266 kernel_->mark_dirty(&dir()->kernel()->dirty_metahandles); | 263 MarkDirty(); |
267 } | 264 } |
268 } | 265 } |
269 | 266 |
270 bool ModelNeutralMutableEntry::PutUniqueServerTag(const string& new_tag) { | 267 bool ModelNeutralMutableEntry::PutUniqueServerTag(const string& new_tag) { |
271 if (new_tag == kernel_->ref(UNIQUE_SERVER_TAG)) { | 268 if (new_tag == kernel_->ref(UNIQUE_SERVER_TAG)) { |
272 return true; | 269 return true; |
273 } | 270 } |
274 | 271 |
275 base_write_transaction_->TrackChangesTo(kernel_); | 272 base_write_transaction_->TrackChangesTo(kernel_); |
276 ScopedKernelLock lock(dir()); | 273 ScopedKernelLock lock(dir()); |
277 // Make sure your new value is not in there already. | 274 // Make sure your new value is not in there already. |
278 if (dir()->kernel()->server_tags_map.find(new_tag) != | 275 if (dir()->kernel()->server_tags_map.find(new_tag) != |
279 dir()->kernel()->server_tags_map.end()) { | 276 dir()->kernel()->server_tags_map.end()) { |
280 DVLOG(1) << "Detected duplicate server tag"; | 277 DVLOG(1) << "Detected duplicate server tag"; |
281 return false; | 278 return false; |
282 } | 279 } |
283 dir()->kernel()->server_tags_map.erase( | 280 dir()->kernel()->server_tags_map.erase( |
284 kernel_->ref(UNIQUE_SERVER_TAG)); | 281 kernel_->ref(UNIQUE_SERVER_TAG)); |
285 kernel_->put(UNIQUE_SERVER_TAG, new_tag); | 282 kernel_->put(UNIQUE_SERVER_TAG, new_tag); |
286 kernel_->mark_dirty(&dir()->kernel()->dirty_metahandles); | 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( |
308 kernel_->ref(UNIQUE_CLIENT_TAG)); | 305 kernel_->ref(UNIQUE_CLIENT_TAG)); |
309 kernel_->put(UNIQUE_CLIENT_TAG, new_tag); | 306 kernel_->put(UNIQUE_CLIENT_TAG, new_tag); |
310 kernel_->mark_dirty(&dir()->kernel()->dirty_metahandles); | 307 MarkDirty(); |
311 if (!new_tag.empty()) { | 308 if (!new_tag.empty()) { |
312 dir()->kernel()->client_tags_map[new_tag] = kernel_; | 309 dir()->kernel()->client_tags_map[new_tag] = kernel_; |
313 } | 310 } |
314 | 311 |
315 return true; | 312 return true; |
316 } | 313 } |
317 | 314 |
318 void ModelNeutralMutableEntry::PutUniqueBookmarkTag(const std::string& tag) { | 315 void ModelNeutralMutableEntry::PutUniqueBookmarkTag(const std::string& tag) { |
319 // This unique tag will eventually be used as the unique suffix when adjusting | 316 // 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. | 317 // this bookmark's position. Let's make sure it's a valid suffix. |
321 if (!UniquePosition::IsValidSuffix(tag)) { | 318 if (!UniquePosition::IsValidSuffix(tag)) { |
322 NOTREACHED(); | 319 NOTREACHED(); |
323 return; | 320 return; |
324 } | 321 } |
325 | 322 |
| 323 //TODO(stanisc): Does this need a call to TrackChangesTo? |
| 324 |
326 if (!kernel_->ref(UNIQUE_BOOKMARK_TAG).empty() && | 325 if (!kernel_->ref(UNIQUE_BOOKMARK_TAG).empty() && |
327 tag != kernel_->ref(UNIQUE_BOOKMARK_TAG)) { | 326 tag != kernel_->ref(UNIQUE_BOOKMARK_TAG)) { |
328 // There is only one scenario where our tag is expected to change. That | 327 // There is only one scenario where our tag is expected to change. That |
329 // scenario occurs when our current tag is a non-correct tag assigned during | 328 // scenario occurs when our current tag is a non-correct tag assigned during |
330 // the UniquePosition migration. | 329 // the UniquePosition migration. |
331 std::string migration_generated_tag = | 330 std::string migration_generated_tag = |
332 GenerateSyncableBookmarkHash(std::string(), | 331 GenerateSyncableBookmarkHash(std::string(), |
333 kernel_->ref(ID).GetServerId()); | 332 kernel_->ref(ID).GetServerId()); |
334 DCHECK_EQ(migration_generated_tag, kernel_->ref(UNIQUE_BOOKMARK_TAG)); | 333 DCHECK_EQ(migration_generated_tag, kernel_->ref(UNIQUE_BOOKMARK_TAG)); |
335 } | 334 } |
336 | 335 |
337 kernel_->put(UNIQUE_BOOKMARK_TAG, tag); | 336 kernel_->put(UNIQUE_BOOKMARK_TAG, tag); |
338 kernel_->mark_dirty(&dir()->kernel()->dirty_metahandles); | 337 MarkDirty(); |
339 } | 338 } |
340 | 339 |
341 void ModelNeutralMutableEntry::PutServerSpecifics( | 340 void ModelNeutralMutableEntry::PutServerSpecifics( |
342 const sync_pb::EntitySpecifics& value) { | 341 const sync_pb::EntitySpecifics& value) { |
343 DCHECK(kernel_); | 342 DCHECK(kernel_); |
344 CHECK(!value.password().has_client_only_encrypted_data()); | 343 CHECK(!value.password().has_client_only_encrypted_data()); |
345 base_write_transaction_->TrackChangesTo(kernel_); | |
346 // TODO(ncarter): This is unfortunately heavyweight. Can we do | 344 // TODO(ncarter): This is unfortunately heavyweight. Can we do |
347 // better? | 345 // better? |
348 const std::string& serialized_value = value.SerializeAsString(); | 346 const std::string& serialized_value = value.SerializeAsString(); |
349 if (serialized_value != kernel_->ref(SERVER_SPECIFICS).SerializeAsString()) { | 347 if (serialized_value != kernel_->ref(SERVER_SPECIFICS).SerializeAsString()) { |
| 348 base_write_transaction_->TrackChangesTo(kernel_); |
350 if (kernel_->ref(IS_UNAPPLIED_UPDATE)) { | 349 if (kernel_->ref(IS_UNAPPLIED_UPDATE)) { |
351 // Remove ourselves from unapplied_update_metahandles with our | 350 // Remove ourselves from unapplied_update_metahandles with our |
352 // old server type. | 351 // old server type. |
353 const ModelType old_server_type = kernel_->GetServerModelType(); | 352 const ModelType old_server_type = kernel_->GetServerModelType(); |
354 const int64 metahandle = kernel_->ref(META_HANDLE); | 353 const int64 metahandle = kernel_->ref(META_HANDLE); |
355 size_t erase_count = | 354 size_t erase_count = |
356 dir()->kernel()->unapplied_update_metahandles[old_server_type] | 355 dir()->kernel()->unapplied_update_metahandles[old_server_type] |
357 .erase(metahandle); | 356 .erase(metahandle); |
358 DCHECK_EQ(erase_count, 1u); | 357 DCHECK_EQ(erase_count, 1u); |
359 } | 358 } |
360 | 359 |
361 // Check for potential sharing - SERVER_SPECIFICS is often | 360 // Check for potential sharing - SERVER_SPECIFICS is often |
362 // copied from SPECIFICS. | 361 // copied from SPECIFICS. |
363 if (serialized_value == kernel_->ref(SPECIFICS).SerializeAsString()) { | 362 if (serialized_value == kernel_->ref(SPECIFICS).SerializeAsString()) { |
364 kernel_->copy(SPECIFICS, SERVER_SPECIFICS); | 363 kernel_->copy(SPECIFICS, SERVER_SPECIFICS); |
365 } else { | 364 } else { |
366 kernel_->put(SERVER_SPECIFICS, value); | 365 kernel_->put(SERVER_SPECIFICS, value); |
367 } | 366 } |
368 kernel_->mark_dirty(&dir()->kernel()->dirty_metahandles); | 367 MarkDirty(); |
369 | 368 |
370 if (kernel_->ref(IS_UNAPPLIED_UPDATE)) { | 369 if (kernel_->ref(IS_UNAPPLIED_UPDATE)) { |
371 // Add ourselves back into unapplied_update_metahandles with our | 370 // Add ourselves back into unapplied_update_metahandles with our |
372 // new server type. | 371 // new server type. |
373 const ModelType new_server_type = kernel_->GetServerModelType(); | 372 const ModelType new_server_type = kernel_->GetServerModelType(); |
374 const int64 metahandle = kernel_->ref(META_HANDLE); | 373 const int64 metahandle = kernel_->ref(META_HANDLE); |
375 dir()->kernel()->unapplied_update_metahandles[new_server_type] | 374 dir()->kernel()->unapplied_update_metahandles[new_server_type] |
376 .insert(metahandle); | 375 .insert(metahandle); |
377 } | 376 } |
378 } | 377 } |
379 } | 378 } |
380 | 379 |
381 void ModelNeutralMutableEntry::PutBaseServerSpecifics( | 380 void ModelNeutralMutableEntry::PutBaseServerSpecifics( |
382 const sync_pb::EntitySpecifics& value) { | 381 const sync_pb::EntitySpecifics& value) { |
383 DCHECK(kernel_); | 382 DCHECK(kernel_); |
384 CHECK(!value.password().has_client_only_encrypted_data()); | 383 CHECK(!value.password().has_client_only_encrypted_data()); |
385 base_write_transaction_->TrackChangesTo(kernel_); | |
386 // TODO(ncarter): This is unfortunately heavyweight. Can we do | 384 // TODO(ncarter): This is unfortunately heavyweight. Can we do |
387 // better? | 385 // better? |
388 const std::string& serialized_value = value.SerializeAsString(); | 386 const std::string& serialized_value = value.SerializeAsString(); |
389 if (serialized_value != | 387 if (serialized_value != |
390 kernel_->ref(BASE_SERVER_SPECIFICS).SerializeAsString()) { | 388 kernel_->ref(BASE_SERVER_SPECIFICS).SerializeAsString()) { |
| 389 base_write_transaction_->TrackChangesTo(kernel_); |
391 // Check for potential sharing - BASE_SERVER_SPECIFICS is often | 390 // Check for potential sharing - BASE_SERVER_SPECIFICS is often |
392 // copied from SERVER_SPECIFICS. | 391 // copied from SERVER_SPECIFICS. |
393 if (serialized_value == | 392 if (serialized_value == |
394 kernel_->ref(SERVER_SPECIFICS).SerializeAsString()) { | 393 kernel_->ref(SERVER_SPECIFICS).SerializeAsString()) { |
395 kernel_->copy(SERVER_SPECIFICS, BASE_SERVER_SPECIFICS); | 394 kernel_->copy(SERVER_SPECIFICS, BASE_SERVER_SPECIFICS); |
396 } else { | 395 } else { |
397 kernel_->put(BASE_SERVER_SPECIFICS, value); | 396 kernel_->put(BASE_SERVER_SPECIFICS, value); |
398 } | 397 } |
399 kernel_->mark_dirty(&dir()->kernel()->dirty_metahandles); | 398 MarkDirty(); |
400 } | 399 } |
401 } | 400 } |
402 | 401 |
403 void ModelNeutralMutableEntry::PutServerUniquePosition( | 402 void ModelNeutralMutableEntry::PutServerUniquePosition( |
404 const UniquePosition& value) { | 403 const UniquePosition& value) { |
405 DCHECK(kernel_); | 404 DCHECK(kernel_); |
406 base_write_transaction_->TrackChangesTo(kernel_); | |
407 if(!kernel_->ref(SERVER_UNIQUE_POSITION).Equals(value)) { | 405 if(!kernel_->ref(SERVER_UNIQUE_POSITION).Equals(value)) { |
| 406 base_write_transaction_->TrackChangesTo(kernel_); |
408 // We should never overwrite a valid position with an invalid one. | 407 // We should never overwrite a valid position with an invalid one. |
409 DCHECK(value.IsValid()); | 408 DCHECK(value.IsValid()); |
410 ScopedKernelLock lock(dir()); | 409 ScopedKernelLock lock(dir()); |
411 kernel_->put(SERVER_UNIQUE_POSITION, value); | 410 kernel_->put(SERVER_UNIQUE_POSITION, value); |
412 kernel_->mark_dirty(&dir()->kernel()->dirty_metahandles); | 411 MarkDirty(); |
413 } | 412 } |
414 } | 413 } |
415 | 414 |
416 void ModelNeutralMutableEntry::PutServerAttachmentMetadata( | 415 void ModelNeutralMutableEntry::PutServerAttachmentMetadata( |
417 const sync_pb::AttachmentMetadata& value) { | 416 const sync_pb::AttachmentMetadata& value) { |
418 DCHECK(kernel_); | 417 DCHECK(kernel_); |
419 base_write_transaction_->TrackChangesTo(kernel_); | |
420 const std::string& serialized_value = value.SerializeAsString(); | 418 const std::string& serialized_value = value.SerializeAsString(); |
421 if (serialized_value != | 419 if (serialized_value != |
422 kernel_->ref(SERVER_ATTACHMENT_METADATA).SerializeAsString()) { | 420 kernel_->ref(SERVER_ATTACHMENT_METADATA).SerializeAsString()) { |
| 421 base_write_transaction_->TrackChangesTo(kernel_); |
423 // Check for potential sharing - SERVER_ATTACHMENT_METADATA is often | 422 // Check for potential sharing - SERVER_ATTACHMENT_METADATA is often |
424 // copied from ATTACHMENT_METADATA. | 423 // copied from ATTACHMENT_METADATA. |
425 if (serialized_value == | 424 if (serialized_value == |
426 kernel_->ref(ATTACHMENT_METADATA).SerializeAsString()) { | 425 kernel_->ref(ATTACHMENT_METADATA).SerializeAsString()) { |
427 kernel_->copy(ATTACHMENT_METADATA, SERVER_ATTACHMENT_METADATA); | 426 kernel_->copy(ATTACHMENT_METADATA, SERVER_ATTACHMENT_METADATA); |
428 } else { | 427 } else { |
429 kernel_->put(SERVER_ATTACHMENT_METADATA, value); | 428 kernel_->put(SERVER_ATTACHMENT_METADATA, value); |
430 } | 429 } |
431 kernel_->mark_dirty(&dir()->kernel()->dirty_metahandles); | 430 MarkDirty(); |
432 } | 431 } |
433 } | 432 } |
434 | 433 |
435 void ModelNeutralMutableEntry::PutSyncing(bool value) { | 434 void ModelNeutralMutableEntry::PutSyncing(bool value) { |
436 kernel_->put(SYNCING, value); | 435 kernel_->put(SYNCING, value); |
437 } | 436 } |
438 | 437 |
439 void ModelNeutralMutableEntry::PutDirtySync(bool value) { | 438 void ModelNeutralMutableEntry::PutDirtySync(bool value) { |
440 DCHECK(!value || GetSyncing()); | 439 DCHECK(!value || GetSyncing()); |
441 kernel_->put(DIRTY_SYNC, value); | 440 kernel_->put(DIRTY_SYNC, value); |
442 } | 441 } |
443 | 442 |
444 void ModelNeutralMutableEntry::PutParentIdPropertyOnly(const Id& parent_id) { | 443 void ModelNeutralMutableEntry::PutParentIdPropertyOnly(const Id& parent_id) { |
445 base_write_transaction_->TrackChangesTo(kernel_); | 444 base_write_transaction_->TrackChangesTo(kernel_); |
446 dir()->ReindexParentId(base_write_transaction(), kernel_, parent_id); | 445 dir()->ReindexParentId(base_write_transaction(), kernel_, parent_id); |
447 kernel_->mark_dirty(&dir()->kernel()->dirty_metahandles); | 446 MarkDirty(); |
448 } | 447 } |
449 | 448 |
450 void ModelNeutralMutableEntry::UpdateTransactionVersion(int64 value) { | 449 void ModelNeutralMutableEntry::UpdateTransactionVersion(int64 value) { |
451 ScopedKernelLock lock(dir()); | |
452 kernel_->put(TRANSACTION_VERSION, value); | 450 kernel_->put(TRANSACTION_VERSION, value); |
453 kernel_->mark_dirty(&(dir()->kernel()->dirty_metahandles)); | 451 MarkDirty(); |
454 } | 452 } |
455 | 453 |
456 ModelNeutralMutableEntry::ModelNeutralMutableEntry(BaseWriteTransaction* trans) | 454 ModelNeutralMutableEntry::ModelNeutralMutableEntry(BaseWriteTransaction* trans) |
457 : Entry(trans), base_write_transaction_(trans) {} | 455 : Entry(trans), base_write_transaction_(trans) {} |
458 | 456 |
459 MetahandleSet* ModelNeutralMutableEntry::GetDirtyIndexHelper() { | 457 void ModelNeutralMutableEntry::MarkDirty() { |
460 return &dir()->kernel()->dirty_metahandles; | 458 kernel_->mark_dirty(&dir()->kernel()->dirty_metahandles); |
461 } | 459 } |
462 | 460 |
463 } // namespace syncable | 461 } // namespace syncable |
464 | 462 |
465 } // namespace syncer | 463 } // namespace syncer |
OLD | NEW |