mirror of
https://github.com/danog/amp.git
synced 2024-12-12 09:29:45 +01:00
Merge branch 'master' into v3
# Conflicts: # lib/Loop/Internal/TimerQueue.php # lib/Loop/Internal/TimerQueueEntry.php
This commit is contained in:
commit
31adf876b6
@ -9,7 +9,7 @@ use Amp\Loop\Watcher;
|
|||||||
*/
|
*/
|
||||||
final class TimerQueue
|
final class TimerQueue
|
||||||
{
|
{
|
||||||
/** @var TimerQueueEntry[] */
|
/** @var Watcher[] */
|
||||||
private array $data = [];
|
private array $data = [];
|
||||||
|
|
||||||
/** @var int[] */
|
/** @var int[] */
|
||||||
@ -24,13 +24,7 @@ final class TimerQueue
|
|||||||
{
|
{
|
||||||
$entry = $this->data[$node];
|
$entry = $this->data[$node];
|
||||||
while ($node !== 0 && $entry->expiration < $this->data[$parent = ($node - 1) >> 1]->expiration) {
|
while ($node !== 0 && $entry->expiration < $this->data[$parent = ($node - 1) >> 1]->expiration) {
|
||||||
$temp = $this->data[$parent];
|
$this->swap($node, $parent);
|
||||||
$this->data[$node] = $temp;
|
|
||||||
$this->pointers[$temp->watcher->id] = $node;
|
|
||||||
|
|
||||||
$this->data[$parent] = $entry;
|
|
||||||
$this->pointers[$entry->watcher->id] = $parent;
|
|
||||||
|
|
||||||
$node = $parent;
|
$node = $parent;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -56,19 +50,22 @@ final class TimerQueue
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
$left = $this->data[$node];
|
$this->swap($node, $swap);
|
||||||
$right = $this->data[$swap];
|
|
||||||
|
|
||||||
$this->data[$node] = $right;
|
|
||||||
$this->pointers[$right->watcher->id] = $node;
|
|
||||||
|
|
||||||
$this->data[$swap] = $left;
|
|
||||||
$this->pointers[$left->watcher->id] = $swap;
|
|
||||||
|
|
||||||
$node = $swap;
|
$node = $swap;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private function swap(int $left, int $right): void
|
||||||
|
{
|
||||||
|
$temp = $this->data[$left];
|
||||||
|
|
||||||
|
$this->data[$left] = $this->data[$right];
|
||||||
|
$this->pointers[$this->data[$right]->id] = $left;
|
||||||
|
|
||||||
|
$this->data[$right] = $temp;
|
||||||
|
$this->pointers[$temp->id] = $right;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Inserts the watcher into the queue. Time complexity: O(log(n)).
|
* Inserts the watcher into the queue. Time complexity: O(log(n)).
|
||||||
*
|
*
|
||||||
@ -83,10 +80,8 @@ final class TimerQueue
|
|||||||
\assert($watcher->expiration !== null);
|
\assert($watcher->expiration !== null);
|
||||||
\assert(!isset($this->pointers[$watcher->id]));
|
\assert(!isset($this->pointers[$watcher->id]));
|
||||||
|
|
||||||
$entry = new TimerQueueEntry($watcher, $watcher->expiration);
|
|
||||||
|
|
||||||
$node = \count($this->data);
|
$node = \count($this->data);
|
||||||
$this->data[$node] = $entry;
|
$this->data[$node] = $watcher;
|
||||||
$this->pointers[$watcher->id] = $node;
|
$this->pointers[$watcher->id] = $node;
|
||||||
|
|
||||||
$this->heapifyUp($node);
|
$this->heapifyUp($node);
|
||||||
@ -128,15 +123,15 @@ final class TimerQueue
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
$data = $this->data[0];
|
$watcher = $this->data[0];
|
||||||
|
|
||||||
if ($data->expiration > $now) {
|
if ($watcher->expiration > $now) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->removeAndRebuild(0);
|
$this->removeAndRebuild(0);
|
||||||
|
|
||||||
return $data->watcher;
|
return $watcher;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -157,9 +152,9 @@ final class TimerQueue
|
|||||||
private function removeAndRebuild(int $node): void
|
private function removeAndRebuild(int $node): void
|
||||||
{
|
{
|
||||||
$length = \count($this->data) - 1;
|
$length = \count($this->data) - 1;
|
||||||
$id = $this->data[$node]->watcher->id;
|
$id = $this->data[$node]->id;
|
||||||
$left = $this->data[$node] = $this->data[$length];
|
$left = $this->data[$node] = $this->data[$length];
|
||||||
$this->pointers[$left->watcher->id] = $node;
|
$this->pointers[$left->id] = $node;
|
||||||
unset($this->data[$length], $this->pointers[$id]);
|
unset($this->data[$length], $this->pointers[$id]);
|
||||||
|
|
||||||
if ($node < $length) { // don't need to do anything if we removed the last element
|
if ($node < $length) { // don't need to do anything if we removed the last element
|
||||||
|
@ -1,28 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace Amp\Loop\Internal;
|
|
||||||
|
|
||||||
use Amp\Loop\Watcher;
|
|
||||||
use Amp\Struct;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @internal
|
|
||||||
*/
|
|
||||||
final class TimerQueueEntry
|
|
||||||
{
|
|
||||||
use Struct;
|
|
||||||
|
|
||||||
public Watcher $watcher;
|
|
||||||
|
|
||||||
public int $expiration;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param Watcher $watcher
|
|
||||||
* @param int $expiration
|
|
||||||
*/
|
|
||||||
public function __construct(Watcher $watcher, int $expiration)
|
|
||||||
{
|
|
||||||
$this->watcher = $watcher;
|
|
||||||
$this->expiration = $expiration;
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
Reference in New Issue
Block a user