diff options
Diffstat (limited to 'sync/syncable')
-rw-r--r-- | sync/syncable/directory.cc | 21 | ||||
-rw-r--r-- | sync/syncable/directory.h | 12 | ||||
-rw-r--r-- | sync/syncable/syncable_mock.h | 2 | ||||
-rw-r--r-- | sync/syncable/syncable_unittest.cc | 8 |
4 files changed, 32 insertions, 11 deletions
diff --git a/sync/syncable/directory.cc b/sync/syncable/directory.cc index 69edfb0..7b58364 100644 --- a/sync/syncable/directory.cc +++ b/sync/syncable/directory.cc @@ -561,12 +561,19 @@ bool Directory::VacuumAfterSaveChanges(const SaveChangesSnapshot& snapshot) { return true; } -bool Directory::PurgeEntriesWithTypeIn(ModelTypeSet types) { +bool Directory::PurgeEntriesWithTypeIn(ModelTypeSet types, + ModelTypeSet types_to_journal) { + DCHECK(types.HasAll(types_to_journal)); + if (types.Empty()) return true; { WriteTransaction trans(FROM_HERE, PURGE_ENTRIES, this); + + EntryKernelSet entries_to_journal; + STLElementDeleter<EntryKernelSet> journal_deleter(&entries_to_journal); + { ScopedKernelLock lock(this); MetahandlesIndex::iterator it = kernel_->metahandles_index->begin(); @@ -600,12 +607,22 @@ bool Directory::PurgeEntriesWithTypeIn(ModelTypeSet types) { num_erased = kernel_->parent_id_child_index->erase(entry); DCHECK_EQ(entry->ref(IS_DEL), !num_erased); kernel_->metahandles_index->erase(it++); - delete entry; + + if ((types_to_journal.Has(local_type) || + types_to_journal.Has(server_type)) && + (delete_journal_->IsDeleteJournalEnabled(local_type) || + delete_journal_->IsDeleteJournalEnabled(server_type))) { + entries_to_journal.insert(entry); + } else { + delete entry; + } } else { ++it; } } + delete_journal_->AddJournalBatch(&trans, entries_to_journal); + // Ensure meta tracking for these data types reflects the deleted state. for (ModelTypeSet::Iterator it = types.First(); it.Good(); it.Inc()) { diff --git a/sync/syncable/directory.h b/sync/syncable/directory.h index 6aa10b2..f55ba4e 100644 --- a/sync/syncable/directory.h +++ b/sync/syncable/directory.h @@ -442,14 +442,18 @@ class SYNC_EXPORT Directory { bool FullyCheckTreeInvariants(BaseTransaction *trans); // Purges all data associated with any entries whose ModelType or - // ServerModelType is found in |types|, from _both_ memory and disk. - // Only valid, "real" model types are allowed in |types| (see model_type.h - // for definitions). "Purge" is just meant to distinguish from "deleting" + // ServerModelType is found in |types|, from sync directory _both_ in memory + // and on disk. |types_to_journal| should be subset of |types| and data + // of |types_to_journal| are saved in delete journal to help prevent + // back-from-dead problem due to offline delete in next sync session. Only + // valid, "real" model types are allowed in |types| (see model_type.h for + // definitions). "Purge" is just meant to distinguish from "deleting" // entries, which means something different in the syncable namespace. // WARNING! This can be real slow, as it iterates over all entries. // WARNING! Performs synchronous I/O. // Returns: true on success, false if an error was encountered. - virtual bool PurgeEntriesWithTypeIn(ModelTypeSet types); + virtual bool PurgeEntriesWithTypeIn(ModelTypeSet types, + ModelTypeSet types_to_journal); private: // A helper that implements the logic of checking tree invariants. diff --git a/sync/syncable/syncable_mock.h b/sync/syncable/syncable_mock.h index 089bd31..55068ed 100644 --- a/sync/syncable/syncable_mock.h +++ b/sync/syncable/syncable_mock.h @@ -28,7 +28,7 @@ class MockDirectory : public Directory { MOCK_METHOD1(GetEntryByClientTag, syncable::EntryKernel*(const std::string&)); - MOCK_METHOD1(PurgeEntriesWithTypeIn, bool(ModelTypeSet)); + MOCK_METHOD2(PurgeEntriesWithTypeIn, bool(ModelTypeSet, ModelTypeSet)); private: syncable::NullDirectoryChangeDelegate delegate_; diff --git a/sync/syncable/syncable_unittest.cc b/sync/syncable/syncable_unittest.cc index 444e9e3..b6f767a 100644 --- a/sync/syncable/syncable_unittest.cc +++ b/sync/syncable/syncable_unittest.cc @@ -561,7 +561,7 @@ TEST_F(SyncableDirectoryTest, TakeSnapshotGetsMetahandlesToPurge) { } ModelTypeSet to_purge(BOOKMARKS); - dir_->PurgeEntriesWithTypeIn(to_purge); + dir_->PurgeEntriesWithTypeIn(to_purge, ModelTypeSet()); Directory::SaveChangesSnapshot snapshot1; base::AutoLock scoped_lock(dir_->kernel_->save_changes_mutex); @@ -570,7 +570,7 @@ TEST_F(SyncableDirectoryTest, TakeSnapshotGetsMetahandlesToPurge) { to_purge.Clear(); to_purge.Put(PREFERENCES); - dir_->PurgeEntriesWithTypeIn(to_purge); + dir_->PurgeEntriesWithTypeIn(to_purge, ModelTypeSet()); dir_->HandleSaveChangesFailure(snapshot1); @@ -1738,7 +1738,7 @@ TEST_F(OnDiskSyncableDirectoryTest, TestPurgeEntriesWithTypeIn) { ASSERT_EQ(10U, all_set.size()); } - dir_->PurgeEntriesWithTypeIn(types_to_purge); + dir_->PurgeEntriesWithTypeIn(types_to_purge, ModelTypeSet()); // We first query the in-memory data, and then reload the directory (without // saving) to verify that disk does not still have the data. @@ -1999,7 +1999,7 @@ TEST_F(OnDiskSyncableDirectoryTest, TestSaveChangesFailureWithPurge) { ASSERT_TRUE(dir_->good()); ModelTypeSet set(BOOKMARKS); - dir_->PurgeEntriesWithTypeIn(set); + dir_->PurgeEntriesWithTypeIn(set, ModelTypeSet()); EXPECT_TRUE(IsInMetahandlesToPurge(handle1)); ASSERT_FALSE(dir_->SaveChanges()); EXPECT_TRUE(IsInMetahandlesToPurge(handle1)); |