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