Page MenuHomePhabricator

D9939.diff
No OneTemporary

D9939.diff

diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php
--- a/src/__phutil_library_map__.php
+++ b/src/__phutil_library_map__.php
@@ -2550,6 +2550,7 @@
'PhrequentSearchEngine' => 'applications/phrequent/query/PhrequentSearchEngine.php',
'PhrequentTimeBlock' => 'applications/phrequent/storage/PhrequentTimeBlock.php',
'PhrequentTimeBlockTestCase' => 'applications/phrequent/storage/__tests__/PhrequentTimeBlockTestCase.php',
+ 'PhrequentTimeSlices' => 'applications/phrequent/storage/PhrequentTimeSlices.php',
'PhrequentTrackController' => 'applications/phrequent/controller/PhrequentTrackController.php',
'PhrequentTrackableInterface' => 'applications/phrequent/interface/PhrequentTrackableInterface.php',
'PhrequentTrackingEditor' => 'applications/phrequent/editor/PhrequentTrackingEditor.php',
@@ -5521,6 +5522,7 @@
'PhrequentSearchEngine' => 'PhabricatorApplicationSearchEngine',
'PhrequentTimeBlock' => 'Phobject',
'PhrequentTimeBlockTestCase' => 'PhabricatorTestCase',
+ 'PhrequentTimeSlices' => 'Phobject',
'PhrequentTrackController' => 'PhrequentController',
'PhrequentTrackingEditor' => 'PhabricatorEditor',
'PhrequentUIEventListener' => 'PhabricatorEventListener',
diff --git a/src/applications/phrequent/conduit/ConduitAPI_phrequent_tracking_Method.php b/src/applications/phrequent/conduit/ConduitAPI_phrequent_tracking_Method.php
--- a/src/applications/phrequent/conduit/ConduitAPI_phrequent_tracking_Method.php
+++ b/src/applications/phrequent/conduit/ConduitAPI_phrequent_tracking_Method.php
@@ -31,6 +31,7 @@
$times = id(new PhrequentUserTimeQuery())
->setViewer($user)
->needPreemptingEvents(true)
+ ->withEnded(PhrequentUserTimeQuery::ENDED_NO)
->withUserPHIDs(array($user->getPHID()))
->execute();
diff --git a/src/applications/phrequent/query/PhrequentUserTimeQuery.php b/src/applications/phrequent/query/PhrequentUserTimeQuery.php
--- a/src/applications/phrequent/query/PhrequentUserTimeQuery.php
+++ b/src/applications/phrequent/query/PhrequentUserTimeQuery.php
@@ -199,7 +199,7 @@
$u_start = $u_event->getDateStarted();
$u_end = $u_event->getDateEnded();
- if (($u_start >= $e_start) && ($u_end <= $e_end) &&
+ if (($u_start >= $e_start) &&
($u_end === null || $u_end > $e_start)) {
$select[] = $u_event;
}
diff --git a/src/applications/phrequent/storage/PhrequentTimeBlock.php b/src/applications/phrequent/storage/PhrequentTimeBlock.php
--- a/src/applications/phrequent/storage/PhrequentTimeBlock.php
+++ b/src/applications/phrequent/storage/PhrequentTimeBlock.php
@@ -10,17 +10,16 @@
}
public function getTimeSpentOnObject($phid, $now) {
- $ranges = idx($this->getObjectTimeRanges($now), $phid, array());
+ $slices = idx($this->getObjectTimeRanges(), $phid);
- $sum = 0;
- foreach ($ranges as $range) {
- $sum += ($range[1] - $range[0]);
+ if (!$slices) {
+ return null;
}
- return $sum;
+ return $slices->getDuration($now);
}
- public function getObjectTimeRanges($now) {
+ public function getObjectTimeRanges() {
$ranges = array();
$range_start = time();
@@ -29,6 +28,7 @@
}
$object_ranges = array();
+ $object_ongoing = array();
foreach ($this->events as $event) {
// First, convert each event's preempting stack into a linear timeline
@@ -42,14 +42,16 @@
);
$timeline[] = array(
'event' => $event,
- 'at' => (int)nonempty($event->getDateEnded(), $now),
+ 'at' => (int)nonempty($event->getDateEnded(), PHP_INT_MAX),
'type' => 'end',
);
$base_phid = $event->getObjectPHID();
+ if (!$event->getDateEnded()) {
+ $object_ongoing[$base_phid] = true;
+ }
$preempts = $event->getPreemptingEvents();
-
foreach ($preempts as $preempt) {
$same_object = ($preempt->getObjectPHID() == $base_phid);
$timeline[] = array(
@@ -59,7 +61,7 @@
);
$timeline[] = array(
'event' => $preempt,
- 'at' => (int)nonempty($preempt->getDateEnded(), $now),
+ 'at' => (int)nonempty($preempt->getDateEnded(), PHP_INT_MAX),
'type' => $same_object ? 'end' : 'pop',
);
}
@@ -89,7 +91,6 @@
$stratum = null;
$strata = array();
-
$ranges = array();
foreach ($timeline as $timeline_event) {
$id = $timeline_event['event']->getID();
@@ -173,15 +174,39 @@
}
}
+ // Filter out ranges with an indefinite start time. These occur when
+ // popping the stack when there are multiple ongoing events.
+ foreach ($ranges as $key => $range) {
+ if ($range[0] == PHP_INT_MAX) {
+ unset($ranges[$key]);
+ }
+ }
+
$object_ranges[$base_phid][] = $ranges;
}
- // Finally, collapse all the ranges so we don't double-count time.
-
+ // Collapse all the ranges so we don't double-count time.
foreach ($object_ranges as $phid => $ranges) {
$object_ranges[$phid] = self::mergeTimeRanges(array_mergev($ranges));
}
+ foreach ($object_ranges as $phid => $ranges) {
+ foreach ($ranges as $key => $range) {
+ if ($range[1] == PHP_INT_MAX) {
+ $ranges[$key][1] = null;
+ }
+ }
+
+ $object_ranges[$phid] = new PhrequentTimeSlices(
+ $phid,
+ isset($object_ongoing[$phid]),
+ $ranges);
+ }
+
+ // Reorder the ranges to be more stack-like, so the first item is the
+ // top of the stack.
+ $object_ranges = array_reverse($object_ranges, $preserve_keys = true);
+
return $object_ranges;
}
@@ -189,33 +214,22 @@
* Returns the current list of work.
*/
public function getCurrentWorkStack($now, $include_inactive = false) {
- $ranges = $this->getObjectTimeRanges($now);
+ $ranges = $this->getObjectTimeRanges();
$results = array();
- foreach ($ranges as $phid => $blocks) {
- $total = 0;
- foreach ($blocks as $block) {
- $total += $block[1] - $block[0];
- }
-
- $type = 'inactive';
- foreach ($blocks as $block) {
- if ($block[1] === $now) {
- if ($block[0] === $block[1]) {
- $type = 'suspended';
- } else {
- $type = 'active';
- }
- break;
+ $active = null;
+ foreach ($ranges as $phid => $slices) {
+ if (!$include_inactive) {
+ if (!$slices->getIsOngoing()) {
+ continue;
}
}
- if ($include_inactive || $type !== 'inactive') {
- $results[] = array(
- 'phid' => $phid,
- 'time' => $total,
- 'type' => $type);
- }
+ $results[] = array(
+ 'phid' => $phid,
+ 'time' => $slices->getDuration($now),
+ 'ongoing' => $slices->getIsOngoing(),
+ );
}
return $results;
diff --git a/src/applications/phrequent/storage/PhrequentTimeSlices.php b/src/applications/phrequent/storage/PhrequentTimeSlices.php
new file mode 100644
--- /dev/null
+++ b/src/applications/phrequent/storage/PhrequentTimeSlices.php
@@ -0,0 +1,37 @@
+<?php
+
+final class PhrequentTimeSlices extends Phobject {
+
+ private $objectPHID;
+ private $isOngoing;
+ private $ranges;
+
+ public function __construct($object_phid, $is_ongoing, array $ranges) {
+ $this->objectPHID = $object_phid;
+ $this->isOngoing = $is_ongoing;
+ $this->ranges = $ranges;
+ }
+
+ public function getObjectPHID() {
+ return $this->objectPHID;
+ }
+
+ public function getDuration($now) {
+ foreach ($this->ranges as $range) {
+ if ($range[1] === null) {
+ return $now - $range[0];
+ } else {
+ return $range[1] - $range[0];
+ }
+ }
+ }
+
+ public function getIsOngoing() {
+ return $this->isOngoing;
+ }
+
+ public function getRanges() {
+ return $this->ranges;
+ }
+
+}
diff --git a/src/applications/phrequent/storage/__tests__/PhrequentTimeBlockTestCase.php b/src/applications/phrequent/storage/__tests__/PhrequentTimeBlockTestCase.php
--- a/src/applications/phrequent/storage/__tests__/PhrequentTimeBlockTestCase.php
+++ b/src/applications/phrequent/storage/__tests__/PhrequentTimeBlockTestCase.php
@@ -86,7 +86,9 @@
$block = new PhrequentTimeBlock(array($event));
- $ranges = $block->getObjectTimeRanges(1800);
+ $ranges = $block->getObjectTimeRanges();
+ $ranges = $this->reduceRanges($ranges);
+
$this->assertEqual(
array(
'T1' => array(
@@ -107,7 +109,9 @@
$block = new PhrequentTimeBlock(array($event));
- $ranges = $block->getObjectTimeRanges(1000);
+ $ranges = $block->getObjectTimeRanges();
+ $ranges = $this->reduceRanges($ranges);
+
$this->assertEqual(
array(
'T2' => array(
@@ -150,7 +154,9 @@
$block = new PhrequentTimeBlock(array($event));
- $ranges = $block->getObjectTimeRanges(1800);
+ $ranges = $block->getObjectTimeRanges();
+ $ranges = $this->reduceRanges($ranges);
+
$this->assertEqual(
array(
'T1' => array(
@@ -172,7 +178,8 @@
$block = new PhrequentTimeBlock(array($event));
- $ranges = $block->getObjectTimeRanges(1000);
+ $ranges = $block->getObjectTimeRanges();
+ $ranges = $this->reduceRanges($ranges);
$this->assertEqual(
array(
@@ -198,7 +205,8 @@
$block = new PhrequentTimeBlock(array($event));
- $ranges = $block->getObjectTimeRanges(1000);
+ $ranges = $block->getObjectTimeRanges();
+ $ranges = $this->reduceRanges($ranges);
$this->assertEqual(
array(
@@ -213,6 +221,67 @@
$ranges);
}
+ public function testOngoing() {
+ $event = $this->newEvent('T1', 1, null);
+ $event->attachPreemptingEvents(array());
+
+ $block = new PhrequentTimeBlock(array($event));
+
+ $ranges = $block->getObjectTimeRanges();
+ $ranges = $this->reduceRanges($ranges);
+
+ $this->assertEqual(
+ array(
+ 'T1' => array(
+ array(1, null),
+ ),
+ ),
+ $ranges);
+ }
+
+ public function testOngoingInterrupted() {
+ $event = $this->newEvent('T1', 1, null);
+ $event->attachPreemptingEvents(
+ array(
+ $this->newEvent('T2', 100, 900),
+ ));
+
+ $block = new PhrequentTimeBlock(array($event));
+
+ $ranges = $block->getObjectTimeRanges();
+ $ranges = $this->reduceRanges($ranges);
+
+ $this->assertEqual(
+ array(
+ 'T1' => array(
+ array(1, 100),
+ array(900, null)
+ ),
+ ),
+ $ranges);
+ }
+
+ public function testOngoingPreempted() {
+ $event = $this->newEvent('T1', 1, null);
+ $event->attachPreemptingEvents(
+ array(
+ $this->newEvent('T2', 100, null),
+ ));
+
+ $block = new PhrequentTimeBlock(array($event));
+
+ $ranges = $block->getObjectTimeRanges();
+ $ranges = $this->reduceRanges($ranges);
+
+ $this->assertEqual(
+ array(
+ 'T1' => array(
+ array(1, 100),
+ ),
+ ),
+ $ranges);
+ }
+
private function newEvent($object_phid, $start_time, $end_time) {
static $id = 0;
@@ -223,4 +292,14 @@
->setDateEnded($end_time);
}
+ private function reduceRanges(array $ranges) {
+ $results = array();
+
+ foreach ($ranges as $phid => $slices) {
+ $results[$phid] = $slices->getRanges();
+ }
+
+ return $results;
+ }
+
}

File Metadata

Mime Type
text/plain
Expires
May 9 2024, 7:41 PM (5 w, 2 d ago)
Storage Engine
blob
Storage Format
Encrypted (AES-256-CBC)
Storage Handle
6274446
Default Alt Text
D9939.diff (11 KB)

Event Timeline