190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved.
290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// found in the LICENSE file.
490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "chrome/browser/chromeos/drive/job_queue.h"
690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
7eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include <algorithm>
8eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "base/logging.h"
105e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)#include "base/strings/stringprintf.h"
1190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
1290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)namespace drive {
1390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
1490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)JobQueue::JobQueue(size_t num_max_concurrent_jobs,
1590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                   size_t num_priority_levels)
1690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    : num_max_concurrent_jobs_(num_max_concurrent_jobs),
1790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      queue_(num_priority_levels) {
1890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
1990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
2090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)JobQueue::~JobQueue() {
2190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
2290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
2390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)bool JobQueue::PopForRun(int accepted_priority, JobID* id) {
2490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  DCHECK_LT(accepted_priority, static_cast<int>(queue_.size()));
2590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
2690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // Too many jobs are running already.
2790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  if (running_.size() >= num_max_concurrent_jobs_)
2890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    return false;
2990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
3090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // Looks up the queue in the order of priority upto |accepted_priority|.
3190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  for (int priority = 0; priority <= accepted_priority; ++priority) {
3290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    if (!queue_[priority].empty()) {
3390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      *id = queue_[priority].front();
3490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      queue_[priority].pop_front();
3590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      running_.insert(*id);
3690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      return true;
3790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    }
3890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  }
3990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  return false;
4090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
4190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
42eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochvoid JobQueue::GetQueuedJobs(int priority, std::vector<JobID>* jobs) const {
43eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  DCHECK_LT(priority, static_cast<int>(queue_.size()));
44eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
45eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  jobs->assign(queue_[priority].begin(), queue_[priority].end());
46eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
47eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
4890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void JobQueue::Push(JobID id, int priority) {
4990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  DCHECK_LT(priority, static_cast<int>(queue_.size()));
5090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
5190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  queue_[priority].push_back(id);
5290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
5390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
5490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void JobQueue::MarkFinished(JobID id) {
5590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  size_t num_erased = running_.erase(id);
5690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  DCHECK_EQ(1U, num_erased);
5790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
5890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
5990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)std::string JobQueue::ToString() const {
6090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  size_t pending = 0;
6190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  for (size_t i = 0; i < queue_.size(); ++i)
6290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    pending += queue_[i].size();
6390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  return base::StringPrintf("pending: %d, running: %d",
6490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                            static_cast<int>(pending),
6590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                            static_cast<int>(running_.size()));
6690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
6790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
6890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)size_t JobQueue::GetNumberOfJobs() const {
6990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  size_t count = running_.size();
7090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  for (size_t i = 0; i < queue_.size(); ++i)
7190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    count += queue_[i].size();
7290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  return count;
7390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
7490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
75eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochvoid JobQueue::Remove(JobID id) {
76eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  for (size_t i = 0; i < queue_.size(); ++i) {
77eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    std::deque<JobID>::iterator iter =
78eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        std::find(queue_[i].begin(), queue_[i].end(), id);
79eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    if (iter != queue_[i].end()) {
80eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      queue_[i].erase(iter);
81eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      break;
82eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    }
83eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  }
84eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
85eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
8690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}  // namespace drive
87