@recaptime-dev's working patches + fork for Phorge, a community fork of Phabricator. (Upstream dev and stable branches are at upstream/main and upstream/stable respectively.) hq.recaptime.dev/wiki/Phorge
phorge phabricator
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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

+34 -2
+1
src/applications/differential/controller/DifferentialRevisionViewController.php
··· 344 344 $stack_graph = id(new DifferentialRevisionGraph()) 345 345 ->setViewer($viewer) 346 346 ->setSeedPHID($revision->getPHID()) 347 + ->setLoadEntireGraph(true) 347 348 ->loadGraph(); 348 349 if (!$stack_graph->isEmpty()) { 349 350 $stack_table = $stack_graph->newGraphTable();
+33 -2
src/infrastructure/graph/PhabricatorObjectGraph.php
··· 5 5 6 6 private $viewer; 7 7 private $edges = array(); 8 + private $edgeReach = array(); 8 9 private $seedPHID; 9 10 private $objects; 11 + private $loadEntireGraph = false; 10 12 11 13 public function setViewer(PhabricatorUser $viewer) { 12 14 $this->viewer = $viewer; ··· 29 31 30 32 final public function setSeedPHID($phid) { 31 33 $this->seedPHID = $phid; 34 + $this->edgeReach[$phid] = array_fill_keys($this->getEdgeTypes(), true); 32 35 33 36 return $this->addNodes( 34 37 array( ··· 41 44 } 42 45 43 46 final public function getEdges($type) { 44 - return idx($this->edges, $type, array()); 47 + $edges = idx($this->edges, $type, array()); 48 + 49 + // Remove any nodes which we never reached. We can get these when loading 50 + // only part of the graph: for example, they point at other subtasks of 51 + // parents or other parents of subtasks. 52 + $nodes = $this->getNodes(); 53 + foreach ($edges as $src => $dsts) { 54 + foreach ($dsts as $key => $dst) { 55 + if (!isset($nodes[$dst])) { 56 + unset($edges[$src][$key]); 57 + } 58 + } 59 + } 60 + 61 + return $edges; 62 + } 63 + 64 + final public function setLoadEntireGraph($load_entire_graph) { 65 + $this->loadEntireGraph = $load_entire_graph; 66 + return $this; 67 + } 68 + 69 + final public function getLoadEntireGraph() { 70 + return $this->loadEntireGraph; 45 71 } 46 72 47 73 final protected function loadEdges(array $nodes) { ··· 52 78 ->withEdgeTypes($edge_types); 53 79 54 80 $query->execute(); 81 + 82 + $whole_graph = $this->getLoadEntireGraph(); 55 83 56 84 $map = array(); 57 85 foreach ($nodes as $node) { ··· 64 92 65 93 $this->edges[$edge_type][$node] = $dst_phids; 66 94 foreach ($dst_phids as $dst_phid) { 67 - $map[$node][] = $dst_phid; 95 + if ($whole_graph || isset($this->edgeReach[$node][$edge_type])) { 96 + $map[$node][] = $dst_phid; 97 + } 98 + $this->edgeReach[$dst_phid][$edge_type] = true; 68 99 } 69 100 } 70 101