Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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/directory.h" | 5 #include "sync/syncable/directory.h" |
| 6 | 6 |
| 7 #include "base/debug/trace_event.h" | 7 #include "base/debug/trace_event.h" |
| 8 #include "base/perftimer.h" | 8 #include "base/perftimer.h" |
| 9 #include "base/stl_util.h" | 9 #include "base/stl_util.h" |
| 10 #include "base/string_number_conversions.h" | 10 #include "base/string_number_conversions.h" |
| (...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 94 download_progress[model_type].set_data_type_id( | 94 download_progress[model_type].set_data_type_id( |
| 95 GetSpecificsFieldNumberFromModelType(model_type)); | 95 GetSpecificsFieldNumberFromModelType(model_type)); |
| 96 // An empty-string token indicates no prior knowledge. | 96 // An empty-string token indicates no prior knowledge. |
| 97 download_progress[model_type].set_token(std::string()); | 97 download_progress[model_type].set_token(std::string()); |
| 98 } | 98 } |
| 99 | 99 |
| 100 Directory::SaveChangesSnapshot::SaveChangesSnapshot() | 100 Directory::SaveChangesSnapshot::SaveChangesSnapshot() |
| 101 : kernel_info_status(KERNEL_SHARE_INFO_INVALID) { | 101 : kernel_info_status(KERNEL_SHARE_INFO_INVALID) { |
| 102 } | 102 } |
| 103 | 103 |
| 104 Directory::SaveChangesSnapshot::~SaveChangesSnapshot() {} | 104 Directory::SaveChangesSnapshot::~SaveChangesSnapshot() { |
| 105 STLDeleteElements(&dirty_metas); | |
|
tim (not reviewing)
2012/12/14 20:12:38
Where was this being deleted before?
haitaol1
2012/12/14 23:15:36
It doesn't need to be deleted because it's not a p
| |
| 106 STLDeleteElements(&delete_journals); | |
| 107 } | |
| 105 | 108 |
| 106 Directory::Kernel::Kernel( | 109 Directory::Kernel::Kernel( |
| 107 const std::string& name, | 110 const std::string& name, |
| 108 const KernelLoadInfo& info, DirectoryChangeDelegate* delegate, | 111 const KernelLoadInfo& info, DirectoryChangeDelegate* delegate, |
| 109 const WeakHandle<TransactionObserver>& transaction_observer) | 112 const WeakHandle<TransactionObserver>& transaction_observer) |
| 110 : next_write_transaction_id(0), | 113 : next_write_transaction_id(0), |
| 111 name(name), | 114 name(name), |
| 112 metahandles_index(new Directory::MetahandlesIndex), | 115 metahandles_index(new Directory::MetahandlesIndex), |
| 113 ids_index(new Directory::IdsIndex), | 116 ids_index(new Directory::IdsIndex), |
| 114 parent_id_child_index(new Directory::ParentIdChildIndex), | 117 parent_id_child_index(new Directory::ParentIdChildIndex), |
| 115 client_tag_index(new Directory::ClientTagIndex), | 118 client_tag_index(new Directory::ClientTagIndex), |
| 116 unsynced_metahandles(new MetahandleSet), | 119 unsynced_metahandles(new MetahandleSet), |
| 117 dirty_metahandles(new MetahandleSet), | 120 dirty_metahandles(new MetahandleSet), |
| 118 metahandles_to_purge(new MetahandleSet), | 121 metahandles_to_purge(new MetahandleSet), |
| 119 info_status(Directory::KERNEL_SHARE_INFO_VALID), | 122 info_status(Directory::KERNEL_SHARE_INFO_VALID), |
| 120 persisted_info(info.kernel_info), | 123 persisted_info(info.kernel_info), |
| 121 cache_guid(info.cache_guid), | 124 cache_guid(info.cache_guid), |
| 122 next_metahandle(info.max_metahandle + 1), | 125 next_metahandle(info.max_metahandle + 1), |
| 123 delegate(delegate), | 126 delegate(delegate), |
| 124 transaction_observer(transaction_observer) { | 127 transaction_observer(transaction_observer), |
| 128 delete_journals_(new Directory::IdsIndex), | |
| 129 delete_journals_to_purge_(new MetahandleSet) { | |
| 125 DCHECK(delegate); | 130 DCHECK(delegate); |
| 126 DCHECK(transaction_observer.IsInitialized()); | 131 DCHECK(transaction_observer.IsInitialized()); |
| 127 } | 132 } |
| 128 | 133 |
| 129 Directory::Kernel::~Kernel() { | 134 Directory::Kernel::~Kernel() { |
| 130 delete unsynced_metahandles; | 135 delete unsynced_metahandles; |
| 131 delete dirty_metahandles; | 136 delete dirty_metahandles; |
| 132 delete metahandles_to_purge; | 137 delete metahandles_to_purge; |
| 133 delete parent_id_child_index; | 138 delete parent_id_child_index; |
| 134 delete client_tag_index; | 139 delete client_tag_index; |
| 135 delete ids_index; | 140 delete ids_index; |
| 136 STLDeleteElements(metahandles_index); | 141 STLDeleteElements(metahandles_index); |
| 137 delete metahandles_index; | 142 delete metahandles_index; |
| 143 STLDeleteElements(delete_journals_); | |
| 144 delete delete_journals_; | |
| 145 delete delete_journals_to_purge_; | |
| 138 } | 146 } |
| 139 | 147 |
| 140 Directory::Directory( | 148 Directory::Directory( |
| 141 DirectoryBackingStore* store, | 149 DirectoryBackingStore* store, |
| 142 UnrecoverableErrorHandler* unrecoverable_error_handler, | 150 UnrecoverableErrorHandler* unrecoverable_error_handler, |
| 143 ReportUnrecoverableErrorFunction report_unrecoverable_error_function, | 151 ReportUnrecoverableErrorFunction report_unrecoverable_error_function, |
| 144 NigoriHandler* nigori_handler, | 152 NigoriHandler* nigori_handler, |
| 145 Cryptographer* cryptographer) | 153 Cryptographer* cryptographer) |
| 146 : kernel_(NULL), | 154 : kernel_(NULL), |
| 147 store_(store), | 155 store_(store), |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 189 } | 197 } |
| 190 DCHECK(!entry->is_dirty()); | 198 DCHECK(!entry->is_dirty()); |
| 191 } | 199 } |
| 192 } | 200 } |
| 193 | 201 |
| 194 DirOpenResult Directory::OpenImpl( | 202 DirOpenResult Directory::OpenImpl( |
| 195 const string& name, | 203 const string& name, |
| 196 DirectoryChangeDelegate* delegate, | 204 DirectoryChangeDelegate* delegate, |
| 197 const WeakHandle<TransactionObserver>& | 205 const WeakHandle<TransactionObserver>& |
| 198 transaction_observer) { | 206 transaction_observer) { |
| 199 | |
| 200 KernelLoadInfo info; | 207 KernelLoadInfo info; |
| 201 // Temporary indices before kernel_ initialized in case Load fails. We 0(1) | 208 // Temporary indices before kernel_ initialized in case Load fails. We 0(1) |
| 202 // swap these later. | 209 // swap these later. |
| 203 MetahandlesIndex metas_bucket; | 210 MetahandlesIndex metas_bucket; |
| 204 DirOpenResult result = store_->Load(&metas_bucket, &info); | 211 IdsIndex delete_journals; |
| 212 | |
| 213 DirOpenResult result = store_->Load(&metas_bucket, &delete_journals, &info); | |
| 205 if (OPENED != result) | 214 if (OPENED != result) |
| 206 return result; | 215 return result; |
| 207 | 216 |
| 208 kernel_ = new Kernel(name, info, delegate, transaction_observer); | 217 kernel_ = new Kernel(name, info, delegate, transaction_observer); |
| 209 kernel_->metahandles_index->swap(metas_bucket); | 218 kernel_->metahandles_index->swap(metas_bucket); |
| 219 kernel_->delete_journals_->swap(delete_journals); | |
| 210 InitializeIndices(); | 220 InitializeIndices(); |
| 211 | 221 |
| 212 // Write back the share info to reserve some space in 'next_id'. This will | 222 // Write back the share info to reserve some space in 'next_id'. This will |
| 213 // prevent local ID reuse in the case of an early crash. See the comments in | 223 // prevent local ID reuse in the case of an early crash. See the comments in |
| 214 // TakeSnapshotForSaveChanges() or crbug.com/142987 for more information. | 224 // TakeSnapshotForSaveChanges() or crbug.com/142987 for more information. |
| 215 kernel_->info_status = KERNEL_SHARE_INFO_DIRTY; | 225 kernel_->info_status = KERNEL_SHARE_INFO_DIRTY; |
| 216 if (!SaveChanges()) | 226 if (!SaveChanges()) |
| 217 return FAILED_INITIAL_WRITE; | 227 return FAILED_INITIAL_WRITE; |
| 218 | 228 |
| 219 return OPENED; | 229 return OPENED; |
| 220 } | 230 } |
| 221 | 231 |
| 222 void Directory::Close() { | 232 void Directory::Close() { |
| 223 store_.reset(); | 233 store_.reset(); |
| 224 if (kernel_) { | 234 if (kernel_) { |
| 225 delete kernel_; | 235 delete kernel_; |
| 226 kernel_ = NULL; | 236 kernel_ = NULL; |
| 227 } | 237 } |
| 228 } | 238 } |
| 229 | 239 |
| 230 void Directory::OnUnrecoverableError(const BaseTransaction* trans, | 240 void Directory::OnUnrecoverableError(const BaseTransaction* trans, |
| 231 const tracked_objects::Location& location, | 241 const tracked_objects::Location& location, |
| 232 const std::string & message) { | 242 const std::string & message) { |
| 233 DCHECK(trans != NULL); | 243 DCHECK(trans != NULL); |
| 234 unrecoverable_error_set_ = true; | 244 unrecoverable_error_set_ = true; |
| 235 unrecoverable_error_handler_->OnUnrecoverableError(location, | 245 unrecoverable_error_handler_->OnUnrecoverableError(location, |
| 236 message); | 246 message); |
| 237 } | 247 } |
| 238 | 248 |
| 249 void Directory::UpdateDeleteJournals(BaseTransaction* trans, | |
|
tim (not reviewing)
2012/12/13 23:41:30
UpdateDeleteJournals sounds a bit more general tha
haitaol1
2012/12/14 19:22:38
Done.
| |
| 250 bool was_deleted, | |
| 251 const EntryKernel& entry) { | |
| 252 if (!(IsDeleteJournalEnabled( | |
| 253 GetModelTypeFromSpecifics(entry.ref(SPECIFICS))) || | |
| 254 IsDeleteJournalEnabled(entry.GetServerModelType()))) { | |
|
tim (not reviewing)
2012/12/13 23:41:30
Do you expect local specifics and server specifics
haitaol1
2012/12/14 19:22:38
The specifics would be different because this is c
| |
| 255 return; | |
| 256 } | |
| 257 | |
| 258 ScopedKernelLock lock(this); | |
| 259 IdsIndex::const_iterator it = | |
| 260 kernel_->delete_journals_->find(const_cast<EntryKernel*>(&entry)); | |
|
tim (not reviewing)
2012/12/13 23:41:30
Why remove the const-ness? Everything about delet
haitaol1
2012/12/14 19:22:38
It's because IdIndex stores non-const pointer. Cha
| |
| 261 | |
| 262 if (entry.ref(SERVER_IS_DEL)) { | |
| 263 if (it == kernel_->delete_journals_->end()) { | |
| 264 // New delete. | |
| 265 EntryKernel* t = new EntryKernel(entry); | |
| 266 kernel_->delete_journals_->insert(t); | |
| 267 kernel_->delete_journals_to_purge_->erase(t->ref(META_HANDLE)); | |
| 268 } | |
| 269 } else { | |
| 270 // Undelete. This could happen in two cases: | |
| 271 // * An entry was actually deleted and undeleted: was_deleted = true. | |
|
tim (not reviewing)
2012/12/13 23:41:30
Where would this undelete have come from? The ser
haitaol1
2012/12/14 19:22:38
Yes. Looks like if an entry was deleted on client
tim (not reviewing)
2012/12/14 20:12:38
So, it was deleted (and possibly applied to the na
haitaol1
2012/12/14 23:15:36
Done.
| |
| 272 // * A data type was broken in last sync session and all its entries | |
|
tim (not reviewing)
2012/12/13 23:41:30
Define broken?
haitaol1
2012/12/14 19:22:38
Done.
| |
| 273 // were duplicated in delete journals. On restart, entries are recreated | |
| 274 // from downloads and recreation calls UpdateDeleteJournals() to remove | |
| 275 // live entries from delete journals, thus only deleted entries remain in | |
| 276 // journals. | |
| 277 if (it != kernel_->delete_journals_->end()) { | |
| 278 kernel_->delete_journals_to_purge_->insert((*it)->ref(META_HANDLE)); | |
| 279 delete *it; | |
| 280 kernel_->delete_journals_->erase(it); | |
| 281 } else if (was_deleted) { | |
| 282 kernel_->delete_journals_to_purge_->insert((*it)->ref(META_HANDLE)); | |
| 283 } | |
| 284 } | |
| 285 } | |
| 286 | |
| 287 void Directory::GetDeleteJournals(BaseTransaction* trans, | |
| 288 ModelType type, | |
| 289 EntryKernelSet* deleted_entries) { | |
| 290 ScopedKernelLock lock(this); | |
| 291 DCHECK(!passive_delete_journal_types_.Has(type)); | |
| 292 for (IdsIndex::const_iterator it = kernel_->delete_journals_->begin(); | |
| 293 it != kernel_->delete_journals_->end(); ++it) { | |
| 294 if (GetModelTypeFromSpecifics((*it)->ref(SPECIFICS)) == type || | |
| 295 (*it)->GetServerModelType() == type) { | |
| 296 deleted_entries->insert(*it); | |
| 297 } | |
| 298 } | |
| 299 passive_delete_journal_types_.Put(type); | |
| 300 } | |
| 301 | |
| 302 void Directory::PurgeDeleteJournals(BaseTransaction* trans, | |
| 303 const MetahandleSet& to_purge) { | |
| 304 ScopedKernelLock lock(this); | |
| 305 IdsIndex::const_iterator it = kernel_->delete_journals_->begin(); | |
| 306 while (it != kernel_->delete_journals_->end()) { | |
| 307 int64 handle = (*it)->ref(META_HANDLE); | |
| 308 if (to_purge.count(handle)) { | |
| 309 delete *it; | |
| 310 kernel_->delete_journals_->erase(it++); | |
| 311 } else { | |
| 312 ++it; | |
| 313 } | |
| 314 } | |
| 315 kernel_->delete_journals_to_purge_->insert(to_purge.begin(), to_purge.end()); | |
| 316 } | |
| 239 | 317 |
| 240 EntryKernel* Directory::GetEntryById(const Id& id) { | 318 EntryKernel* Directory::GetEntryById(const Id& id) { |
| 241 ScopedKernelLock lock(this); | 319 ScopedKernelLock lock(this); |
| 242 return GetEntryById(id, &lock); | 320 return GetEntryById(id, &lock); |
| 243 } | 321 } |
| 244 | 322 |
| 245 EntryKernel* Directory::GetEntryById(const Id& id, | 323 EntryKernel* Directory::GetEntryById(const Id& id, |
| 246 ScopedKernelLock* const lock) { | 324 ScopedKernelLock* const lock) { |
| 247 DCHECK(kernel_); | 325 DCHECK(kernel_); |
| 248 // Find it in the in memory ID index. | 326 // Find it in the in memory ID index. |
| (...skipping 210 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 459 // Deep copy dirty entries from kernel_->metahandles_index into snapshot and | 537 // Deep copy dirty entries from kernel_->metahandles_index into snapshot and |
| 460 // clear dirty flags. | 538 // clear dirty flags. |
| 461 for (MetahandleSet::const_iterator i = kernel_->dirty_metahandles->begin(); | 539 for (MetahandleSet::const_iterator i = kernel_->dirty_metahandles->begin(); |
| 462 i != kernel_->dirty_metahandles->end(); ++i) { | 540 i != kernel_->dirty_metahandles->end(); ++i) { |
| 463 EntryKernel* entry = GetEntryByHandle(*i, &lock); | 541 EntryKernel* entry = GetEntryByHandle(*i, &lock); |
| 464 if (!entry) | 542 if (!entry) |
| 465 continue; | 543 continue; |
| 466 // Skip over false positives; it happens relatively infrequently. | 544 // Skip over false positives; it happens relatively infrequently. |
| 467 if (!entry->is_dirty()) | 545 if (!entry->is_dirty()) |
| 468 continue; | 546 continue; |
| 469 snapshot->dirty_metas.insert(snapshot->dirty_metas.end(), *entry); | 547 snapshot->dirty_metas.insert(snapshot->dirty_metas.end(), |
| 548 new EntryKernel(*entry)); | |
| 470 DCHECK_EQ(1U, kernel_->dirty_metahandles->count(*i)); | 549 DCHECK_EQ(1U, kernel_->dirty_metahandles->count(*i)); |
| 471 // We don't bother removing from the index here as we blow the entire thing | 550 // We don't bother removing from the index here as we blow the entire thing |
| 472 // in a moment, and it unnecessarily complicates iteration. | 551 // in a moment, and it unnecessarily complicates iteration. |
| 473 entry->clear_dirty(NULL); | 552 entry->clear_dirty(NULL); |
| 474 } | 553 } |
| 475 ClearDirtyMetahandles(); | 554 ClearDirtyMetahandles(); |
| 476 | 555 |
| 477 // Set purged handles. | 556 // Set purged handles. |
| 478 DCHECK(snapshot->metahandles_to_purge.empty()); | 557 DCHECK(snapshot->metahandles_to_purge.empty()); |
| 479 snapshot->metahandles_to_purge.swap(*(kernel_->metahandles_to_purge)); | 558 snapshot->metahandles_to_purge.swap(*(kernel_->metahandles_to_purge)); |
| 480 | 559 |
| 481 // Fill kernel_info_status and kernel_info. | 560 // Fill kernel_info_status and kernel_info. |
| 482 snapshot->kernel_info = kernel_->persisted_info; | 561 snapshot->kernel_info = kernel_->persisted_info; |
| 483 // To avoid duplicates when the process crashes, we record the next_id to be | 562 // To avoid duplicates when the process crashes, we record the next_id to be |
| 484 // greater magnitude than could possibly be reached before the next save | 563 // greater magnitude than could possibly be reached before the next save |
| 485 // changes. In other words, it's effectively impossible for the user to | 564 // changes. In other words, it's effectively impossible for the user to |
| 486 // generate 65536 new bookmarks in 3 seconds. | 565 // generate 65536 new bookmarks in 3 seconds. |
| 487 snapshot->kernel_info.next_id -= 65536; | 566 snapshot->kernel_info.next_id -= 65536; |
| 488 snapshot->kernel_info_status = kernel_->info_status; | 567 snapshot->kernel_info_status = kernel_->info_status; |
| 489 // This one we reset on failure. | 568 // This one we reset on failure. |
| 490 kernel_->info_status = KERNEL_SHARE_INFO_VALID; | 569 kernel_->info_status = KERNEL_SHARE_INFO_VALID; |
| 570 | |
| 571 // Move passive delete journals to snapshot. Will copy back if snapshot fails | |
| 572 // to save. | |
| 573 MetahandlesIndex::const_iterator it = kernel_->delete_journals_->begin(); | |
| 574 while (it != kernel_->delete_journals_->end()) { | |
| 575 if (passive_delete_journal_types_.Has((*it)->GetServerModelType()) || | |
| 576 passive_delete_journal_types_.Has(GetModelTypeFromSpecifics( | |
| 577 (*it)->ref(SPECIFICS)))) { | |
| 578 snapshot->delete_journals.insert(*it); | |
| 579 kernel_->delete_journals_->erase(it++); | |
| 580 } else { | |
| 581 ++it; | |
| 582 } | |
| 583 } | |
| 584 snapshot->delete_journals_to_purge.swap( | |
| 585 *kernel_->delete_journals_to_purge_); | |
| 491 } | 586 } |
| 492 | 587 |
| 493 bool Directory::SaveChanges() { | 588 bool Directory::SaveChanges() { |
| 494 bool success = false; | 589 bool success = false; |
| 495 | 590 |
| 496 base::AutoLock scoped_lock(kernel_->save_changes_mutex); | 591 base::AutoLock scoped_lock(kernel_->save_changes_mutex); |
| 497 | 592 |
| 498 // Snapshot and save. | 593 // Snapshot and save. |
| 499 SaveChangesSnapshot snapshot; | 594 SaveChangesSnapshot snapshot; |
| 500 TakeSnapshotForSaveChanges(&snapshot); | 595 TakeSnapshotForSaveChanges(&snapshot); |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 511 bool Directory::VacuumAfterSaveChanges(const SaveChangesSnapshot& snapshot) { | 606 bool Directory::VacuumAfterSaveChanges(const SaveChangesSnapshot& snapshot) { |
| 512 if (snapshot.dirty_metas.empty()) | 607 if (snapshot.dirty_metas.empty()) |
| 513 return true; | 608 return true; |
| 514 | 609 |
| 515 // Need a write transaction as we are about to permanently purge entries. | 610 // Need a write transaction as we are about to permanently purge entries. |
| 516 WriteTransaction trans(FROM_HERE, VACUUM_AFTER_SAVE, this); | 611 WriteTransaction trans(FROM_HERE, VACUUM_AFTER_SAVE, this); |
| 517 ScopedKernelLock lock(this); | 612 ScopedKernelLock lock(this); |
| 518 // Now drop everything we can out of memory. | 613 // Now drop everything we can out of memory. |
| 519 for (EntryKernelSet::const_iterator i = snapshot.dirty_metas.begin(); | 614 for (EntryKernelSet::const_iterator i = snapshot.dirty_metas.begin(); |
| 520 i != snapshot.dirty_metas.end(); ++i) { | 615 i != snapshot.dirty_metas.end(); ++i) { |
| 521 kernel_->needle.put(META_HANDLE, i->ref(META_HANDLE)); | 616 kernel_->needle.put(META_HANDLE, (*i)->ref(META_HANDLE)); |
| 522 MetahandlesIndex::iterator found = | 617 MetahandlesIndex::iterator found = |
| 523 kernel_->metahandles_index->find(&kernel_->needle); | 618 kernel_->metahandles_index->find(&kernel_->needle); |
| 524 EntryKernel* entry = (found == kernel_->metahandles_index->end() ? | 619 EntryKernel* entry = (found == kernel_->metahandles_index->end() ? |
| 525 NULL : *found); | 620 NULL : *found); |
| 526 if (entry && SafeToPurgeFromMemory(&trans, entry)) { | 621 if (entry && SafeToPurgeFromMemory(&trans, entry)) { |
| 527 // We now drop deleted metahandles that are up to date on both the client | 622 // We now drop deleted metahandles that are up to date on both the client |
| 528 // and the server. | 623 // and the server. |
| 529 size_t num_erased = 0; | 624 size_t num_erased = 0; |
| 530 num_erased = kernel_->ids_index->erase(entry); | 625 num_erased = kernel_->ids_index->erase(entry); |
| 531 DCHECK_EQ(1u, num_erased); | 626 DCHECK_EQ(1u, num_erased); |
| 532 num_erased = kernel_->metahandles_index->erase(entry); | 627 num_erased = kernel_->metahandles_index->erase(entry); |
| 533 DCHECK_EQ(1u, num_erased); | 628 DCHECK_EQ(1u, num_erased); |
| 534 | 629 |
| 535 // Might not be in it | 630 // Might not be in it |
| 536 num_erased = kernel_->client_tag_index->erase(entry); | 631 num_erased = kernel_->client_tag_index->erase(entry); |
| 537 DCHECK_EQ(entry->ref(UNIQUE_CLIENT_TAG).empty(), !num_erased); | 632 DCHECK_EQ(entry->ref(UNIQUE_CLIENT_TAG).empty(), !num_erased); |
| 538 if (!SyncAssert(!kernel_->parent_id_child_index->count(entry), | 633 if (!SyncAssert(!kernel_->parent_id_child_index->count(entry), |
| 539 FROM_HERE, | 634 FROM_HERE, |
| 540 "Deleted entry still present", | 635 "Deleted entry still present", |
| 541 (&trans))) | 636 (&trans))) |
| 542 return false; | 637 return false; |
| 543 delete entry; | 638 delete entry; |
| 544 } | 639 } |
| 545 if (trans.unrecoverable_error_set()) | 640 if (trans.unrecoverable_error_set()) |
| 546 return false; | 641 return false; |
| 547 } | 642 } |
| 548 return true; | 643 return true; |
| 549 } | 644 } |
| 550 | 645 |
| 551 bool Directory::PurgeEntriesWithTypeIn(ModelTypeSet types) { | 646 bool Directory::PurgeEntriesWithTypeIn(ModelTypeSet types) { |
|
tim (not reviewing)
2012/12/13 23:41:30
I don't see any changes here for the delete journa
haitaol1
2012/12/14 19:22:38
I'm a little ahead of myself here. This is in anot
| |
| 552 if (types.Empty()) | 647 if (types.Empty()) |
| 553 return true; | 648 return true; |
| 554 | 649 |
| 555 { | 650 { |
| 556 WriteTransaction trans(FROM_HERE, PURGE_ENTRIES, this); | 651 WriteTransaction trans(FROM_HERE, PURGE_ENTRIES, this); |
| 557 { | 652 { |
| 558 ScopedKernelLock lock(this); | 653 ScopedKernelLock lock(this); |
| 559 MetahandlesIndex::iterator it = kernel_->metahandles_index->begin(); | 654 MetahandlesIndex::iterator it = kernel_->metahandles_index->begin(); |
| 560 while (it != kernel_->metahandles_index->end()) { | 655 while (it != kernel_->metahandles_index->end()) { |
| 561 const sync_pb::EntitySpecifics& local_specifics = (*it)->ref(SPECIFICS); | 656 const sync_pb::EntitySpecifics& local_specifics = (*it)->ref(SPECIFICS); |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 609 ScopedKernelLock lock(this); | 704 ScopedKernelLock lock(this); |
| 610 kernel_->info_status = KERNEL_SHARE_INFO_DIRTY; | 705 kernel_->info_status = KERNEL_SHARE_INFO_DIRTY; |
| 611 | 706 |
| 612 // Because we optimistically cleared the dirty bit on the real entries when | 707 // Because we optimistically cleared the dirty bit on the real entries when |
| 613 // taking the snapshot, we must restore it on failure. Not doing this could | 708 // taking the snapshot, we must restore it on failure. Not doing this could |
| 614 // cause lost data, if no other changes are made to the in-memory entries | 709 // cause lost data, if no other changes are made to the in-memory entries |
| 615 // that would cause the dirty bit to get set again. Setting the bit ensures | 710 // that would cause the dirty bit to get set again. Setting the bit ensures |
| 616 // that SaveChanges will at least try again later. | 711 // that SaveChanges will at least try again later. |
| 617 for (EntryKernelSet::const_iterator i = snapshot.dirty_metas.begin(); | 712 for (EntryKernelSet::const_iterator i = snapshot.dirty_metas.begin(); |
| 618 i != snapshot.dirty_metas.end(); ++i) { | 713 i != snapshot.dirty_metas.end(); ++i) { |
| 619 kernel_->needle.put(META_HANDLE, i->ref(META_HANDLE)); | 714 kernel_->needle.put(META_HANDLE, (*i)->ref(META_HANDLE)); |
| 620 MetahandlesIndex::iterator found = | 715 MetahandlesIndex::iterator found = |
| 621 kernel_->metahandles_index->find(&kernel_->needle); | 716 kernel_->metahandles_index->find(&kernel_->needle); |
| 622 if (found != kernel_->metahandles_index->end()) { | 717 if (found != kernel_->metahandles_index->end()) { |
| 623 (*found)->mark_dirty(kernel_->dirty_metahandles); | 718 (*found)->mark_dirty(kernel_->dirty_metahandles); |
| 624 } | 719 } |
| 625 } | 720 } |
| 626 | 721 |
| 627 kernel_->metahandles_to_purge->insert(snapshot.metahandles_to_purge.begin(), | 722 kernel_->metahandles_to_purge->insert(snapshot.metahandles_to_purge.begin(), |
| 628 snapshot.metahandles_to_purge.end()); | 723 snapshot.metahandles_to_purge.end()); |
| 724 | |
| 725 // Restore delete journals. | |
| 726 for (EntryKernelSet::const_iterator i = snapshot.delete_journals.begin(); | |
| 727 i != snapshot.delete_journals.end(); ++i) { | |
| 728 kernel_->needle.put(ID, (*i)->ref(ID)); | |
| 729 if (kernel_->delete_journals_->find(&kernel_->needle) == | |
| 730 kernel_->delete_journals_->end()) { | |
| 731 kernel_->delete_journals_->insert(new EntryKernel(**i)); | |
| 732 } | |
| 733 } | |
| 734 kernel_->delete_journals_to_purge_->insert( | |
| 735 snapshot.delete_journals_to_purge.begin(), | |
| 736 snapshot.delete_journals_to_purge.end()); | |
| 737 | |
| 629 } | 738 } |
| 630 | 739 |
| 631 void Directory::GetDownloadProgress( | 740 void Directory::GetDownloadProgress( |
| 632 ModelType model_type, | 741 ModelType model_type, |
| 633 sync_pb::DataTypeProgressMarker* value_out) const { | 742 sync_pb::DataTypeProgressMarker* value_out) const { |
| 634 ScopedKernelLock lock(this); | 743 ScopedKernelLock lock(this); |
| 635 return value_out->CopyFrom( | 744 return value_out->CopyFrom( |
| 636 kernel_->persisted_info.download_progress[model_type]); | 745 kernel_->persisted_info.download_progress[model_type]); |
| 637 } | 746 } |
| 638 | 747 |
| (...skipping 622 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1261 // ordering. | 1370 // ordering. |
| 1262 if (entry->ref(PREV_ID).IsRoot() || | 1371 if (entry->ref(PREV_ID).IsRoot() || |
| 1263 entry->ref(PREV_ID) != entry->ref(NEXT_ID)) { | 1372 entry->ref(PREV_ID) != entry->ref(NEXT_ID)) { |
| 1264 return entry; | 1373 return entry; |
| 1265 } | 1374 } |
| 1266 } | 1375 } |
| 1267 // There were no children in the linked list. | 1376 // There were no children in the linked list. |
| 1268 return NULL; | 1377 return NULL; |
| 1269 } | 1378 } |
| 1270 | 1379 |
| 1380 /* static */ | |
| 1381 bool Directory::IsDeleteJournalEnabled(ModelType type) { | |
| 1382 switch (type) { | |
| 1383 case BOOKMARKS: | |
| 1384 return true; | |
| 1385 default: | |
| 1386 return false; | |
| 1387 } | |
| 1388 } | |
| 1389 | |
| 1271 ScopedKernelLock::ScopedKernelLock(const Directory* dir) | 1390 ScopedKernelLock::ScopedKernelLock(const Directory* dir) |
| 1272 : scoped_lock_(dir->kernel_->mutex), dir_(const_cast<Directory*>(dir)) { | 1391 : scoped_lock_(dir->kernel_->mutex), dir_(const_cast<Directory*>(dir)) { |
| 1273 } | 1392 } |
| 1274 | 1393 |
| 1275 } // namespace syncable | 1394 } // namespace syncable |
| 1276 } // namespace syncer | 1395 } // namespace syncer |
| OLD | NEW |