summaryrefslogtreecommitdiffstats
path: root/sync/syncable
diff options
context:
space:
mode:
Diffstat (limited to 'sync/syncable')
-rw-r--r--sync/syncable/directory.cc21
-rw-r--r--sync/syncable/directory.h12
-rw-r--r--sync/syncable/syncable_mock.h2
-rw-r--r--sync/syncable/syncable_unittest.cc8
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));