[ Index ]

PHP Cross Reference of phpBB-3.2.11-deutsch

title

Body

[close]

/vendor/zendframework/zend-stdlib/src/ -> PriorityQueue.php (source)

   1  <?php
   2  /**
   3   * Zend Framework (http://framework.zend.com/)
   4   *
   5   * @link      http://github.com/zendframework/zf2 for the canonical source repository
   6   * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
   7   * @license   http://framework.zend.com/license/new-bsd New BSD License
   8   */
   9  
  10  namespace Zend\Stdlib;
  11  
  12  use Countable;
  13  use IteratorAggregate;
  14  use Serializable;
  15  
  16  /**
  17   * Re-usable, serializable priority queue implementation
  18   *
  19   * SplPriorityQueue acts as a heap; on iteration, each item is removed from the
  20   * queue. If you wish to re-use such a queue, you need to clone it first. This
  21   * makes for some interesting issues if you wish to delete items from the queue,
  22   * or, as already stated, iterate over it multiple times.
  23   *
  24   * This class aggregates items for the queue itself, but also composes an
  25   * "inner" iterator in the form of an SplPriorityQueue object for performing
  26   * the actual iteration.
  27   */
  28  class PriorityQueue implements Countable, IteratorAggregate, Serializable
  29  {
  30      const EXTR_DATA     = 0x00000001;
  31      const EXTR_PRIORITY = 0x00000002;
  32      const EXTR_BOTH     = 0x00000003;
  33  
  34      /**
  35       * Inner queue class to use for iteration
  36       * @var string
  37       */
  38      protected $queueClass = 'Zend\Stdlib\SplPriorityQueue';
  39  
  40      /**
  41       * Actual items aggregated in the priority queue. Each item is an array
  42       * with keys "data" and "priority".
  43       * @var array
  44       */
  45      protected $items      = array();
  46  
  47      /**
  48       * Inner queue object
  49       * @var SplPriorityQueue
  50       */
  51      protected $queue;
  52  
  53      /**
  54       * Insert an item into the queue
  55       *
  56       * Priority defaults to 1 (low priority) if none provided.
  57       *
  58       * @param  mixed $data
  59       * @param  int $priority
  60       * @return PriorityQueue
  61       */
  62      public function insert($data, $priority = 1)
  63      {
  64          $priority = (int) $priority;
  65          $this->items[] = array(
  66              'data'     => $data,
  67              'priority' => $priority,
  68          );
  69          $this->getQueue()->insert($data, $priority);
  70          return $this;
  71      }
  72  
  73      /**
  74       * Remove an item from the queue
  75       *
  76       * This is different than {@link extract()}; its purpose is to dequeue an
  77       * item.
  78       *
  79       * This operation is potentially expensive, as it requires
  80       * re-initialization and re-population of the inner queue.
  81       *
  82       * Note: this removes the first item matching the provided item found. If
  83       * the same item has been added multiple times, it will not remove other
  84       * instances.
  85       *
  86       * @param  mixed $datum
  87       * @return bool False if the item was not found, true otherwise.
  88       */
  89      public function remove($datum)
  90      {
  91          $found = false;
  92          foreach ($this->items as $key => $item) {
  93              if ($item['data'] === $datum) {
  94                  $found = true;
  95                  break;
  96              }
  97          }
  98          if ($found) {
  99              unset($this->items[$key]);
 100              $this->queue = null;
 101  
 102              if (!$this->isEmpty()) {
 103                  $queue = $this->getQueue();
 104                  foreach ($this->items as $item) {
 105                      $queue->insert($item['data'], $item['priority']);
 106                  }
 107              }
 108              return true;
 109          }
 110          return false;
 111      }
 112  
 113      /**
 114       * Is the queue empty?
 115       *
 116       * @return bool
 117       */
 118      public function isEmpty()
 119      {
 120          return (0 === $this->count());
 121      }
 122  
 123      /**
 124       * How many items are in the queue?
 125       *
 126       * @return int
 127       */
 128      public function count()
 129      {
 130          return count($this->items);
 131      }
 132  
 133      /**
 134       * Peek at the top node in the queue, based on priority.
 135       *
 136       * @return mixed
 137       */
 138      public function top()
 139      {
 140          return $this->getIterator()->top();
 141      }
 142  
 143      /**
 144       * Extract a node from the inner queue and sift up
 145       *
 146       * @return mixed
 147       */
 148      public function extract()
 149      {
 150          return $this->getQueue()->extract();
 151      }
 152  
 153      /**
 154       * Retrieve the inner iterator
 155       *
 156       * SplPriorityQueue acts as a heap, which typically implies that as items
 157       * are iterated, they are also removed. This does not work for situations
 158       * where the queue may be iterated multiple times. As such, this class
 159       * aggregates the values, and also injects an SplPriorityQueue. This method
 160       * retrieves the inner queue object, and clones it for purposes of
 161       * iteration.
 162       *
 163       * @return SplPriorityQueue
 164       */
 165      public function getIterator()
 166      {
 167          $queue = $this->getQueue();
 168          return clone $queue;
 169      }
 170  
 171      /**
 172       * Serialize the data structure
 173       *
 174       * @return string
 175       */
 176      public function serialize()
 177      {
 178          return serialize($this->items);
 179      }
 180  
 181      /**
 182       * Unserialize a string into a PriorityQueue object
 183       *
 184       * Serialization format is compatible with {@link Zend\Stdlib\SplPriorityQueue}
 185       *
 186       * @param  string $data
 187       * @return void
 188       */
 189      public function unserialize($data)
 190      {
 191          foreach (unserialize($data) as $item) {
 192              $this->insert($item['data'], $item['priority']);
 193          }
 194      }
 195  
 196      /**
 197       * Serialize to an array
 198       *
 199       * By default, returns only the item data, and in the order registered (not
 200       * sorted). You may provide one of the EXTR_* flags as an argument, allowing
 201       * the ability to return priorities or both data and priority.
 202       *
 203       * @param  int $flag
 204       * @return array
 205       */
 206      public function toArray($flag = self::EXTR_DATA)
 207      {
 208          switch ($flag) {
 209              case self::EXTR_BOTH:
 210                  return $this->items;
 211              case self::EXTR_PRIORITY:
 212                  return array_map(function ($item) {
 213                      return $item['priority'];
 214                  }, $this->items);
 215              case self::EXTR_DATA:
 216              default:
 217                  return array_map(function ($item) {
 218                      return $item['data'];
 219                  }, $this->items);
 220          }
 221      }
 222  
 223      /**
 224       * Specify the internal queue class
 225       *
 226       * Please see {@link getIterator()} for details on the necessity of an
 227       * internal queue class. The class provided should extend SplPriorityQueue.
 228       *
 229       * @param  string $class
 230       * @return PriorityQueue
 231       */
 232      public function setInternalQueueClass($class)
 233      {
 234          $this->queueClass = (string) $class;
 235          return $this;
 236      }
 237  
 238      /**
 239       * Does the queue contain the given datum?
 240       *
 241       * @param  mixed $datum
 242       * @return bool
 243       */
 244      public function contains($datum)
 245      {
 246          foreach ($this->items as $item) {
 247              if ($item['data'] === $datum) {
 248                  return true;
 249              }
 250          }
 251          return false;
 252      }
 253  
 254      /**
 255       * Does the queue have an item with the given priority?
 256       *
 257       * @param  int $priority
 258       * @return bool
 259       */
 260      public function hasPriority($priority)
 261      {
 262          foreach ($this->items as $item) {
 263              if ($item['priority'] === $priority) {
 264                  return true;
 265              }
 266          }
 267          return false;
 268      }
 269  
 270      /**
 271       * Get the inner priority queue instance
 272       *
 273       * @throws Exception\DomainException
 274       * @return SplPriorityQueue
 275       */
 276      protected function getQueue()
 277      {
 278          if (null === $this->queue) {
 279              $this->queue = new $this->queueClass();
 280              if (!$this->queue instanceof \SplPriorityQueue) {
 281                  throw new Exception\DomainException(sprintf(
 282                      'PriorityQueue expects an internal queue of type SplPriorityQueue; received "%s"',
 283                      get_class($this->queue)
 284                  ));
 285              }
 286          }
 287          return $this->queue;
 288      }
 289  
 290      /**
 291       * Add support for deep cloning
 292       *
 293       * @return void
 294       */
 295      public function __clone()
 296      {
 297          if (null !== $this->queue) {
 298              $this->queue = clone $this->queue;
 299          }
 300      }
 301  }


Generated: Wed Nov 11 20:33:01 2020 Cross-referenced by PHPXref 0.7.1