@@ -57,9 +57,9 @@ class FastPriorityQueue implements Iterator, Countable, Serializable
57
57
/**
58
58
* Max priority
59
59
*
60
- * @var integer
60
+ * @var integer|null
61
61
*/
62
- protected $ maxPriority = 0 ;
62
+ protected $ maxPriority = null ;
63
63
64
64
/**
65
65
* Total number of elements in the queue
@@ -86,7 +86,7 @@ class FastPriorityQueue implements Iterator, Countable, Serializable
86
86
* Insert an element in the queue with a specified priority
87
87
*
88
88
* @param mixed $value
89
- * @param integer $priority a positive integer
89
+ * @param integer $priority
90
90
*/
91
91
public function insert ($ value , $ priority )
92
92
{
@@ -96,7 +96,7 @@ public function insert($value, $priority)
96
96
$ this ->values [$ priority ][] = $ value ;
97
97
if (! isset ($ this ->priorities [$ priority ])) {
98
98
$ this ->priorities [$ priority ] = $ priority ;
99
- $ this ->maxPriority = max ($ priority , $ this ->maxPriority );
99
+ $ this ->maxPriority = $ this -> maxPriority === null ? $ priority : max ($ priority , $ this ->maxPriority );
100
100
}
101
101
++$ this ->count ;
102
102
}
@@ -132,11 +132,35 @@ public function extract()
132
132
*/
133
133
public function remove ($ datum )
134
134
{
135
+ $ currentIndex = $ this ->index ;
136
+ $ currentSubIndex = $ this ->subIndex ;
137
+ $ currentPriority = $ this ->maxPriority ;
138
+
135
139
$ this ->rewind ();
136
140
while ($ this ->valid ()) {
137
141
if (current ($ this ->values [$ this ->maxPriority ]) === $ datum ) {
138
142
$ index = key ($ this ->values [$ this ->maxPriority ]);
139
143
unset($ this ->values [$ this ->maxPriority ][$ index ]);
144
+
145
+ // The `next()` method advances the internal array pointer, so we need to use the `reset()` function,
146
+ // otherwise we would lose all elements before the place the pointer points.
147
+ reset ($ this ->values [$ this ->maxPriority ]);
148
+
149
+ $ this ->index = $ currentIndex ;
150
+ $ this ->subIndex = $ currentSubIndex ;
151
+
152
+ // If the array is empty we need to destroy the unnecessary priority,
153
+ // otherwise we would end up with an incorrect value of `$this->count`
154
+ // {@see \Zend\Stdlib\FastPriorityQueue::nextAndRemove()}.
155
+ if (empty ($ this ->values [$ this ->maxPriority ])) {
156
+ unset($ this ->values [$ this ->maxPriority ]);
157
+ unset($ this ->priorities [$ this ->maxPriority ]);
158
+ if ($ this ->maxPriority === $ currentPriority ) {
159
+ $ this ->subIndex = 0 ;
160
+ }
161
+ }
162
+
163
+ $ this ->maxPriority = empty ($ this ->priorities ) ? null : max ($ this ->priorities );
140
164
--$ this ->count ;
141
165
return true ;
142
166
}
@@ -191,11 +215,15 @@ public function key()
191
215
*/
192
216
protected function nextAndRemove ()
193
217
{
218
+ $ key = key ($ this ->values [$ this ->maxPriority ]);
219
+
194
220
if (false === next ($ this ->values [$ this ->maxPriority ])) {
195
221
unset($ this ->priorities [$ this ->maxPriority ]);
196
222
unset($ this ->values [$ this ->maxPriority ]);
197
- $ this ->maxPriority = empty ($ this ->priorities ) ? 0 : max ($ this ->priorities );
223
+ $ this ->maxPriority = empty ($ this ->priorities ) ? null : max ($ this ->priorities );
198
224
$ this ->subIndex = -1 ;
225
+ } else {
226
+ unset($ this ->values [$ this ->maxPriority ][$ key ]);
199
227
}
200
228
++$ this ->index ;
201
229
++$ this ->subIndex ;
@@ -211,7 +239,7 @@ public function next()
211
239
if (false === next ($ this ->values [$ this ->maxPriority ])) {
212
240
unset($ this ->subPriorities [$ this ->maxPriority ]);
213
241
reset ($ this ->values [$ this ->maxPriority ]);
214
- $ this ->maxPriority = empty ($ this ->subPriorities ) ? 0 : max ($ this ->subPriorities );
242
+ $ this ->maxPriority = empty ($ this ->subPriorities ) ? null : max ($ this ->subPriorities );
215
243
$ this ->subIndex = -1 ;
216
244
}
217
245
++$ this ->index ;
0 commit comments