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