task_dependency_manager.cc revision effb81e5f8246d0db0270817048dc992db66e9fb
1// Copyright 2014 The Chromium Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5#include "chrome/browser/sync_file_system/drive_backend/task_dependency_manager.h" 6 7#include <utility> 8 9#include "base/logging.h" 10 11namespace sync_file_system { 12namespace drive_backend { 13 14namespace { 15 16// Erases all items in |item_to_erase| from |container|. 17template <typename Container1, typename Container2> 18void EraseContainer(const Container1& items_to_erase, Container2* container) { 19 for (typename Container1::const_iterator itr = items_to_erase.begin(); 20 itr != items_to_erase.end(); ++itr) { 21 container->erase(*itr); 22 } 23} 24 25// Inserts all items in |items_to_insert| to |container|, returns true if all 26// items are inserted successfully. Otherwise, returns false and leave 27// |container| have the original contents. 28template <typename Container1, typename Container2> 29bool InsertAllOrNone(const Container1& items_to_insert, Container2* container) { 30 typedef typename Container1::const_iterator iterator; 31 for (iterator itr = items_to_insert.begin(); 32 itr != items_to_insert.end(); ++itr) { 33 if (!container->insert(*itr).second) { 34 // Revert all successful insertion. 35 iterator end = itr; 36 itr = items_to_insert.begin(); 37 for (; itr != end; ++itr) 38 container->erase(*itr); 39 return false; 40 } 41 } 42 return true; 43} 44 45bool InsertPaths(std::vector<base::FilePath> paths_to_insert, 46 SubtreeSet* paths) { 47 typedef std::vector<base::FilePath>::const_iterator iterator; 48 for (iterator itr = paths_to_insert.begin(); 49 itr != paths_to_insert.end(); ++itr) { 50 if (!paths->insert(*itr)) { 51 iterator end = itr; 52 for (itr = paths_to_insert.begin(); itr != end; ++itr) 53 paths->erase(*itr); 54 return false; 55 } 56 } 57 return true; 58} 59 60} // namespace 61 62BlockingFactor::BlockingFactor() : exclusive(false) {} 63BlockingFactor::~BlockingFactor() {} 64 65TaskDependencyManager::TaskDependencyManager() 66 : running_exclusive_task_(false) {} 67 68TaskDependencyManager::~TaskDependencyManager() { 69 DCHECK(paths_by_app_id_.empty()); 70 DCHECK(file_ids_.empty()); 71 DCHECK(tracker_ids_.empty()); 72} 73 74bool TaskDependencyManager::Insert(const BlockingFactor& blocking_factor) { 75 if (running_exclusive_task_) 76 return false; 77 78 if (blocking_factor.exclusive) { 79 if (!tracker_ids_.empty() || 80 !file_ids_.empty() || 81 !paths_by_app_id_.empty()) 82 return false; 83 running_exclusive_task_ = true; 84 return true; 85 } 86 87 if (!InsertAllOrNone(blocking_factor.tracker_ids, &tracker_ids_)) 88 goto fail_on_tracker_id_insertion; 89 90 if (!InsertAllOrNone(blocking_factor.file_ids, &file_ids_)) 91 goto fail_on_file_id_insertion; 92 93 if (!blocking_factor.app_id.empty() && 94 !InsertPaths(blocking_factor.paths, 95 &paths_by_app_id_[blocking_factor.app_id])) { 96 if (paths_by_app_id_[blocking_factor.app_id].empty()) 97 paths_by_app_id_.erase(blocking_factor.app_id); 98 goto fail_on_path_insertion; 99 } 100 101 return true; 102 103 fail_on_path_insertion: 104 EraseContainer(blocking_factor.file_ids, &file_ids_); 105 fail_on_file_id_insertion: 106 EraseContainer(blocking_factor.tracker_ids, &tracker_ids_); 107 fail_on_tracker_id_insertion: 108 109 return false; 110} 111 112void TaskDependencyManager::Erase(const BlockingFactor& blocking_factor) { 113 if (blocking_factor.exclusive) { 114 DCHECK(running_exclusive_task_); 115 DCHECK(paths_by_app_id_.empty()); 116 DCHECK(file_ids_.empty()); 117 DCHECK(tracker_ids_.empty()); 118 119 running_exclusive_task_ = false; 120 return; 121 } 122 123 if (!blocking_factor.app_id.empty()) { 124 EraseContainer(blocking_factor.paths, 125 &paths_by_app_id_[blocking_factor.app_id]); 126 if (paths_by_app_id_[blocking_factor.app_id].empty()) 127 paths_by_app_id_.erase(blocking_factor.app_id); 128 } 129 130 EraseContainer(blocking_factor.file_ids, &file_ids_); 131 EraseContainer(blocking_factor.tracker_ids, &tracker_ids_); 132} 133 134} // namespace drive_backend 135} // namespace sync_file_system 136