| OLD | NEW |
| 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 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 124 SYNC_FILE_TYPE_DIRECTORY)); | 124 SYNC_FILE_TYPE_DIRECTORY)); |
| 125 } | 125 } |
| 126 | 126 |
| 127 void LocalFileChangeTracker::OnRemoveDirectory(const FileSystemURL& url) { | 127 void LocalFileChangeTracker::OnRemoveDirectory(const FileSystemURL& url) { |
| 128 RecordChange(url, FileChange(FileChange::FILE_CHANGE_DELETE, | 128 RecordChange(url, FileChange(FileChange::FILE_CHANGE_DELETE, |
| 129 SYNC_FILE_TYPE_DIRECTORY)); | 129 SYNC_FILE_TYPE_DIRECTORY)); |
| 130 } | 130 } |
| 131 | 131 |
| 132 void LocalFileChangeTracker::GetNextChangedURLs( | 132 void LocalFileChangeTracker::GetNextChangedURLs( |
| 133 std::deque<FileSystemURL>* urls, int max_urls) { | 133 std::deque<FileSystemURL>* urls, int max_urls) { |
| 134 DCHECK(file_task_runner_->RunsTasksOnCurrentThread()); |
| 134 DCHECK(urls); | 135 DCHECK(urls); |
| 135 DCHECK(file_task_runner_->RunsTasksOnCurrentThread()); | |
| 136 urls->clear(); | 136 urls->clear(); |
| 137 // Mildly prioritizes the URLs that older changes and have not been updated | 137 // Mildly prioritizes the URLs that older changes and have not been updated |
| 138 // for a while. | 138 // for a while. |
| 139 for (ChangeSeqMap::iterator iter = change_seqs_.begin(); | 139 for (ChangeSeqMap::iterator iter = change_seqs_.begin(); |
| 140 iter != change_seqs_.end() && | 140 iter != change_seqs_.end() && |
| 141 (max_urls == 0 || urls->size() < static_cast<size_t>(max_urls)); | 141 (max_urls == 0 || urls->size() < static_cast<size_t>(max_urls)); |
| 142 ++iter) { | 142 ++iter) { |
| 143 urls->push_back(iter->second); | 143 urls->push_back(iter->second); |
| 144 } | 144 } |
| 145 } | 145 } |
| (...skipping 20 matching lines...) Expand all Loading... |
| 166 FileChangeMap::iterator found = changes_.find(url); | 166 FileChangeMap::iterator found = changes_.find(url); |
| 167 if (found == changes_.end()) | 167 if (found == changes_.end()) |
| 168 return; | 168 return; |
| 169 change_seqs_.erase(found->second.change_seq); | 169 change_seqs_.erase(found->second.change_seq); |
| 170 changes_.erase(found); | 170 changes_.erase(found); |
| 171 UpdateNumChanges(); | 171 UpdateNumChanges(); |
| 172 } | 172 } |
| 173 | 173 |
| 174 void LocalFileChangeTracker::CreateFreshMirrorForURL( | 174 void LocalFileChangeTracker::CreateFreshMirrorForURL( |
| 175 const fileapi::FileSystemURL& url) { | 175 const fileapi::FileSystemURL& url) { |
| 176 DCHECK(file_task_runner_->RunsTasksOnCurrentThread()); |
| 176 DCHECK(!ContainsKey(mirror_changes_, url)); | 177 DCHECK(!ContainsKey(mirror_changes_, url)); |
| 177 mirror_changes_[url] = ChangeInfo(); | 178 mirror_changes_[url] = ChangeInfo(); |
| 178 } | 179 } |
| 179 | 180 |
| 180 void LocalFileChangeTracker::RemoveMirrorAndCommitChangesForURL( | 181 void LocalFileChangeTracker::RemoveMirrorAndCommitChangesForURL( |
| 181 const fileapi::FileSystemURL& url) { | 182 const fileapi::FileSystemURL& url) { |
| 183 DCHECK(file_task_runner_->RunsTasksOnCurrentThread()); |
| 182 FileChangeMap::iterator found = mirror_changes_.find(url); | 184 FileChangeMap::iterator found = mirror_changes_.find(url); |
| 183 if (found == mirror_changes_.end()) | 185 if (found == mirror_changes_.end()) |
| 184 return; | 186 return; |
| 185 mirror_changes_.erase(found); | 187 mirror_changes_.erase(found); |
| 186 | 188 |
| 187 if (ContainsKey(changes_, url)) | 189 if (ContainsKey(changes_, url)) |
| 188 MarkDirtyOnDatabase(url); | 190 MarkDirtyOnDatabase(url); |
| 189 else | 191 else |
| 190 ClearDirtyOnDatabase(url); | 192 ClearDirtyOnDatabase(url); |
| 191 UpdateNumChanges(); | 193 UpdateNumChanges(); |
| 192 } | 194 } |
| 193 | 195 |
| 194 void LocalFileChangeTracker::ResetToMirrorAndCommitChangesForURL( | 196 void LocalFileChangeTracker::ResetToMirrorAndCommitChangesForURL( |
| 195 const fileapi::FileSystemURL& url) { | 197 const fileapi::FileSystemURL& url) { |
| 198 DCHECK(file_task_runner_->RunsTasksOnCurrentThread()); |
| 196 FileChangeMap::iterator found = mirror_changes_.find(url); | 199 FileChangeMap::iterator found = mirror_changes_.find(url); |
| 197 if (found == mirror_changes_.end() || found->second.change_list.empty()) { | 200 if (found == mirror_changes_.end() || found->second.change_list.empty()) { |
| 198 ClearChangesForURL(url); | 201 ClearChangesForURL(url); |
| 199 return; | 202 return; |
| 200 } | 203 } |
| 201 const ChangeInfo& info = found->second; | 204 const ChangeInfo& info = found->second; |
| 202 change_seqs_[info.change_seq] = url; | 205 change_seqs_[info.change_seq] = url; |
| 203 changes_[url] = info; | 206 changes_[url] = info; |
| 204 RemoveMirrorAndCommitChangesForURL(url); | 207 RemoveMirrorAndCommitChangesForURL(url); |
| 205 } | 208 } |
| 206 | 209 |
| 207 void LocalFileChangeTracker::DemoteChangesForURL( | 210 void LocalFileChangeTracker::DemoteChangesForURL( |
| 208 const fileapi::FileSystemURL& url) { | 211 const fileapi::FileSystemURL& url) { |
| 212 DCHECK(file_task_runner_->RunsTasksOnCurrentThread()); |
| 209 FileChangeMap::iterator found = changes_.find(url); | 213 FileChangeMap::iterator found = changes_.find(url); |
| 210 if (found == changes_.end()) | 214 if (found == changes_.end()) |
| 211 return; | 215 return; |
| 212 FileChangeList changes = found->second.change_list; | 216 FileChangeList changes = found->second.change_list; |
| 213 | 217 |
| 214 mirror_changes_.erase(url); | 218 mirror_changes_.erase(url); |
| 215 change_seqs_.erase(found->second.change_seq); | 219 change_seqs_.erase(found->second.change_seq); |
| 216 changes_.erase(found); | 220 changes_.erase(found); |
| 217 | 221 |
| 218 FileChangeList::List change_list = changes.list(); | 222 FileChangeList::List change_list = changes.list(); |
| 219 while (!change_list.empty()) { | 223 while (!change_list.empty()) { |
| 220 RecordChangeToChangeMaps(url, change_list.front(), 0, | 224 RecordChangeToChangeMaps(url, change_list.front(), 0, |
| 221 &demoted_changes_, NULL); | 225 &demoted_changes_, NULL); |
| 222 change_list.pop_front(); | 226 change_list.pop_front(); |
| 223 } | 227 } |
| 224 } | 228 } |
| 225 | 229 |
| 230 void LocalFileChangeTracker::PromoteDemotedChangesForURL( |
| 231 const fileapi::FileSystemURL& url) { |
| 232 DCHECK(file_task_runner_->RunsTasksOnCurrentThread()); |
| 233 |
| 234 FileChangeMap::iterator iter = demoted_changes_.find(url); |
| 235 if (iter == demoted_changes_.end()) |
| 236 return; |
| 237 |
| 238 FileChangeList::List change_list = iter->second.change_list.list(); |
| 239 // Make sure that this URL is in no queues. |
| 240 DCHECK(!ContainsKey(changes_, url)); |
| 241 DCHECK(!ContainsKey(mirror_changes_, url)); |
| 242 |
| 243 demoted_changes_.erase(iter); |
| 244 |
| 245 while (!change_list.empty()) { |
| 246 RecordChange(url, change_list.front()); |
| 247 change_list.pop_front(); |
| 248 } |
| 249 } |
| 250 |
| 226 bool LocalFileChangeTracker::PromoteDemotedChanges() { | 251 bool LocalFileChangeTracker::PromoteDemotedChanges() { |
| 252 DCHECK(file_task_runner_->RunsTasksOnCurrentThread()); |
| 227 if (demoted_changes_.empty()) | 253 if (demoted_changes_.empty()) |
| 228 return false; | 254 return false; |
| 229 for (FileChangeMap::iterator iter = demoted_changes_.begin(); | 255 while (!demoted_changes_.empty()) { |
| 230 iter != demoted_changes_.end();) { | 256 fileapi::FileSystemURL url = demoted_changes_.begin()->first; |
| 231 fileapi::FileSystemURL url = iter->first; | 257 PromoteDemotedChangesForURL(url); |
| 232 FileChangeList::List change_list = iter->second.change_list.list(); | |
| 233 demoted_changes_.erase(iter++); | |
| 234 | |
| 235 // Make sure that this URL is in no queues. | |
| 236 DCHECK(!ContainsKey(changes_, url)); | |
| 237 DCHECK(!ContainsKey(demoted_changes_, url)); | |
| 238 DCHECK(!ContainsKey(mirror_changes_, url)); | |
| 239 | |
| 240 while (!change_list.empty()) { | |
| 241 RecordChange(url, change_list.front()); | |
| 242 change_list.pop_front(); | |
| 243 } | |
| 244 } | 258 } |
| 245 demoted_changes_.clear(); | |
| 246 return true; | 259 return true; |
| 247 } | 260 } |
| 248 | 261 |
| 249 SyncStatusCode LocalFileChangeTracker::Initialize( | 262 SyncStatusCode LocalFileChangeTracker::Initialize( |
| 250 FileSystemContext* file_system_context) { | 263 FileSystemContext* file_system_context) { |
| 251 DCHECK(file_task_runner_->RunsTasksOnCurrentThread()); | 264 DCHECK(file_task_runner_->RunsTasksOnCurrentThread()); |
| 252 DCHECK(!initialized_); | 265 DCHECK(!initialized_); |
| 253 DCHECK(file_system_context); | 266 DCHECK(file_system_context); |
| 254 | 267 |
| 255 SyncStatusCode status = CollectLastDirtyChanges(file_system_context); | 268 SyncStatusCode status = CollectLastDirtyChanges(file_system_context); |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 289 tracker_db_->WriteBatch(batch.Pass()); | 302 tracker_db_->WriteBatch(batch.Pass()); |
| 290 UpdateNumChanges(); | 303 UpdateNumChanges(); |
| 291 } | 304 } |
| 292 | 305 |
| 293 void LocalFileChangeTracker::UpdateNumChanges() { | 306 void LocalFileChangeTracker::UpdateNumChanges() { |
| 294 base::AutoLock lock(num_changes_lock_); | 307 base::AutoLock lock(num_changes_lock_); |
| 295 num_changes_ = static_cast<int64>(change_seqs_.size()); | 308 num_changes_ = static_cast<int64>(change_seqs_.size()); |
| 296 } | 309 } |
| 297 | 310 |
| 298 void LocalFileChangeTracker::GetAllChangedURLs(FileSystemURLSet* urls) { | 311 void LocalFileChangeTracker::GetAllChangedURLs(FileSystemURLSet* urls) { |
| 312 DCHECK(file_task_runner_->RunsTasksOnCurrentThread()); |
| 299 std::deque<FileSystemURL> url_deque; | 313 std::deque<FileSystemURL> url_deque; |
| 300 GetNextChangedURLs(&url_deque, 0); | 314 GetNextChangedURLs(&url_deque, 0); |
| 301 urls->clear(); | 315 urls->clear(); |
| 302 urls->insert(url_deque.begin(), url_deque.end()); | 316 urls->insert(url_deque.begin(), url_deque.end()); |
| 303 } | 317 } |
| 304 | 318 |
| 305 void LocalFileChangeTracker::DropAllChanges() { | 319 void LocalFileChangeTracker::DropAllChanges() { |
| 320 DCHECK(file_task_runner_->RunsTasksOnCurrentThread()); |
| 306 changes_.clear(); | 321 changes_.clear(); |
| 307 change_seqs_.clear(); | 322 change_seqs_.clear(); |
| 308 mirror_changes_.clear(); | 323 mirror_changes_.clear(); |
| 309 } | 324 } |
| 310 | 325 |
| 311 SyncStatusCode LocalFileChangeTracker::MarkDirtyOnDatabase( | 326 SyncStatusCode LocalFileChangeTracker::MarkDirtyOnDatabase( |
| 312 const FileSystemURL& url) { | 327 const FileSystemURL& url) { |
| 313 std::string serialized_url; | 328 std::string serialized_url; |
| 314 if (!SerializeSyncableFileSystemURL(url, &serialized_url)) | 329 if (!SerializeSyncableFileSystemURL(url, &serialized_url)) |
| 315 return SYNC_FILE_ERROR_INVALID_URL; | 330 return SYNC_FILE_ERROR_INVALID_URL; |
| 316 | 331 |
| 317 return tracker_db_->MarkDirty(serialized_url); | 332 return tracker_db_->MarkDirty(serialized_url); |
| 318 } | 333 } |
| 319 | 334 |
| 320 SyncStatusCode LocalFileChangeTracker::ClearDirtyOnDatabase( | 335 SyncStatusCode LocalFileChangeTracker::ClearDirtyOnDatabase( |
| 321 const FileSystemURL& url) { | 336 const FileSystemURL& url) { |
| 337 DCHECK(file_task_runner_->RunsTasksOnCurrentThread()); |
| 322 std::string serialized_url; | 338 std::string serialized_url; |
| 323 if (!SerializeSyncableFileSystemURL(url, &serialized_url)) | 339 if (!SerializeSyncableFileSystemURL(url, &serialized_url)) |
| 324 return SYNC_FILE_ERROR_INVALID_URL; | 340 return SYNC_FILE_ERROR_INVALID_URL; |
| 325 | 341 |
| 326 return tracker_db_->ClearDirty(serialized_url); | 342 return tracker_db_->ClearDirty(serialized_url); |
| 327 } | 343 } |
| 328 | 344 |
| 329 SyncStatusCode LocalFileChangeTracker::CollectLastDirtyChanges( | 345 SyncStatusCode LocalFileChangeTracker::CollectLastDirtyChanges( |
| 330 FileSystemContext* file_system_context) { | 346 FileSystemContext* file_system_context) { |
| 331 DCHECK(file_task_runner_->RunsTasksOnCurrentThread()); | 347 DCHECK(file_task_runner_->RunsTasksOnCurrentThread()); |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 400 RecordChangeToChangeMaps(url, change, 0, &demoted_changes_, NULL); | 416 RecordChangeToChangeMaps(url, change, 0, &demoted_changes_, NULL); |
| 401 return; | 417 return; |
| 402 } | 418 } |
| 403 int change_seq = current_change_seq_++; | 419 int change_seq = current_change_seq_++; |
| 404 RecordChangeToChangeMaps(url, change, change_seq, &changes_, &change_seqs_); | 420 RecordChangeToChangeMaps(url, change, change_seq, &changes_, &change_seqs_); |
| 405 if (ContainsKey(mirror_changes_, url)) | 421 if (ContainsKey(mirror_changes_, url)) |
| 406 RecordChangeToChangeMaps(url, change, change_seq, &mirror_changes_, NULL); | 422 RecordChangeToChangeMaps(url, change, change_seq, &mirror_changes_, NULL); |
| 407 UpdateNumChanges(); | 423 UpdateNumChanges(); |
| 408 } | 424 } |
| 409 | 425 |
| 426 // static |
| 410 void LocalFileChangeTracker::RecordChangeToChangeMaps( | 427 void LocalFileChangeTracker::RecordChangeToChangeMaps( |
| 411 const FileSystemURL& url, | 428 const FileSystemURL& url, |
| 412 const FileChange& change, | 429 const FileChange& change, |
| 413 int new_change_seq, | 430 int new_change_seq, |
| 414 FileChangeMap* changes, | 431 FileChangeMap* changes, |
| 415 ChangeSeqMap* change_seqs) { | 432 ChangeSeqMap* change_seqs) { |
| 416 ChangeInfo& info = (*changes)[url]; | 433 ChangeInfo& info = (*changes)[url]; |
| 417 if (info.change_seq >= 0 && change_seqs) | 434 if (info.change_seq >= 0 && change_seqs) |
| 418 change_seqs->erase(info.change_seq); | 435 change_seqs->erase(info.change_seq); |
| 419 info.change_list.Update(change); | 436 info.change_list.Update(change); |
| (...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 573 if (!status.ok() && !status.IsNotFound()) { | 590 if (!status.ok() && !status.IsNotFound()) { |
| 574 HandleError(FROM_HERE, status); | 591 HandleError(FROM_HERE, status); |
| 575 db_status_ = LevelDBStatusToSyncStatusCode(status); | 592 db_status_ = LevelDBStatusToSyncStatusCode(status); |
| 576 db_.reset(); | 593 db_.reset(); |
| 577 return db_status_; | 594 return db_status_; |
| 578 } | 595 } |
| 579 return SYNC_STATUS_OK; | 596 return SYNC_STATUS_OK; |
| 580 } | 597 } |
| 581 | 598 |
| 582 } // namespace sync_file_system | 599 } // namespace sync_file_system |
| OLD | NEW |