PageRenderTime 78ms CodeModel.GetById 25ms RepoModel.GetById 1ms app.codeStats 1ms

/www/libs/Zend/Stdlib/PriorityQueue.php

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