From 975c2bbcb9544a585e4e7d73a90678e2e97f414c Mon Sep 17 00:00:00 2001 From: Paul Beckingham Date: Thu, 16 Sep 2010 21:52:48 -0400 Subject: [PATCH] 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. --- src/dependency.cpp | 48 ++++++++++++++++++++++++++++++++++++++++++++-- src/main.h | 2 ++ src/report.cpp | 40 +++++++++++++++++--------------------- 3 files changed, 66 insertions(+), 24 deletions(-) diff --git a/src/dependency.cpp b/src/dependency.cpp index 756b678f5..eec7a48c6 100644 --- a/src/dependency.cpp +++ b/src/dependency.cpp @@ -37,12 +37,41 @@ extern Context context; static bool followUpstream (const Task&, const Task&, const std::vector &, std::vector &); //////////////////////////////////////////////////////////////////////////////// -// 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 & all = context.tdb.getAllPending (); + std::vector ::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 & blocked) +{ + std::string depends = task.get ("depends"); + if (depends != "") + { + const std::vector & all = context.tdb.getAllPending (); + std::vector ::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 & blocking) +{ + std::string uuid = task.get ("uuid"); + + const std::vector & all = context.tdb.getAllPending (); + std::vector ::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 diff --git a/src/main.h b/src/main.h index 2b238eccb..b325df6b4 100644 --- a/src/main.h +++ b/src/main.h @@ -133,7 +133,9 @@ int handleExportYAML (std::string &); // dependency.cpp bool dependencyIsBlocked (Task&); +void dependencyGetBlocked (Task&, std::vector &); bool dependencyIsBlocking (Task&); +void dependencyGetBlocking (Task&, std::vector &); bool dependencyIsCircular (Task&); bool dependencyChainBroken (Task&); std::string dependencyNag (Task&); diff --git a/src/report.cpp b/src/report.cpp index 0f539c001..c96f92bd6 100644 --- a/src/report.cpp +++ b/src/report.cpp @@ -440,37 +440,33 @@ int handleInfo (std::string &outs) // dependencies: blocked if (task->has ("depends")) { + std::vector blocked; + dependencyGetBlocked (*task, blocked); + + std::stringstream message; + std::vector ::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 & rpending = context.tdb.getAllPending (); - - std::stringstream blocked; - std::vector ::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 & rpending = context.tdb.getAllPending (); - - std::stringstream blocked; - std::vector ::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 blocking; + dependencyGetBlocking (*task, blocking); + if (blocking.size ()) { + std::stringstream message; + std::vector ::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 ()); } }