Dependencies

- Added dependencyGetBlocking and dependencyGetBlocked API calls, in
  the ongoing effort to find a workable API for dependencies.  The
  goal is to make the calling code as small as possible when dealing
  with dependencies.
- Corrected the algorithm for determining whether a task is blocked or
  blocking to also check that the other task is pending or waiting.
  For example:
    task add one
    task add two depends:1
    task do 1
  As the first task is completed, task 2 still depends on 1, but is
  no longer blocked due to the completed status.
- Modified the "info" report to use the modified API.
This commit is contained in:
Paul Beckingham 2010-09-16 21:52:48 -04:00
parent 8904daf9e5
commit 975c2bbcb9
3 changed files with 66 additions and 24 deletions

View file

@ -37,12 +37,41 @@ extern Context context;
static bool followUpstream (const Task&, const Task&, const std::vector <Task>&, std::vector <std::string>&);
////////////////////////////////////////////////////////////////////////////////
// All it takes to be blocked is to depend on another task.
// A task is blocked if it depends on tasks that are pending or waiting.
bool dependencyIsBlocked (Task& task)
{
return task.has ("depends");
if (task.has ("depends"))
{
std::string depends = task.get ("depends");
const std::vector <Task>& all = context.tdb.getAllPending ();
std::vector <Task>::const_iterator it;
for (it = all.begin (); it != all.end (); ++it)
if ((it->getStatus () == Task::pending ||
it->getStatus () == Task::waiting) &&
depends.find (it->get ("uuid")) != std::string::npos)
return true;
}
return false;
}
////////////////////////////////////////////////////////////////////////////////
void dependencyGetBlocked (Task& task, std::vector <Task>& blocked)
{
std::string depends = task.get ("depends");
if (depends != "")
{
const std::vector <Task>& all = context.tdb.getAllPending ();
std::vector <Task>::const_iterator it;
for (it = all.begin (); it != all.end (); ++it)
if ((it->getStatus () == Task::pending ||
it->getStatus () == Task::waiting) &&
depends.find (it->get ("uuid")) != std::string::npos)
blocked.push_back (*it);
}
}
////////////////////////////////////////////////////////////////////////////////
// To be a blocking task, there must be at least one other task that depends on
// this task, that is either pending or waiting.
@ -62,6 +91,21 @@ bool dependencyIsBlocking (Task& task)
return false;
}
////////////////////////////////////////////////////////////////////////////////
void dependencyGetBlocking (Task& task, std::vector <Task>& blocking)
{
std::string uuid = task.get ("uuid");
const std::vector <Task>& all = context.tdb.getAllPending ();
std::vector <Task>::const_iterator it;
for (it = all.begin (); it != all.end (); ++it)
if ((it->getStatus () == Task::pending ||
it->getStatus () == Task::waiting) &&
it->has ("depends") &&
it->get ("depends").find (uuid) != std::string::npos)
blocking.push_back (*it);
}
////////////////////////////////////////////////////////////////////////////////
// Terminology:
// --> if a depends on b, then it can be said that a --> b

View file

@ -133,7 +133,9 @@ int handleExportYAML (std::string &);
// dependency.cpp
bool dependencyIsBlocked (Task&);
void dependencyGetBlocked (Task&, std::vector <Task>&);
bool dependencyIsBlocking (Task&);
void dependencyGetBlocking (Task&, std::vector <Task>&);
bool dependencyIsCircular (Task&);
bool dependencyChainBroken (Task&);
std::string dependencyNag (Task&);

View file

@ -440,37 +440,33 @@ int handleInfo (std::string &outs)
// dependencies: blocked
if (task->has ("depends"))
{
std::vector <Task> blocked;
dependencyGetBlocked (*task, blocked);
std::stringstream message;
std::vector <Task>::const_iterator it;
for (it = blocked.begin (); it != blocked.end (); ++it)
message << it->id << " " << it->get ("description") << "\n";
row = table.addRow ();
table.addCell (row, 0, "This task blocked by");
std::string depends = task->get ("depends");
const std::vector <Task>& rpending = context.tdb.getAllPending ();
std::stringstream blocked;
std::vector <Task>::const_iterator it;
for (it = rpending.begin (); it != rpending.end (); ++it)
if (depends.find (it->get ("uuid")) != std::string::npos)
blocked << it->id << " " << it->get ("description") << "\n";
table.addCell (row, 1, blocked.str ());
table.addCell (row, 1, message.str ());
}
// dependencies: blocking
{
std::string uuid = task->get ("uuid");
const std::vector <Task>& rpending = context.tdb.getAllPending ();
std::stringstream blocked;
std::vector <Task>::const_iterator it;
for (it = rpending.begin (); it != rpending.end (); ++it)
if (it->get ("depends").find (uuid) != std::string::npos)
blocked << it->id << " " << it->get ("description") << "\n";
if (blocked.str().length ())
std::vector <Task> blocking;
dependencyGetBlocking (*task, blocking);
if (blocking.size ())
{
std::stringstream message;
std::vector <Task>::const_iterator it;
for (it = blocking.begin (); it != blocking.end (); ++it)
message << it->id << " " << it->get ("description") << "\n";
row = table.addRow ();
table.addCell (row, 0, "This task is blocking");
table.addCell (row, 1, blocked.str ());
table.addCell (row, 1, message.str ());
}
}