ok
Direktori : /home2/selectio/www/mm-tailor-billing/vendor/zendframework/zend-stdlib/src/ |
Current File : /home2/selectio/www/mm-tailor-billing/vendor/zendframework/zend-stdlib/src/PriorityQueue.php |
<?php /** * Zend Framework (http://framework.zend.com/) * * @link http://github.com/zendframework/zf2 for the canonical source repository * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) * @license http://framework.zend.com/license/new-bsd New BSD License */ namespace Zend\Stdlib; use Countable; use IteratorAggregate; use Serializable; /** * Re-usable, serializable priority queue implementation * * SplPriorityQueue acts as a heap; on iteration, each item is removed from the * queue. If you wish to re-use such a queue, you need to clone it first. This * makes for some interesting issues if you wish to delete items from the queue, * or, as already stated, iterate over it multiple times. * * This class aggregates items for the queue itself, but also composes an * "inner" iterator in the form of an SplPriorityQueue object for performing * the actual iteration. */ class PriorityQueue implements Countable, IteratorAggregate, Serializable { const EXTR_DATA = 0x00000001; const EXTR_PRIORITY = 0x00000002; const EXTR_BOTH = 0x00000003; /** * Inner queue class to use for iteration * @var string */ protected $queueClass = 'Zend\Stdlib\SplPriorityQueue'; /** * Actual items aggregated in the priority queue. Each item is an array * with keys "data" and "priority". * @var array */ protected $items = []; /** * Inner queue object * @var SplPriorityQueue */ protected $queue; /** * Insert an item into the queue * * Priority defaults to 1 (low priority) if none provided. * * @param mixed $data * @param int $priority * @return PriorityQueue */ public function insert($data, $priority = 1) { $priority = (int) $priority; $this->items[] = [ 'data' => $data, 'priority' => $priority, ]; $this->getQueue()->insert($data, $priority); return $this; } /** * Remove an item from the queue * * This is different than {@link extract()}; its purpose is to dequeue an * item. * * This operation is potentially expensive, as it requires * re-initialization and re-population of the inner queue. * * Note: this removes the first item matching the provided item found. If * the same item has been added multiple times, it will not remove other * instances. * * @param mixed $datum * @return bool False if the item was not found, true otherwise. */ public function remove($datum) { $found = false; foreach ($this->items as $key => $item) { if ($item['data'] === $datum) { $found = true; break; } } if ($found) { unset($this->items[$key]); $this->queue = null; if (! $this->isEmpty()) { $queue = $this->getQueue(); foreach ($this->items as $item) { $queue->insert($item['data'], $item['priority']); } } return true; } return false; } /** * Is the queue empty? * * @return bool */ public function isEmpty() { return (0 === $this->count()); } /** * How many items are in the queue? * * @return int */ public function count() { return count($this->items); } /** * Peek at the top node in the queue, based on priority. * * @return mixed */ public function top() { return $this->getIterator()->top(); } /** * Extract a node from the inner queue and sift up * * @return mixed */ public function extract() { return $this->getQueue()->extract(); } /** * Retrieve the inner iterator * * SplPriorityQueue acts as a heap, which typically implies that as items * are iterated, they are also removed. This does not work for situations * where the queue may be iterated multiple times. As such, this class * aggregates the values, and also injects an SplPriorityQueue. This method * retrieves the inner queue object, and clones it for purposes of * iteration. * * @return SplPriorityQueue */ public function getIterator() { $queue = $this->getQueue(); return clone $queue; } /** * Serialize the data structure * * @return string */ public function serialize() { return serialize($this->items); } /** * Unserialize a string into a PriorityQueue object * * Serialization format is compatible with {@link Zend\Stdlib\SplPriorityQueue} * * @param string $data * @return void */ public function unserialize($data) { foreach (unserialize($data) as $item) { $this->insert($item['data'], $item['priority']); } } /** * Serialize to an array * * By default, returns only the item data, and in the order registered (not * sorted). You may provide one of the EXTR_* flags as an argument, allowing * the ability to return priorities or both data and priority. * * @param int $flag * @return array */ public function toArray($flag = self::EXTR_DATA) { switch ($flag) { case self::EXTR_BOTH: return $this->items; case self::EXTR_PRIORITY: return array_map(function ($item) { return $item['priority']; }, $this->items); case self::EXTR_DATA: default: return array_map(function ($item) { return $item['data']; }, $this->items); } } /** * Specify the internal queue class * * Please see {@link getIterator()} for details on the necessity of an * internal queue class. The class provided should extend SplPriorityQueue. * * @param string $class * @return PriorityQueue */ public function setInternalQueueClass($class) { $this->queueClass = (string) $class; return $this; } /** * Does the queue contain the given datum? * * @param mixed $datum * @return bool */ public function contains($datum) { foreach ($this->items as $item) { if ($item['data'] === $datum) { return true; } } return false; } /** * Does the queue have an item with the given priority? * * @param int $priority * @return bool */ public function hasPriority($priority) { foreach ($this->items as $item) { if ($item['priority'] === $priority) { return true; } } return false; } /** * Get the inner priority queue instance * * @throws Exception\DomainException * @return SplPriorityQueue */ protected function getQueue() { if (null === $this->queue) { $this->queue = new $this->queueClass(); if (! $this->queue instanceof \SplPriorityQueue) { throw new Exception\DomainException(sprintf( 'PriorityQueue expects an internal queue of type SplPriorityQueue; received "%s"', get_class($this->queue) )); } } return $this->queue; } /** * Add support for deep cloning * * @return void */ public function __clone() { if (null !== $this->queue) { $this->queue = clone $this->queue; } } }