1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2024-11-10 00:42:41 +01:00

Show responsiveness' in differential stats

Summary: For "accept" and "reject" action, find the time between the action and last time the revision was updated by a new diff. Show it as the responsiveness row.

Test Plan: view it for a couple of engineers.

Reviewers: epriestley, vii

Reviewed By: epriestley

CC: vrana, nh, aran, Korvin

Differential Revision: https://secure.phabricator.com/D2970
This commit is contained in:
Jason Ge 2012-07-03 18:24:58 -07:00
parent f5754ddadc
commit e0d4793e74
2 changed files with 107 additions and 12 deletions

View file

@ -67,6 +67,20 @@ final class DifferentialRevisionStatsController extends DifferentialController {
return $table->loadAllFromArray($rows);
}
private function loadDiffs(array $revisions) {
if (!$revisions) {
return array();
}
$diff_teml = new DifferentialDiff();
$diffs = $diff_teml->loadAllWhere(
'revisionID in (%Ld)',
array_keys($revisions)
);
return $diffs;
}
public function willProcessRequest(array $data) {
$this->filter = idx($data, 'filter');
}
@ -127,13 +141,16 @@ final class DifferentialRevisionStatsController extends DifferentialController {
$comments = $this->loadComments($params['phid']);
$revisions = $this->loadRevisions($params['phid']);
$diffs = $this->loadDiffs($revisions);
$panel = new AphrontPanelView();
$panel->setHeader('Differential rate analysis');
$panel->appendChild(
id(new DifferentialRevisionStatsView())
->setComments($comments)
->setFilter($this->filter)
->setRevisions($revisions)
->setDiffs($diffs)
->setUser($user));
$panels[] = $panel;

View file

@ -22,7 +22,9 @@
final class DifferentialRevisionStatsView extends AphrontView {
private $comments;
private $revisions;
private $diffs;
private $user;
private $filter;
public function setRevisions(array $revisions) {
assert_instances_of($revisions, 'DifferentialRevision');
@ -36,6 +38,17 @@ final class DifferentialRevisionStatsView extends AphrontView {
return $this;
}
public function setDiffs(array $diffs) {
assert_instances_of($diffs, 'DifferentialDiff');
$this->diffs = $diffs;
return $this;
}
public function setFilter($filter) {
$this->filter = $filter;
return $this;
}
public function setUser($user) {
$this->user = $user;
return $this;
@ -56,9 +69,10 @@ final class DifferentialRevisionStatsView extends AphrontView {
$dates = array();
$counts = array();
$lines = array();
$boosts = array();
$days_with_diffs = array();
$count_active = array();
$response_time = array();
$response_count = array();
$now = time();
$row_array = array();
@ -72,33 +86,52 @@ final class DifferentialRevisionStatsView extends AphrontView {
$counts[$age] = 0;
$lines[$age] = 0;
$count_active[$age] = 0;
$response_time[$age] = array();
}
$revision_diffs_map = mgroup($this->diffs, 'getRevisionID');
foreach ($revision_diffs_map as $revision_id => $diffs) {
$revision_diffs_map[$revision_id] = msort($diffs, 'getID');
}
foreach ($this->comments as $comment) {
$rev_date = $comment->getDateCreated();
$comment_date = $comment->getDateCreated();
$day = phabricator_date($rev_date, $user);
$day = phabricator_date($comment_date, $user);
$old_daycount = idx($days_with_diffs, $day, 0);
$days_with_diffs[$day] = $old_daycount + 1;
$rev_id = $comment->getRevisionID();
if (idx($revisions_seen, $rev_id)) {
continue;
$revision_seen = true;
$rev = null;
} else {
$revision_seen = false;
$rev = $id_to_revision_map[$rev_id];
$revisions_seen[$rev_id] = true;
}
$rev = $id_to_revision_map[$rev_id];
$revisions_seen[$rev_id] = true;
foreach ($dates as $age => $cutoff) {
if ($cutoff >= $rev_date) {
if ($cutoff >= $comment_date) {
continue;
}
if ($rev) {
$lines[$age] += $rev->getLineCount();
if (!$revision_seen) {
if ($rev) {
$lines[$age] += $rev->getLineCount();
}
$counts[$age]++;
if (!$old_daycount) {
$count_active[$age]++;
}
}
$counts[$age]++;
if (!$old_daycount) {
$count_active[$age]++;
$diffs = $revision_diffs_map[$rev_id];
$target_diff = $this->findTargetDiff($diffs, $comment);
if ($target_diff) {
$response_time[$age][] =
$comment_date - $target_diff->getDateCreated();
}
}
}
@ -123,6 +156,30 @@ final class DifferentialRevisionStatsView extends AphrontView {
($counts[$age] + 0.0001)),
'Active days' => number_format($count_active[$age]),
);
switch ($this->filter) {
case DifferentialAction::ACTION_CLOSE:
case DifferentialAction::ACTION_UPDATE:
case DifferentialAction::ACTION_COMMENT:
break;
case DifferentialAction::ACTION_ACCEPT:
case DifferentialAction::ACTION_REJECT:
$count = count($response_time[$age]);
if ($count) {
rsort($response_time[$age]);
$median = $response_time[$age][round($count / 2) - 1];
$average = array_sum($response_time[$age]) / $count;
} else {
$median = 0;
$average = 0;
}
$row_array[$age]['Response hours (median|average)'] =
number_format($median / 3600, 1).
' | '.
number_format($average / 3600, 1);
break;
}
}
$rows = array();
@ -153,4 +210,25 @@ final class DifferentialRevisionStatsView extends AphrontView {
return $table->render();
}
private function findTargetDiff(array $diffs,
DifferentialComment $comment) {
switch ($this->filter) {
case DifferentialAction::ACTION_CLOSE:
case DifferentialAction::ACTION_UPDATE:
case DifferentialAction::ACTION_COMMENT:
return null;
case DifferentialAction::ACTION_ACCEPT:
case DifferentialAction::ACTION_REJECT:
$result = head($diffs);
foreach ($diffs as $diff) {
if ($diff->getDateCreated() >= $comment->getDateCreated()) {
break;
}
$result = $diff;
}
return $result;
}
}
}