| 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 |