Verzeichnisstruktur phpBB-3.2.0


Veröffentlicht
06.01.2017

So funktioniert es


Auf das letzte Element klicken. Dies geht jeweils ein Schritt zurück

Auf das Icon klicken, dies öffnet das Verzeichnis. Nochmal klicken schließt das Verzeichnis.
Auf den Verzeichnisnamen klicken, dies zeigt nur das Verzeichnis mit Inhalt an

      (Beispiel Datei-Icons)

Auf das Icon klicken um den Quellcode anzuzeigen

PriorityQueue.php

Zuletzt modifiziert: 09.10.2024, 12:55 - Dateigröße: 7.71 KiB


 001  <?php
 002  /**
 003   * Zend Framework (http://framework.zend.com/)
 004   *
 005   * @link      http://github.com/zendframework/zf2 for the canonical source repository
 006   * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
 007   * @license   http://framework.zend.com/license/new-bsd New BSD License
 008   */
 009   
 010  namespace Zend\Stdlib;
 011   
 012  use Countable;
 013  use IteratorAggregate;
 014  use Serializable;
 015   
 016  /**
 017   * Re-usable, serializable priority queue implementation
 018   *
 019   * SplPriorityQueue acts as a heap; on iteration, each item is removed from the
 020   * queue. If you wish to re-use such a queue, you need to clone it first. This
 021   * makes for some interesting issues if you wish to delete items from the queue,
 022   * or, as already stated, iterate over it multiple times.
 023   *
 024   * This class aggregates items for the queue itself, but also composes an
 025   * "inner" iterator in the form of an SplPriorityQueue object for performing
 026   * the actual iteration.
 027   */
 028  class PriorityQueue implements Countable, IteratorAggregate, Serializable
 029  {
 030      const EXTR_DATA     = 0x00000001;
 031      const EXTR_PRIORITY = 0x00000002;
 032      const EXTR_BOTH     = 0x00000003;
 033   
 034      /**
 035       * Inner queue class to use for iteration
 036       * @var string
 037       */
 038      protected $queueClass = 'Zend\Stdlib\SplPriorityQueue';
 039   
 040      /**
 041       * Actual items aggregated in the priority queue. Each item is an array
 042       * with keys "data" and "priority".
 043       * @var array
 044       */
 045      protected $items      = array();
 046   
 047      /**
 048       * Inner queue object
 049       * @var SplPriorityQueue
 050       */
 051      protected $queue;
 052   
 053      /**
 054       * Insert an item into the queue
 055       *
 056       * Priority defaults to 1 (low priority) if none provided.
 057       *
 058       * @param  mixed $data
 059       * @param  int $priority
 060       * @return PriorityQueue
 061       */
 062      public function insert($data, $priority = 1)
 063      {
 064          $priority = (int) $priority;
 065          $this->items[] = array(
 066              'data'     => $data,
 067              'priority' => $priority,
 068          );
 069          $this->getQueue()->insert($data, $priority);
 070          return $this;
 071      }
 072   
 073      /**
 074       * Remove an item from the queue
 075       *
 076       * This is different than {@link extract()}; its purpose is to dequeue an
 077       * item.
 078       *
 079       * This operation is potentially expensive, as it requires
 080       * re-initialization and re-population of the inner queue.
 081       *
 082       * Note: this removes the first item matching the provided item found. If
 083       * the same item has been added multiple times, it will not remove other
 084       * instances.
 085       *
 086       * @param  mixed $datum
 087       * @return bool False if the item was not found, true otherwise.
 088       */
 089      public function remove($datum)
 090      {
 091          $found = false;
 092          foreach ($this->items as $key => $item) {
 093              if ($item['data'] === $datum) {
 094                  $found = true;
 095                  break;
 096              }
 097          }
 098          if ($found) {
 099              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  }
 302