Index: chrome/browser/sync_file_system/local/local_file_change_tracker.cc |
diff --git a/chrome/browser/sync_file_system/local/local_file_change_tracker.cc b/chrome/browser/sync_file_system/local/local_file_change_tracker.cc |
index d112285047c9a8d04a52c0945c4ada2d0363335d..1adb927c02ced92aa89ea34fdcda945757226d9f 100644 |
--- a/chrome/browser/sync_file_system/local/local_file_change_tracker.cc |
+++ b/chrome/browser/sync_file_system/local/local_file_change_tracker.cc |
@@ -79,7 +79,7 @@ LocalFileChangeTracker::LocalFileChangeTracker( |
: initialized_(false), |
file_task_runner_(file_task_runner), |
tracker_db_(new TrackerDB(base_path, env_override)), |
- current_change_seq_(0), |
+ current_change_seq_number_(0), |
num_changes_(0) { |
} |
@@ -90,7 +90,7 @@ LocalFileChangeTracker::~LocalFileChangeTracker() { |
void LocalFileChangeTracker::OnStartUpdate(const FileSystemURL& url) { |
DCHECK(file_task_runner_->RunsTasksOnCurrentThread()); |
- if (ContainsKey(changes_, url)) |
+ if (ContainsKey(changes_, url) || ContainsKey(demoted_changes_, url)) |
return; |
// TODO(nhiroki): propagate the error code (see http://crbug.com/152127). |
MarkDirtyOnDatabase(url); |
@@ -186,7 +186,7 @@ void LocalFileChangeTracker::RemoveMirrorAndCommitChangesForURL( |
return; |
mirror_changes_.erase(found); |
- if (ContainsKey(changes_, url)) |
+ if (ContainsKey(changes_, url) || ContainsKey(demoted_changes_, url)) |
MarkDirtyOnDatabase(url); |
else |
ClearDirtyOnDatabase(url); |
@@ -202,29 +202,28 @@ void LocalFileChangeTracker::ResetToMirrorAndCommitChangesForURL( |
return; |
} |
const ChangeInfo& info = found->second; |
- change_seqs_[info.change_seq] = url; |
- changes_[url] = info; |
+ if (ContainsKey(demoted_changes_, url)) { |
+ DCHECK(!ContainsKey(changes_, url)); |
+ demoted_changes_[url] = info; |
+ } else { |
+ DCHECK(!ContainsKey(demoted_changes_, url)); |
+ change_seqs_[info.change_seq] = url; |
+ changes_[url] = info; |
+ } |
RemoveMirrorAndCommitChangesForURL(url); |
} |
void LocalFileChangeTracker::DemoteChangesForURL( |
const fileapi::FileSystemURL& url) { |
DCHECK(file_task_runner_->RunsTasksOnCurrentThread()); |
+ |
FileChangeMap::iterator found = changes_.find(url); |
if (found == changes_.end()) |
return; |
- FileChangeList changes = found->second.change_list; |
- |
- mirror_changes_.erase(url); |
+ DCHECK(!ContainsKey(demoted_changes_, url)); |
change_seqs_.erase(found->second.change_seq); |
+ demoted_changes_.insert(*found); |
changes_.erase(found); |
- |
- FileChangeList::List change_list = changes.list(); |
- while (!change_list.empty()) { |
- RecordChangeToChangeMaps(url, change_list.front(), 0, |
- &demoted_changes_, NULL); |
- change_list.pop_front(); |
- } |
UpdateNumChanges(); |
} |
@@ -238,15 +237,12 @@ void LocalFileChangeTracker::PromoteDemotedChangesForURL( |
FileChangeList::List change_list = iter->second.change_list.list(); |
// Make sure that this URL is in no queues. |
+ DCHECK(!ContainsKey(change_seqs_, iter->second.change_seq)); |
DCHECK(!ContainsKey(changes_, url)); |
- DCHECK(!ContainsKey(mirror_changes_, url)); |
+ change_seqs_[iter->second.change_seq] = url; |
+ changes_.insert(*iter); |
demoted_changes_.erase(iter); |
- |
- while (!change_list.empty()) { |
- RecordChange(url, change_list.front()); |
- change_list.pop_front(); |
- } |
} |
bool LocalFileChangeTracker::PromoteDemotedChanges() { |
@@ -281,24 +277,25 @@ void LocalFileChangeTracker::ResetForFileSystem( |
for (FileChangeMap::iterator iter = changes_.begin(); |
iter != changes_.end();) { |
fileapi::FileSystemURL url = iter->first; |
- if (url.origin() != origin || url.type() != type) { |
- ++iter; |
- continue; |
- } |
- mirror_changes_.erase(url); |
- demoted_changes_.erase(url); |
- change_seqs_.erase(iter->second.change_seq); |
- changes_.erase(iter++); |
- |
- std::string serialized_url; |
- const bool should_success = |
- SerializeSyncableFileSystemURL(url, &serialized_url); |
- if (!should_success) { |
- NOTREACHED() << "Failed to serialize: " << url.DebugString(); |
- continue; |
- } |
- batch->Delete(serialized_url); |
+ int change_seq = iter->second.change_seq; |
+ // Advance |iter| before calling ResetForURL to avoid the iterator |
+ // invalidation in it. |
+ ++iter; |
+ if (url.origin() == origin && url.type() == type) |
+ ResetForURL(url, change_seq, batch.get()); |
} |
+ |
+ for (FileChangeMap::iterator iter = demoted_changes_.begin(); |
+ iter != demoted_changes_.end();) { |
+ fileapi::FileSystemURL url = iter->first; |
+ int change_seq = iter->second.change_seq; |
+ // Advance |iter| before calling ResetForURL to avoid the iterator |
+ // invalidation in it. |
+ ++iter; |
+ if (url.origin() == origin && url.type() == type) |
+ ResetForURL(url, change_seq, batch.get()); |
+ } |
+ |
// Fail to apply batch to database wouldn't have critical effect, they'll be |
// just marked deleted on next relaunch. |
tracker_db_->WriteBatch(batch.Pass()); |
@@ -415,12 +412,13 @@ SyncStatusCode LocalFileChangeTracker::CollectLastDirtyChanges( |
void LocalFileChangeTracker::RecordChange( |
const FileSystemURL& url, const FileChange& change) { |
DCHECK(file_task_runner_->RunsTasksOnCurrentThread()); |
+ int change_seq = current_change_seq_number_++; |
if (ContainsKey(demoted_changes_, url)) { |
- RecordChangeToChangeMaps(url, change, 0, &demoted_changes_, NULL); |
- return; |
+ RecordChangeToChangeMaps(url, change, change_seq, |
+ &demoted_changes_, NULL); |
+ } else { |
+ RecordChangeToChangeMaps(url, change, change_seq, &changes_, &change_seqs_); |
} |
- int change_seq = current_change_seq_++; |
- RecordChangeToChangeMaps(url, change, change_seq, &changes_, &change_seqs_); |
if (ContainsKey(mirror_changes_, url)) |
RecordChangeToChangeMaps(url, change, change_seq, &mirror_changes_, NULL); |
UpdateNumChanges(); |
@@ -446,6 +444,22 @@ void LocalFileChangeTracker::RecordChangeToChangeMaps( |
(*change_seqs)[info.change_seq] = url; |
} |
+void LocalFileChangeTracker::ResetForURL(const fileapi::FileSystemURL& url, |
+ int change_seq, |
+ leveldb::WriteBatch* batch) { |
+ mirror_changes_.erase(url); |
+ demoted_changes_.erase(url); |
+ change_seqs_.erase(change_seq); |
+ changes_.erase(url); |
+ |
+ std::string serialized_url; |
+ if (!SerializeSyncableFileSystemURL(url, &serialized_url)) { |
+ NOTREACHED() << "Failed to serialize: " << url.DebugString(); |
+ return; |
+ } |
+ batch->Delete(serialized_url); |
+} |
+ |
// TrackerDB ------------------------------------------------------------------- |
LocalFileChangeTracker::TrackerDB::TrackerDB(const base::FilePath& base_path, |