Remove references to the 'depends' property outside of Task.cpp

With the exception of `taskDifferences` and `taskInfoDifferences`,
deferred to #2572.
This commit is contained in:
Dustin J. Mitchell 2021-08-15 17:18:47 +00:00 committed by Tomas Babej
parent 9e67f4f946
commit 413b8d22b7
11 changed files with 92 additions and 92 deletions

View file

@ -515,8 +515,6 @@ void TF2::dependency_scan ()
{ {
// Iterate and modify TDB2 in-place. Don't do this at home. // Iterate and modify TDB2 in-place. Don't do this at home.
for (auto& left : _tasks) for (auto& left : _tasks)
{
if (left.has ("depends"))
{ {
for (auto& dep : left.getDependencyUUIDs ()) for (auto& dep : left.getDependencyUUIDs ())
{ {
@ -542,7 +540,6 @@ void TF2::dependency_scan ()
} }
} }
} }
}
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////

View file

@ -1258,6 +1258,15 @@ void Task::removeDependency (int id)
throw format ("Could not delete a dependency on task {1} - not found.", id); throw format ("Could not delete a dependency on task {1} - not found.", id);
} }
////////////////////////////////////////////////////////////////////////////////
bool Task::hasDependency (const std::string& uuid) const
{
auto deps = split (get ("depends"), ',');
auto i = std::find (deps.begin (), deps.end (), uuid);
return i != deps.end ();
}
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
std::vector <int> Task::getDependencyIDs () const std::vector <int> Task::getDependencyIDs () const
{ {
@ -1277,15 +1286,36 @@ std::vector <std::string> Task::getDependencyUUIDs () const
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
std::vector <Task> Task::getDependencyTasks () const std::vector <Task> Task::getDependencyTasks () const
{ {
std::vector <Task> all; auto depends = get ("depends");
for (auto& dep : split (get ("depends"), ','))
{
Task task;
Context::getContext ().tdb2.get (dep, task);
all.push_back (task);
}
return all; // NOTE: this may seem inefficient, but note that `TDB2::get` performs a
// linear search on each invocation, so scanning *once* is quite a bit more
// efficient.
std::vector <Task> blocking;
if (depends != "")
for (auto& it : Context::getContext ().tdb2.pending.get_tasks ())
if (it.getStatus () != Task::completed &&
it.getStatus () != Task::deleted &&
depends.find (it.get ("uuid")) != std::string::npos)
blocking.push_back (it);
return blocking;
}
////////////////////////////////////////////////////////////////////////////////
std::vector <Task> Task::getBlockedTasks () const
{
auto uuid = get ("uuid");
std::vector <Task> blocked;
for (auto& it : Context::getContext ().tdb2.pending.get_tasks ())
if (it.getStatus () != Task::completed &&
it.getStatus () != Task::deleted &&
it.has ("depends") &&
it.get ("depends").find (uuid) != std::string::npos)
blocked.push_back (it);
return blocked;
} }
#endif #endif
@ -2038,9 +2068,9 @@ float Task::urgency_inherit () const
{ {
float v = FLT_MIN; float v = FLT_MIN;
#ifdef PRODUCT_TASKWARRIOR #ifdef PRODUCT_TASKWARRIOR
// Calling dependencyGetBlocked is rather expensive. // Calling getBlockedTasks is rather expensive.
// It is called recursively for each dependency in the chain here. // It is called recursively for each dependency in the chain here.
for (auto& task : dependencyGetBlocked (*this)) for (auto& task : getBlockedTasks ())
{ {
// Find highest urgency in all blocked tasks. // Find highest urgency in all blocked tasks.
v = std::max (v, task.urgency ()); v = std::max (v, task.urgency ());

View file

@ -144,8 +144,10 @@ public:
#ifdef PRODUCT_TASKWARRIOR #ifdef PRODUCT_TASKWARRIOR
void removeDependency (int); void removeDependency (int);
void removeDependency (const std::string&); void removeDependency (const std::string&);
bool hasDependency (const std::string&) const;
std::vector <int> getDependencyIDs () const; std::vector <int> getDependencyIDs () const;
std::vector <std::string> getDependencyUUIDs () const; std::vector <std::string> getDependencyUUIDs () const;
std::vector <Task> getBlockedTasks () const;
std::vector <Task> getDependencyTasks () const; std::vector <Task> getDependencyTasks () const;
std::vector <std::string> getUDAOrphanUUIDs () const; std::vector <std::string> getUDAOrphanUUIDs () const;

View file

@ -68,7 +68,9 @@ void ColumnDepends::setStyle (const std::string& value)
void ColumnDepends::measure (Task& task, unsigned int& minimum, unsigned int& maximum) void ColumnDepends::measure (Task& task, unsigned int& minimum, unsigned int& maximum)
{ {
minimum = maximum = 0; minimum = maximum = 0;
if (task.has (_name)) auto deptasks = task.getDependencyTasks ();
if (deptasks.size () > 0)
{ {
if (_style == "indicator") if (_style == "indicator")
{ {
@ -77,25 +79,24 @@ void ColumnDepends::measure (Task& task, unsigned int& minimum, unsigned int& ma
else if (_style == "count") else if (_style == "count")
{ {
minimum = maximum = 2 + format ((int) dependencyGetBlocking (task).size ()).length (); minimum = maximum = 2 + format ((int) deptasks.size ()).length ();
} }
else if (_style == "default" || else if (_style == "default" ||
_style == "list") _style == "list")
{ {
minimum = maximum = 0; minimum = maximum = 0;
auto blocking = dependencyGetBlocking (task);
std::vector <int> blocking_ids; std::vector <int> blocking_ids;
blocking_ids.reserve(blocking.size()); blocking_ids.reserve(deptasks.size());
for (auto& i : blocking) for (auto& i : deptasks)
blocking_ids.push_back (i.id); blocking_ids.push_back (i.id);
auto all = join (" ", blocking_ids); auto all = join (" ", blocking_ids);
maximum = all.length (); maximum = all.length ();
unsigned int length; unsigned int length;
for (auto& i : blocking) for (auto& i : deptasks)
{ {
length = format (i.id).length (); length = format (i.id).length ();
if (length > minimum) if (length > minimum)
@ -112,7 +113,9 @@ void ColumnDepends::render (
int width, int width,
Color& color) Color& color)
{ {
if (task.has (_name)) auto deptasks = task.getDependencyTasks ();
if (deptasks.size () > 0)
{ {
if (_style == "indicator") if (_style == "indicator")
{ {
@ -121,17 +124,15 @@ void ColumnDepends::render (
else if (_style == "count") else if (_style == "count")
{ {
renderStringRight (lines, width, color, '[' + format (static_cast <int>(dependencyGetBlocking (task).size ())) + ']'); renderStringRight (lines, width, color, '[' + format (static_cast <int>(deptasks.size ())) + ']');
} }
else if (_style == "default" || else if (_style == "default" ||
_style == "list") _style == "list")
{ {
auto blocking = dependencyGetBlocking (task);
std::vector <int> blocking_ids; std::vector <int> blocking_ids;
blocking_ids.reserve(blocking.size()); blocking_ids.reserve(deptasks.size());
for (const auto& t : blocking) for (const auto& t : deptasks)
blocking_ids.push_back (t.id); blocking_ids.push_back (t.id);
auto combined = join (" ", blocking_ids); auto combined = join (" ", blocking_ids);

View file

@ -667,7 +667,8 @@ void CmdEdit::parseTask (Task& task, const std::string& after, const std::string
value = findValue (after, "\n Dependencies:"); value = findValue (after, "\n Dependencies:");
auto dependencies = split (value, ','); auto dependencies = split (value, ',');
task.remove ("depends"); for (auto& dep : task.getDependencyUUIDs ())
task.removeDependency (dep);
for (auto& dep : dependencies) for (auto& dep : dependencies)
{ {
if (dep.length () >= 7) if (dep.length () >= 7)

View file

@ -147,7 +147,7 @@ int CmdInfo::execute (std::string& output)
// dependencies: blocked // dependencies: blocked
{ {
auto blocked = dependencyGetBlocking (task); auto blocked = task.getDependencyTasks ();
if (blocked.size ()) if (blocked.size ())
{ {
std::stringstream message; std::stringstream message;
@ -162,7 +162,7 @@ int CmdInfo::execute (std::string& output)
// dependencies: blocking // dependencies: blocking
{ {
auto blocking = dependencyGetBlocked (task); auto blocking = task.getBlockedTasks ();
if (blocking.size ()) if (blocking.size ())
{ {
std::stringstream message; std::stringstream message;

View file

@ -71,8 +71,7 @@ void CmdPurge::handleDeps (Task& task)
for (auto& blockedConst: Context::getContext ().tdb2.all_tasks ()) for (auto& blockedConst: Context::getContext ().tdb2.all_tasks ())
{ {
Task& blocked = const_cast<Task&>(blockedConst); Task& blocked = const_cast<Task&>(blockedConst);
if (blocked.has ("depends") && if (blocked.hasDependency (uuid))
blocked.get ("depends").find (uuid) != std::string::npos)
{ {
blocked.removeDependency (uuid); blocked.removeDependency (uuid);
Context::getContext ().tdb2.modify (blocked); Context::getContext ().tdb2.modify (blocked);

View file

@ -36,38 +36,6 @@
#define STRING_DEPEND_BLOCKED "Task {1} is blocked by:" #define STRING_DEPEND_BLOCKED "Task {1} is blocked by:"
////////////////////////////////////////////////////////////////////////////////
std::vector <Task> dependencyGetBlocked (const Task& task)
{
auto uuid = task.get ("uuid");
std::vector <Task> blocked;
for (auto& it : Context::getContext ().tdb2.pending.get_tasks ())
if (it.getStatus () != Task::completed &&
it.getStatus () != Task::deleted &&
it.has ("depends") &&
it.get ("depends").find (uuid) != std::string::npos)
blocked.push_back (it);
return blocked;
}
////////////////////////////////////////////////////////////////////////////////
std::vector <Task> dependencyGetBlocking (const Task& task)
{
auto depends = task.get ("depends");
std::vector <Task> blocking;
if (depends != "")
for (auto& it : Context::getContext ().tdb2.pending.get_tasks ())
if (it.getStatus () != Task::completed &&
it.getStatus () != Task::deleted &&
depends.find (it.get ("uuid")) != std::string::npos)
blocking.push_back (it);
return blocking;
}
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// Returns true if the supplied task adds a cycle to the dependency chain. // Returns true if the supplied task adds a cycle to the dependency chain.
bool dependencyIsCircular (const Task& task) bool dependencyIsCircular (const Task& task)
@ -150,12 +118,12 @@ bool dependencyIsCircular (const Task& task)
// //
void dependencyChainOnComplete (Task& task) void dependencyChainOnComplete (Task& task)
{ {
auto blocking = dependencyGetBlocking (task); auto blocking = task.getDependencyTasks ();
// If the task is anything but the tail end of a dependency chain. // If the task is anything but the tail end of a dependency chain.
if (blocking.size ()) if (blocking.size ())
{ {
auto blocked = dependencyGetBlocked (task); auto blocked = task.getBlockedTasks ();
// Nag about broken chain. // Nag about broken chain.
if (Context::getContext ().config.getBoolean ("dependency.reminder")) if (Context::getContext ().config.getBoolean ("dependency.reminder"))
@ -207,7 +175,7 @@ void dependencyChainOnStart (Task& task)
{ {
if (Context::getContext ().config.getBoolean ("dependency.reminder")) if (Context::getContext ().config.getBoolean ("dependency.reminder"))
{ {
auto blocking = dependencyGetBlocking (task); auto blocking = task.getDependencyTasks ();
// If the task is anything but the tail end of a dependency chain, nag about // If the task is anything but the tail end of a dependency chain, nag about
// broken chain. // broken chain.

View file

@ -78,6 +78,7 @@ std::string taskDifferences (const Task& before, const Task& after)
<< format ("{1} will be deleted.", Lexer::ucFirst (name)) << format ("{1} will be deleted.", Lexer::ucFirst (name))
<< "\n"; << "\n";
// TODO: #2572 - rewrite to look at dep_ and tag_
for (auto& name : afterOnly) for (auto& name : afterOnly)
{ {
if (name == "depends") if (name == "depends")
@ -384,12 +385,12 @@ void feedback_unblocked (const Task& task)
if (Context::getContext ().verbose ("affected")) if (Context::getContext ().verbose ("affected"))
{ {
// Get a list of tasks that depended on this task. // Get a list of tasks that depended on this task.
auto blocked = dependencyGetBlocked (task); auto blocked = task.getBlockedTasks ();
// Scan all the tasks that were blocked by this task // Scan all the tasks that were blocked by this task
for (auto& i : blocked) for (auto& i : blocked)
{ {
auto blocking = dependencyGetBlocking (i); auto blocking = i.getDependencyTasks ();
if (blocking.size () == 0) if (blocking.size () == 0)
{ {
if (i.id) if (i.id)

View file

@ -59,8 +59,6 @@ std::string colorizeError (const std::string&);
std::string colorizeDebug (const std::string&); std::string colorizeDebug (const std::string&);
// dependency.cpp // dependency.cpp
std::vector <Task> dependencyGetBlocked (const Task&);
std::vector <Task> dependencyGetBlocking (const Task&);
bool dependencyIsCircular (const Task&); bool dependencyIsCircular (const Task&);
void dependencyChainOnComplete (Task&); void dependencyChainOnComplete (Task&);
void dependencyChainOnStart (Task&); void dependencyChainOnStart (Task&);

View file

@ -200,22 +200,25 @@ static bool sort_compare (int left, int right)
// Depends string. // Depends string.
else if (field == "depends") else if (field == "depends")
{ {
// Raw data is a comma-separated list of uuids // Raw data is an un-sorted list of UUIDs. We just need a stable
auto left_string = (*global_data)[left].get_ref (field); // sort, so we sort them lexically.
auto right_string = (*global_data)[right].get_ref (field); auto left_deps = (*global_data)[left].getDependencyUUIDs ();
std::sort(left_deps.begin(), left_deps.end());
auto right_deps = (*global_data)[right].getDependencyUUIDs ();
std::sort(right_deps.begin(), right_deps.end());
if (left_string == right_string) if (left_deps == right_deps)
continue; continue;
if (left_string == "" && right_string != "") if (left_deps.size () == 0 && right_deps.size () > 0)
return ascending; return ascending;
if (left_string != "" && right_string == "") if (left_deps.size () > 0 && right_deps.size () == 0)
return !ascending; return !ascending;
// Sort on the first dependency. // Sort on the first dependency.
left_number = Context::getContext ().tdb2.id (left_string.substr (0, 36)); left_number = Context::getContext ().tdb2.id (left_deps[0].substr (0, 36));
right_number = Context::getContext ().tdb2.id (right_string.substr (0, 36)); right_number = Context::getContext ().tdb2.id (right_deps[0].substr (0, 36));
if (left_number == right_number) if (left_number == right_number)
continue; continue;