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