Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(560)

Side by Side Diff: sync/syncable/directory.cc

Issue 11441026: [Sync] Add support for loading, updating and querying delete journals in (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 8 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
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
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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698