1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2025-03-07 18:09:27 +01:00

Don't load the entire graph for tasks

Summary:
Ref T4788. As it turns out, our tasks are very tightly connected.

Instead of loading every parent/child task, then every parent/child of those tasks, etc., etc., only load tasks in the "same direction" that we're already heading.

For example, we load children of children, but not parents of children. And we load parents of parents, but not children of parents.

Basically we only go "up" and "down" now, but not "out" as much. This should reduce the gigantic multiple-thousand-node graphs currently shown in the UI.

I still discover the whole graph for revisiosn, because I think it's probably more useful and always much smaller. That might need adjustment too, though.

Test Plan: Seems fine locally??

Reviewers: chad

Reviewed By: chad

Maniphest Tasks: T4788

Differential Revision: https://secure.phabricator.com/D16218
This commit is contained in:
epriestley 2016-07-01 11:37:01 -07:00
parent f26374241a
commit bc3ac31584
2 changed files with 34 additions and 2 deletions

View file

@ -344,6 +344,7 @@ final class DifferentialRevisionViewController extends DifferentialController {
$stack_graph = id(new DifferentialRevisionGraph())
->setViewer($viewer)
->setSeedPHID($revision->getPHID())
->setLoadEntireGraph(true)
->loadGraph();
if (!$stack_graph->isEmpty()) {
$stack_table = $stack_graph->newGraphTable();

View file

@ -5,8 +5,10 @@ abstract class PhabricatorObjectGraph
private $viewer;
private $edges = array();
private $edgeReach = array();
private $seedPHID;
private $objects;
private $loadEntireGraph = false;
public function setViewer(PhabricatorUser $viewer) {
$this->viewer = $viewer;
@ -29,6 +31,7 @@ abstract class PhabricatorObjectGraph
final public function setSeedPHID($phid) {
$this->seedPHID = $phid;
$this->edgeReach[$phid] = array_fill_keys($this->getEdgeTypes(), true);
return $this->addNodes(
array(
@ -41,7 +44,30 @@ abstract class PhabricatorObjectGraph
}
final public function getEdges($type) {
return idx($this->edges, $type, array());
$edges = idx($this->edges, $type, array());
// Remove any nodes which we never reached. We can get these when loading
// only part of the graph: for example, they point at other subtasks of
// parents or other parents of subtasks.
$nodes = $this->getNodes();
foreach ($edges as $src => $dsts) {
foreach ($dsts as $key => $dst) {
if (!isset($nodes[$dst])) {
unset($edges[$src][$key]);
}
}
}
return $edges;
}
final public function setLoadEntireGraph($load_entire_graph) {
$this->loadEntireGraph = $load_entire_graph;
return $this;
}
final public function getLoadEntireGraph() {
return $this->loadEntireGraph;
}
final protected function loadEdges(array $nodes) {
@ -53,6 +79,8 @@ abstract class PhabricatorObjectGraph
$query->execute();
$whole_graph = $this->getLoadEntireGraph();
$map = array();
foreach ($nodes as $node) {
$map[$node] = array();
@ -64,7 +92,10 @@ abstract class PhabricatorObjectGraph
$this->edges[$edge_type][$node] = $dst_phids;
foreach ($dst_phids as $dst_phid) {
$map[$node][] = $dst_phid;
if ($whole_graph || isset($this->edgeReach[$node][$edge_type])) {
$map[$node][] = $dst_phid;
}
$this->edgeReach[$dst_phid][$edge_type] = true;
}
}