queue.cpp 7.59 KiB
#include "queue.hpp"
#include <vector>
#include <boost/algorithm/string.hpp>
#include "pempek_assert.hpp"
using namespace std;
SortableJobOrder::UpdateInformation::UpdateInformation(Rational current_date) :
current_date(current_date)
{
}
SortableJobOrder::UpdateInformation::~UpdateInformation()
{
}
SortableJobOrder::~SortableJobOrder()
{
}
FCFSOrder::FCFSOrder()
{
update_job_impact=false;
}
FCFSOrder::~FCFSOrder()
{
}
bool FCFSOrder::compare(const SortableJob *j1, const SortableJob *j2, const SortableJobOrder::CompareInformation *info) const
{
(void) info;
if (j1->release_date == j2->release_date)
return jobcmp(j1->job, j2->job);
else
return j1->release_date < j2->release_date;
}
void FCFSOrder::updateJob(SortableJob *job, const SortableJobOrder::UpdateInformation *info) const
{
(void) job;
(void) info;
}
LCFSOrder::LCFSOrder()
{
update_job_impact = false;
}
LCFSOrder::~LCFSOrder()
{
}
bool LCFSOrder::compare(const SortableJob *j1, const SortableJob *j2, const SortableJobOrder::CompareInformation *info) const
{
(void) info;
if (j1->release_date == j2->release_date)
return jobcmp(j1->job, j2->job);
else
return j1->release_date > j2->release_date;
}
void LCFSOrder::updateJob(SortableJob *job, const SortableJobOrder::UpdateInformation *info) const
{
(void) job;
(void) info;
}
AscendingSizeOrder::AscendingSizeOrder()
{
update_job_impact = false;
}
AscendingSizeOrder::~AscendingSizeOrder()
{
}
bool AscendingSizeOrder::compare(const SortableJob *j1, const SortableJob *j2, const SortableJobOrder::CompareInformation *info) const
{
(void) info;
if (j1->job->nb_requested_resources == j2->job->nb_requested_resources)
if (j1->job->submission_time == j2->job->submission_time)
return jobcmp(j1->job, j2->job);
else
return j1->job->submission_time < j2->job->submission_time;
else
return j1->job->nb_requested_resources < j2->job->nb_requested_resources;
}
void AscendingSizeOrder::updateJob(SortableJob *job, const SortableJobOrder::UpdateInformation *info) const
{
(void) job;
(void) info;
}
DescendingSizeOrder::DescendingSizeOrder()
{
update_job_impact = false;
}
DescendingSizeOrder::~DescendingSizeOrder()
{
}
bool DescendingSizeOrder::compare(const SortableJob *j1, const SortableJob *j2, const SortableJobOrder::CompareInformation *info) const
{
(void) info;
if (j1->job->nb_requested_resources == j2->job->nb_requested_resources)
if (j1->job->submission_time == j2->job->submission_time)
return jobcmp(j1->job, j2->job);
else
return j1->job->submission_time < j2->job->submission_time;
else
return j1->job->nb_requested_resources > j2->job->nb_requested_resources;
}
void DescendingSizeOrder::updateJob(SortableJob *job, const SortableJobOrder::UpdateInformation *info) const
{
(void) job;
(void) info;
}
AscendingWalltimeOrder::AscendingWalltimeOrder()
{
update_job_impact = false;
}
AscendingWalltimeOrder::~AscendingWalltimeOrder()
{
}
bool AscendingWalltimeOrder::compare(const SortableJob *j1, const SortableJob *j2, const SortableJobOrder::CompareInformation *info) const
{
(void) info;
if (j1->job->walltime == j2->job->walltime)
return jobcmp(j1->job, j2->job);
else
return j1->job->walltime < j2->job->walltime;
}
void AscendingWalltimeOrder::updateJob(SortableJob *job, const SortableJobOrder::UpdateInformation *info) const
{
(void) job;
(void) info;
}
DescendingWalltimeOrder::DescendingWalltimeOrder()
{
update_job_impact = false;
}
DescendingWalltimeOrder::~DescendingWalltimeOrder()
{
}
bool DescendingWalltimeOrder::compare(const SortableJob *j1, const SortableJob *j2, const SortableJobOrder::CompareInformation *info) const
{
(void) info;
if (j1->job->walltime == j2->job->walltime)
return jobcmp(j1->job, j2->job);
else
return j1->job->walltime > j2->job->walltime;
}
void DescendingWalltimeOrder::updateJob(SortableJob *job, const SortableJobOrder::UpdateInformation *info) const
{
(void) job;
(void) info;
}
/**********
** QUEUE **
**********/
Queue::Queue(SortableJobOrder *order) :
_order(order)
{
}
Queue::~Queue()
{
auto it = _jobs.begin();
while (it != _jobs.end())
it = remove_job((*it)->job);
}
void Queue::append_job(const Job *job, SortableJobOrder::UpdateInformation *update_info)
{
SortableJob * sjob = new SortableJob;
sjob->job = job;
sjob->release_date = update_info->current_date;
_jobs.push_back(sjob);
}
void Queue::insert_job(const Job *job)
{
SortableJob * sjob = new SortableJob;
sjob->job = job;
sjob->release_date = Rational(job->submission_time);
_jobs.push_back(sjob);
}
void Queue::insert_sorted_job(const Job * job, const SortableJobOrder::UpdateInformation *update_info , const SortableJobOrder::CompareInformation * compare_info){
SortableJob * sjob = new SortableJob;
sjob->job = job;
sjob->release_date = update_info->current_date;
auto start = _jobs.begin();
auto end = _jobs.end();
while(start!=end && _order->compare((*start), sjob, compare_info)) {
++start;
}
_jobs.insert(start,sjob);
}
std::list<SortableJob *>::iterator Queue::remove_job(const Job *job)
{
auto it = std::find_if(_jobs.begin(), _jobs.end(),
[job](SortableJob * sjob)
{
return sjob->job == job;
});
PPK_ASSERT_ERROR(it != _jobs.end(), "Cannot remove job '%s': not in the queue", job->id.c_str());
return remove_job(it);
}
std::list<SortableJob *>::iterator Queue::remove_job(std::list<SortableJob *>::iterator job_it)
{
SortableJob * sjob = *job_it;
delete sjob;
return _jobs.erase(job_it);
}
void Queue::sort_queue(SortableJobOrder::UpdateInformation *update_info,
SortableJobOrder::CompareInformation *compare_info)
{
// Update of all jobs
if (_order->update_job_impact)
{
for (SortableJob *sjob : _jobs)
_order->updateJob(sjob, update_info);
}
// Sort
_jobs.sort([this, compare_info](const SortableJob * j1, const SortableJob * j2)
{
return _order->compare(j1, j2, compare_info);
});
}
const Job* Queue::first_job() const
{
PPK_ASSERT_ERROR(_jobs.size() > 0, "No first job: Queue is empty");
return (*_jobs.begin())->job;
}
const Job *Queue::first_job_or_nullptr() const
{
if (_jobs.size() == 0)
return nullptr;
else
return first_job();
}
bool Queue::contains_job(const Job *job) const
{
auto it = std::find_if(_jobs.begin(), _jobs.end(),
[job](SortableJob * sjob)
{
return sjob->job == job;
});
return it != _jobs.end();
}
bool Queue::is_empty() const
{
return _jobs.size() == 0;
}
int Queue::nb_jobs() const
{
return _jobs.size();
}
std::string Queue::to_string() const
{
vector<string> jobs_strings;
jobs_strings.reserve(_jobs.size());
for (const SortableJob * sjob : _jobs)
jobs_strings.push_back(sjob->job->id);
return "[" + boost::algorithm::join(jobs_strings, ", ") + "]";
}
std::list<SortableJob *>::iterator Queue::begin()
{
return _jobs.begin();
}
std::list<SortableJob *>::iterator Queue::end()
{
return _jobs.end();
}
std::list<SortableJob *>::const_iterator Queue::begin() const
{
return _jobs.begin();
}
std::list<SortableJob *>::const_iterator Queue::end() const
{
return _jobs.end();
}