1a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved.
2a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
3a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// found in the LICENSE file.
4a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
5a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "chrome/browser/sync_file_system/drive_backend/task_dependency_manager.h"
6a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
7a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include <utility>
8a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
9a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "base/logging.h"
10a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
11a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)namespace sync_file_system {
12a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)namespace drive_backend {
13a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
14a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)namespace {
15a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
16a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// Erases all items in |item_to_erase| from |container|.
17a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)template <typename Container1, typename Container2>
18a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void EraseContainer(const Container1& items_to_erase, Container2* container) {
19a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  for (typename Container1::const_iterator itr = items_to_erase.begin();
20a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)       itr != items_to_erase.end(); ++itr) {
21a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    container->erase(*itr);
22a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
23a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
24a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
25a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// Inserts all items in |items_to_insert| to |container|, returns true if all
26a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// items are inserted successfully.  Otherwise, returns false and leave
27a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// |container| have the original contents.
28a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)template <typename Container1, typename Container2>
29a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)bool InsertAllOrNone(const Container1& items_to_insert, Container2* container) {
30a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  typedef typename Container1::const_iterator iterator;
31a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  for (iterator itr = items_to_insert.begin();
32a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)       itr != items_to_insert.end(); ++itr) {
33a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    if (!container->insert(*itr).second) {
34a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      // Revert all successful insertion.
35a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      iterator end = itr;
36a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      itr = items_to_insert.begin();
37a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      for (; itr != end; ++itr)
38a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        container->erase(*itr);
39a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      return false;
40a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    }
41a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
42a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  return true;
43a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
44a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
45a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)bool InsertPaths(std::vector<base::FilePath> paths_to_insert,
46a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                 SubtreeSet* paths) {
47a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  typedef std::vector<base::FilePath>::const_iterator iterator;
48a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  for (iterator itr = paths_to_insert.begin();
49a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)       itr != paths_to_insert.end(); ++itr) {
50a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    if (!paths->insert(*itr)) {
51a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      iterator end = itr;
52a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      for (itr = paths_to_insert.begin(); itr != end; ++itr)
53a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        paths->erase(*itr);
54a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      return false;
55a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    }
56a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
57a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  return true;
58a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
59a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
60a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}  // namespace
61a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
621320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciTaskBlocker::TaskBlocker() : exclusive(false) {}
631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciTaskBlocker::~TaskBlocker() {}
64a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
65effb81e5f8246d0db0270817048dc992db66e9fbBen MurdochTaskDependencyManager::TaskDependencyManager()
66a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    : running_task_count_(0),
67a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      running_exclusive_task_(false) {}
68a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
69a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)TaskDependencyManager::~TaskDependencyManager() {
70a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  DCHECK(paths_by_app_id_.empty());
71a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  DCHECK(file_ids_.empty());
72a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  DCHECK(tracker_ids_.empty());
73a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
74a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
751320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccibool TaskDependencyManager::Insert(const TaskBlocker* task_blocker) {
76effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  if (running_exclusive_task_)
77effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    return false;
78effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
791320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (!task_blocker) {
80a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    ++running_task_count_;
81a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    return true;
82a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  }
83a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch
841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (task_blocker->exclusive) {
85a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    if (running_task_count_ ||
86a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        !tracker_ids_.empty() ||
87effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch        !file_ids_.empty() ||
88effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch        !paths_by_app_id_.empty())
89effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      return false;
90a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    ++running_task_count_;
91effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    running_exclusive_task_ = true;
92effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    return true;
93effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  }
94effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
951320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (!InsertAllOrNone(task_blocker->tracker_ids, &tracker_ids_))
96a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    goto fail_on_tracker_id_insertion;
97a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (!InsertAllOrNone(task_blocker->file_ids, &file_ids_))
99a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    goto fail_on_file_id_insertion;
100a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
1011320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (!task_blocker->app_id.empty() &&
1021320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      !InsertPaths(task_blocker->paths,
1031320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                   &paths_by_app_id_[task_blocker->app_id])) {
1041320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    if (paths_by_app_id_[task_blocker->app_id].empty())
1051320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      paths_by_app_id_.erase(task_blocker->app_id);
106a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    goto fail_on_path_insertion;
107a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
108a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
109a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  ++running_task_count_;
110a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  return true;
111a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
112a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) fail_on_path_insertion:
1131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EraseContainer(task_blocker->file_ids, &file_ids_);
114a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) fail_on_file_id_insertion:
1151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EraseContainer(task_blocker->tracker_ids, &tracker_ids_);
116a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) fail_on_tracker_id_insertion:
117a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
118a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  return false;
119a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
120a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
1211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid TaskDependencyManager::Erase(const TaskBlocker* task_blocker) {
122a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  --running_task_count_;
123a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  DCHECK_LE(0, running_task_count_);
1241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (!task_blocker)
125a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    return;
126a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch
1271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (task_blocker->exclusive) {
128effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    DCHECK(running_exclusive_task_);
129effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    DCHECK(paths_by_app_id_.empty());
130effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    DCHECK(file_ids_.empty());
131effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    DCHECK(tracker_ids_.empty());
132a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    DCHECK_EQ(0, running_task_count_);
133effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
134effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    running_exclusive_task_ = false;
135effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    return;
136effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  }
137effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
1381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (!task_blocker->app_id.empty()) {
1391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    EraseContainer(task_blocker->paths,
1401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                   &paths_by_app_id_[task_blocker->app_id]);
1411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    if (paths_by_app_id_[task_blocker->app_id].empty())
1421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      paths_by_app_id_.erase(task_blocker->app_id);
14323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  }
144a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
1451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EraseContainer(task_blocker->file_ids, &file_ids_);
1461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EraseContainer(task_blocker->tracker_ids, &tracker_ids_);
147a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
148a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
149a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}  // namespace drive_backend
150a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}  // namespace sync_file_system
151