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

Side by Side Diff: chrome/browser/sync_file_system/local/local_file_change_tracker.cc

Issue 394033005: [SyncFS] Make the snapshot sync of local-to-remote sync parallelization enabled. (2/3) (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: rebase Created 6 years, 5 months 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 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 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 "chrome/browser/sync_file_system/local/local_file_change_tracker.h" 5 #include "chrome/browser/sync_file_system/local/local_file_change_tracker.h"
6 6
7 #include <queue> 7 #include <queue>
8 8
9 #include "base/location.h" 9 #include "base/location.h"
10 #include "base/logging.h" 10 #include "base/logging.h"
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
83 num_changes_(0) { 83 num_changes_(0) {
84 } 84 }
85 85
86 LocalFileChangeTracker::~LocalFileChangeTracker() { 86 LocalFileChangeTracker::~LocalFileChangeTracker() {
87 DCHECK(file_task_runner_->RunsTasksOnCurrentThread()); 87 DCHECK(file_task_runner_->RunsTasksOnCurrentThread());
88 tracker_db_.reset(); 88 tracker_db_.reset();
89 } 89 }
90 90
91 void LocalFileChangeTracker::OnStartUpdate(const FileSystemURL& url) { 91 void LocalFileChangeTracker::OnStartUpdate(const FileSystemURL& url) {
92 DCHECK(file_task_runner_->RunsTasksOnCurrentThread()); 92 DCHECK(file_task_runner_->RunsTasksOnCurrentThread());
93 if (ContainsKey(changes_, url)) 93 if (ContainsKey(changes_, url) || ContainsKey(demoted_changes_, url))
94 return; 94 return;
95 // TODO(nhiroki): propagate the error code (see http://crbug.com/152127). 95 // TODO(nhiroki): propagate the error code (see http://crbug.com/152127).
96 MarkDirtyOnDatabase(url); 96 MarkDirtyOnDatabase(url);
97 } 97 }
98 98
99 void LocalFileChangeTracker::OnEndUpdate(const FileSystemURL& url) {} 99 void LocalFileChangeTracker::OnEndUpdate(const FileSystemURL& url) {}
100 100
101 void LocalFileChangeTracker::OnCreateFile(const FileSystemURL& url) { 101 void LocalFileChangeTracker::OnCreateFile(const FileSystemURL& url) {
102 RecordChange(url, FileChange(FileChange::FILE_CHANGE_ADD_OR_UPDATE, 102 RecordChange(url, FileChange(FileChange::FILE_CHANGE_ADD_OR_UPDATE,
103 SYNC_FILE_TYPE_FILE)); 103 SYNC_FILE_TYPE_FILE));
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
179 } 179 }
180 180
181 void LocalFileChangeTracker::RemoveMirrorAndCommitChangesForURL( 181 void LocalFileChangeTracker::RemoveMirrorAndCommitChangesForURL(
182 const fileapi::FileSystemURL& url) { 182 const fileapi::FileSystemURL& url) {
183 DCHECK(file_task_runner_->RunsTasksOnCurrentThread()); 183 DCHECK(file_task_runner_->RunsTasksOnCurrentThread());
184 FileChangeMap::iterator found = mirror_changes_.find(url); 184 FileChangeMap::iterator found = mirror_changes_.find(url);
185 if (found == mirror_changes_.end()) 185 if (found == mirror_changes_.end())
186 return; 186 return;
187 mirror_changes_.erase(found); 187 mirror_changes_.erase(found);
188 188
189 if (ContainsKey(changes_, url)) 189 if (ContainsKey(changes_, url) || ContainsKey(demoted_changes_, url))
190 MarkDirtyOnDatabase(url); 190 MarkDirtyOnDatabase(url);
191 else 191 else
192 ClearDirtyOnDatabase(url); 192 ClearDirtyOnDatabase(url);
193 UpdateNumChanges(); 193 UpdateNumChanges();
194 } 194 }
195 195
196 void LocalFileChangeTracker::ResetToMirrorAndCommitChangesForURL( 196 void LocalFileChangeTracker::ResetToMirrorAndCommitChangesForURL(
197 const fileapi::FileSystemURL& url) { 197 const fileapi::FileSystemURL& url) {
198 DCHECK(file_task_runner_->RunsTasksOnCurrentThread()); 198 DCHECK(file_task_runner_->RunsTasksOnCurrentThread());
199 FileChangeMap::iterator found = mirror_changes_.find(url); 199 FileChangeMap::iterator found = mirror_changes_.find(url);
200 if (found == mirror_changes_.end() || found->second.change_list.empty()) { 200 if (found == mirror_changes_.end() || found->second.change_list.empty()) {
201 ClearChangesForURL(url); 201 ClearChangesForURL(url);
202 return; 202 return;
203 } 203 }
204 const ChangeInfo& info = found->second; 204 const ChangeInfo& info = found->second;
205 change_seqs_[info.change_seq] = url; 205 if (ContainsKey(demoted_changes_, url)) {
nhiroki 2014/07/23 06:37:13 Can you have "DCHECK(!ContainsKey(changes_, url))"
tzik 2014/07/24 15:35:20 Done.
206 changes_[url] = info; 206 demoted_changes_[url] = info;
207 } else {
nhiroki 2014/07/23 06:37:13 ditto: "DCHECK(!ContainsKey(demoted_changes_, url)
tzik 2014/07/24 15:35:20 Done.
208 change_seqs_[info.change_seq] = url;
209 changes_[url] = info;
210 }
207 RemoveMirrorAndCommitChangesForURL(url); 211 RemoveMirrorAndCommitChangesForURL(url);
208 } 212 }
209 213
210 void LocalFileChangeTracker::DemoteChangesForURL( 214 void LocalFileChangeTracker::DemoteChangesForURL(
211 const fileapi::FileSystemURL& url) { 215 const fileapi::FileSystemURL& url) {
212 DCHECK(file_task_runner_->RunsTasksOnCurrentThread()); 216 DCHECK(file_task_runner_->RunsTasksOnCurrentThread());
217
213 FileChangeMap::iterator found = changes_.find(url); 218 FileChangeMap::iterator found = changes_.find(url);
214 if (found == changes_.end()) 219 if (found == changes_.end())
215 return; 220 return;
216 FileChangeList changes = found->second.change_list; 221 DCHECK(!ContainsKey(demoted_changes_, url));
217
218 mirror_changes_.erase(url);
219 change_seqs_.erase(found->second.change_seq); 222 change_seqs_.erase(found->second.change_seq);
223 demoted_changes_.insert(*found);
220 changes_.erase(found); 224 changes_.erase(found);
221 225 UpdateNumChanges();
222 FileChangeList::List change_list = changes.list();
223 while (!change_list.empty()) {
224 RecordChangeToChangeMaps(url, change_list.front(), 0,
225 &demoted_changes_, NULL);
226 change_list.pop_front();
227 }
228 } 226 }
229 227
230 void LocalFileChangeTracker::PromoteDemotedChangesForURL( 228 void LocalFileChangeTracker::PromoteDemotedChangesForURL(
231 const fileapi::FileSystemURL& url) { 229 const fileapi::FileSystemURL& url) {
232 DCHECK(file_task_runner_->RunsTasksOnCurrentThread()); 230 DCHECK(file_task_runner_->RunsTasksOnCurrentThread());
233 231
234 FileChangeMap::iterator iter = demoted_changes_.find(url); 232 FileChangeMap::iterator iter = demoted_changes_.find(url);
235 if (iter == demoted_changes_.end()) 233 if (iter == demoted_changes_.end())
236 return; 234 return;
237 235
238 FileChangeList::List change_list = iter->second.change_list.list(); 236 FileChangeList::List change_list = iter->second.change_list.list();
239 // Make sure that this URL is in no queues. 237 // Make sure that this URL is in no queues.
238 DCHECK(!ContainsKey(change_seqs_, iter->second.change_seq));
240 DCHECK(!ContainsKey(changes_, url)); 239 DCHECK(!ContainsKey(changes_, url));
241 DCHECK(!ContainsKey(mirror_changes_, url));
242 240
241 change_seqs_[iter->second.change_seq] = url;
242 changes_.insert(*iter);
243 demoted_changes_.erase(iter); 243 demoted_changes_.erase(iter);
244
245 while (!change_list.empty()) {
246 RecordChange(url, change_list.front());
247 change_list.pop_front();
248 }
249 } 244 }
250 245
251 bool LocalFileChangeTracker::PromoteDemotedChanges() { 246 bool LocalFileChangeTracker::PromoteDemotedChanges() {
252 DCHECK(file_task_runner_->RunsTasksOnCurrentThread()); 247 DCHECK(file_task_runner_->RunsTasksOnCurrentThread());
253 if (demoted_changes_.empty()) 248 if (demoted_changes_.empty())
254 return false; 249 return false;
255 while (!demoted_changes_.empty()) { 250 while (!demoted_changes_.empty()) {
256 fileapi::FileSystemURL url = demoted_changes_.begin()->first; 251 fileapi::FileSystemURL url = demoted_changes_.begin()->first;
257 PromoteDemotedChangesForURL(url); 252 PromoteDemotedChangesForURL(url);
258 } 253 }
254 UpdateNumChanges();
259 return true; 255 return true;
260 } 256 }
261 257
262 SyncStatusCode LocalFileChangeTracker::Initialize( 258 SyncStatusCode LocalFileChangeTracker::Initialize(
263 FileSystemContext* file_system_context) { 259 FileSystemContext* file_system_context) {
264 DCHECK(file_task_runner_->RunsTasksOnCurrentThread()); 260 DCHECK(file_task_runner_->RunsTasksOnCurrentThread());
265 DCHECK(!initialized_); 261 DCHECK(!initialized_);
266 DCHECK(file_system_context); 262 DCHECK(file_system_context);
267 263
268 SyncStatusCode status = CollectLastDirtyChanges(file_system_context); 264 SyncStatusCode status = CollectLastDirtyChanges(file_system_context);
269 if (status == SYNC_STATUS_OK) 265 if (status == SYNC_STATUS_OK)
270 initialized_ = true; 266 initialized_ = true;
271 return status; 267 return status;
272 } 268 }
273 269
274 void LocalFileChangeTracker::ResetForFileSystem( 270 void LocalFileChangeTracker::ResetForFileSystem(
275 const GURL& origin, 271 const GURL& origin,
276 fileapi::FileSystemType type) { 272 fileapi::FileSystemType type) {
277 DCHECK(file_task_runner_->RunsTasksOnCurrentThread()); 273 DCHECK(file_task_runner_->RunsTasksOnCurrentThread());
278 scoped_ptr<leveldb::WriteBatch> batch(new leveldb::WriteBatch); 274 scoped_ptr<leveldb::WriteBatch> batch(new leveldb::WriteBatch);
279 for (FileChangeMap::iterator iter = changes_.begin(); 275 for (FileChangeMap::iterator iter = changes_.begin();
280 iter != changes_.end();) { 276 iter != changes_.end();) {
281 fileapi::FileSystemURL url = iter->first; 277 fileapi::FileSystemURL url = iter->first;
282 if (url.origin() != origin || url.type() != type) { 278 int change_seq = iter->second.change_seq;
283 ++iter; 279 // Advance |iter| before calling ResetForURL to avoid the iterator
284 continue; 280 // invalidation in it.
285 } 281 ++iter;
286 mirror_changes_.erase(url); 282 if (url.origin() == origin && url.type() == type)
287 demoted_changes_.erase(url); 283 ResetForURL(url, change_seq, batch.get());
288 change_seqs_.erase(iter->second.change_seq); 284 }
289 changes_.erase(iter++);
290 285
291 std::string serialized_url; 286 for (FileChangeMap::iterator iter = demoted_changes_.begin();
292 const bool should_success = 287 iter != demoted_changes_.end();) {
293 SerializeSyncableFileSystemURL(url, &serialized_url); 288 fileapi::FileSystemURL url = iter->first;
294 if (!should_success) { 289 int change_seq = iter->second.change_seq;
295 NOTREACHED() << "Failed to serialize: " << url.DebugString(); 290 // Advance |iter| before calling ResetForURL to avoid the iterator
296 continue; 291 // invalidation in it.
297 } 292 ++iter;
298 batch->Delete(serialized_url); 293 if (url.origin() == origin && url.type() == type)
294 ResetForURL(url, change_seq, batch.get());
299 } 295 }
296
300 // Fail to apply batch to database wouldn't have critical effect, they'll be 297 // Fail to apply batch to database wouldn't have critical effect, they'll be
301 // just marked deleted on next relaunch. 298 // just marked deleted on next relaunch.
302 tracker_db_->WriteBatch(batch.Pass()); 299 tracker_db_->WriteBatch(batch.Pass());
303 UpdateNumChanges(); 300 UpdateNumChanges();
304 } 301 }
305 302
306 void LocalFileChangeTracker::UpdateNumChanges() { 303 void LocalFileChangeTracker::UpdateNumChanges() {
307 base::AutoLock lock(num_changes_lock_); 304 base::AutoLock lock(num_changes_lock_);
308 num_changes_ = static_cast<int64>(change_seqs_.size()); 305 num_changes_ = static_cast<int64>(change_seqs_.size());
309 } 306 }
310 307
311 void LocalFileChangeTracker::GetAllChangedURLs(FileSystemURLSet* urls) { 308 void LocalFileChangeTracker::GetAllChangedURLs(FileSystemURLSet* urls) {
312 DCHECK(file_task_runner_->RunsTasksOnCurrentThread()); 309 DCHECK(file_task_runner_->RunsTasksOnCurrentThread());
313 std::deque<FileSystemURL> url_deque; 310 std::deque<FileSystemURL> url_deque;
314 GetNextChangedURLs(&url_deque, 0); 311 GetNextChangedURLs(&url_deque, 0);
315 urls->clear(); 312 urls->clear();
316 urls->insert(url_deque.begin(), url_deque.end()); 313 urls->insert(url_deque.begin(), url_deque.end());
317 } 314 }
318 315
319 void LocalFileChangeTracker::DropAllChanges() { 316 void LocalFileChangeTracker::DropAllChanges() {
320 DCHECK(file_task_runner_->RunsTasksOnCurrentThread()); 317 DCHECK(file_task_runner_->RunsTasksOnCurrentThread());
321 changes_.clear(); 318 changes_.clear();
322 change_seqs_.clear(); 319 change_seqs_.clear();
323 mirror_changes_.clear(); 320 mirror_changes_.clear();
321 UpdateNumChanges();
324 } 322 }
325 323
326 SyncStatusCode LocalFileChangeTracker::MarkDirtyOnDatabase( 324 SyncStatusCode LocalFileChangeTracker::MarkDirtyOnDatabase(
327 const FileSystemURL& url) { 325 const FileSystemURL& url) {
328 std::string serialized_url; 326 std::string serialized_url;
329 if (!SerializeSyncableFileSystemURL(url, &serialized_url)) 327 if (!SerializeSyncableFileSystemURL(url, &serialized_url))
330 return SYNC_FILE_ERROR_INVALID_URL; 328 return SYNC_FILE_ERROR_INVALID_URL;
331 329
332 return tracker_db_->MarkDirty(serialized_url); 330 return tracker_db_->MarkDirty(serialized_url);
333 } 331 }
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
405 LOG(WARNING) << "Failed to access local file."; 403 LOG(WARNING) << "Failed to access local file.";
406 break; 404 break;
407 } 405 }
408 } 406 }
409 return SYNC_STATUS_OK; 407 return SYNC_STATUS_OK;
410 } 408 }
411 409
412 void LocalFileChangeTracker::RecordChange( 410 void LocalFileChangeTracker::RecordChange(
413 const FileSystemURL& url, const FileChange& change) { 411 const FileSystemURL& url, const FileChange& change) {
414 DCHECK(file_task_runner_->RunsTasksOnCurrentThread()); 412 DCHECK(file_task_runner_->RunsTasksOnCurrentThread());
413 int change_seq = current_change_seq_++;
415 if (ContainsKey(demoted_changes_, url)) { 414 if (ContainsKey(demoted_changes_, url)) {
416 RecordChangeToChangeMaps(url, change, 0, &demoted_changes_, NULL); 415 RecordChangeToChangeMaps(url, change, change_seq,
417 return; 416 &demoted_changes_, NULL);
417 } else{
418 RecordChangeToChangeMaps(url, change, change_seq, &changes_, &change_seqs_);
418 } 419 }
419 int change_seq = current_change_seq_++;
420 RecordChangeToChangeMaps(url, change, change_seq, &changes_, &change_seqs_);
421 if (ContainsKey(mirror_changes_, url)) 420 if (ContainsKey(mirror_changes_, url))
422 RecordChangeToChangeMaps(url, change, change_seq, &mirror_changes_, NULL); 421 RecordChangeToChangeMaps(url, change, change_seq, &mirror_changes_, NULL);
423 UpdateNumChanges(); 422 UpdateNumChanges();
424 } 423 }
425 424
426 // static 425 // static
427 void LocalFileChangeTracker::RecordChangeToChangeMaps( 426 void LocalFileChangeTracker::RecordChangeToChangeMaps(
428 const FileSystemURL& url, 427 const FileSystemURL& url,
429 const FileChange& change, 428 const FileChange& change,
430 int new_change_seq, 429 int new_change_seq,
431 FileChangeMap* changes, 430 FileChangeMap* changes,
432 ChangeSeqMap* change_seqs) { 431 ChangeSeqMap* change_seqs) {
433 ChangeInfo& info = (*changes)[url]; 432 ChangeInfo& info = (*changes)[url];
434 if (info.change_seq >= 0 && change_seqs) 433 if (info.change_seq >= 0 && change_seqs)
435 change_seqs->erase(info.change_seq); 434 change_seqs->erase(info.change_seq);
436 info.change_list.Update(change); 435 info.change_list.Update(change);
437 if (info.change_list.empty()) { 436 if (info.change_list.empty()) {
438 changes->erase(url); 437 changes->erase(url);
439 return; 438 return;
440 } 439 }
441 info.change_seq = new_change_seq; 440 info.change_seq = new_change_seq;
442 if (change_seqs) 441 if (change_seqs)
443 (*change_seqs)[info.change_seq] = url; 442 (*change_seqs)[info.change_seq] = url;
444 } 443 }
445 444
445 void LocalFileChangeTracker::ResetForURL(const fileapi::FileSystemURL& url,
446 int change_seq,
447 leveldb::WriteBatch* batch) {
448 mirror_changes_.erase(url);
449 demoted_changes_.erase(url);
450 change_seqs_.erase(change_seq);
451 changes_.erase(url);
452
453 std::string serialized_url;
454 if (!SerializeSyncableFileSystemURL(url, &serialized_url)) {
455 NOTREACHED() << "Failed to serialize: " << url.DebugString();
456 return;
457 }
458 batch->Delete(serialized_url);
459 }
460
446 // TrackerDB ------------------------------------------------------------------- 461 // TrackerDB -------------------------------------------------------------------
447 462
448 LocalFileChangeTracker::TrackerDB::TrackerDB(const base::FilePath& base_path, 463 LocalFileChangeTracker::TrackerDB::TrackerDB(const base::FilePath& base_path,
449 leveldb::Env* env_override) 464 leveldb::Env* env_override)
450 : base_path_(base_path), 465 : base_path_(base_path),
451 env_override_(env_override), 466 env_override_(env_override),
452 db_status_(SYNC_STATUS_OK) {} 467 db_status_(SYNC_STATUS_OK) {}
453 468
454 SyncStatusCode LocalFileChangeTracker::TrackerDB::Init( 469 SyncStatusCode LocalFileChangeTracker::TrackerDB::Init(
455 RecoveryOption recovery_option) { 470 RecoveryOption recovery_option) {
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after
590 if (!status.ok() && !status.IsNotFound()) { 605 if (!status.ok() && !status.IsNotFound()) {
591 HandleError(FROM_HERE, status); 606 HandleError(FROM_HERE, status);
592 db_status_ = LevelDBStatusToSyncStatusCode(status); 607 db_status_ = LevelDBStatusToSyncStatusCode(status);
593 db_.reset(); 608 db_.reset();
594 return db_status_; 609 return db_status_;
595 } 610 }
596 return SYNC_STATUS_OK; 611 return SYNC_STATUS_OK;
597 } 612 }
598 613
599 } // namespace sync_file_system 614 } // namespace sync_file_system
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698