Cache Task definition lists for ChangeNodes

ChangeNodes do not benefit from caching their subNode lists even when
they are not going to need to be reloaded because ChangeNodes themselves
aren't cached or reused due to their name change. However if the
subNodes don't need to be reloaded, the subtask lists will be the same
for other ChangeNodes created by the same TasksFactory. In this case,
cache the Task definitions Lists by TasksFactory and reuse them instead
of node lists. ChangeNodes can still benefit from not repeating the
related work that was done to create the definitions: expanding tasks,
fetching definitions, creating definitions from factories...

A walking ancestors use case benefits tremendously from this reuse since
a top level wlaking task, and thus all the ChangeNodes do not need their
subtasks reloaded, and there are over 1K of these subnodes, and
potentially around 100K ChangeNodes when walking ancestors!

The performance difference in the case of a task.config which walks all
dependencies for a change when run with status:open --no-limit
--task--applicable is very significant, around 2.5 times faster:

Before this change: 23m4s, 24m48s, 26m38s, 24m18s, 25m2s
After this change: 9m29s, 9m25s, 9m28s, 9m33s, 11m11s

Change-Id: I2ef200e629627a76936d78a6aec8fe460cd46501
1 file changed