@@ -208,47 +208,80 @@ public void testAddAllDoesNotFitIntoQueue() {
208208 () -> pq .addAll (list ));
209209 }
210210
211- /** Randomly add and remove elements, comparing against the reference java.util.PriorityQueue. */
212- public void testRemovalsAndInsertions () {
211+ /** Randomly remove elements, comparing against the reference java.util.PriorityQueue by value . */
212+ public void testRemovals () {
213213 int maxElement = RandomNumbers .randomIntBetween (random (), 1 , 10_000 );
214214 int size = maxElement / 2 + 1 ;
215-
216215 var reference = new java .util .PriorityQueue <Integer >();
217216 var pq = new IntegerQueue (size );
218-
219217 Random localRandom = nonAssertingRandom (random ());
220-
221- // Lucene's PriorityQueue.remove uses reference equality, not .equals to determine which
222- // elements
223- // to remove (!).
224218 HashMap <Integer , Integer > ints = new HashMap <>();
219+ // Fill both queues with up to maxSize elements
220+ for (int i = 0 ; i < size ; i ++) {
221+ Integer element = ints .computeIfAbsent (localRandom .nextInt (maxElement ), k -> k );
222+ pq .add (element );
223+ reference .add (element );
224+ }
225+ // Perform random removals and compare by value
226+ for (int i = 0 ; i < size ; i ++) {
227+ Integer element = ints .computeIfAbsent (localRandom .nextInt (maxElement ), k -> k );
228+ int pqCount = 0 , refCount = 0 ;
229+ for (Integer val : pq ) if (val .equals (element )) pqCount ++;
230+ for (Integer val : reference ) if (val .equals (element )) refCount ++;
231+ boolean pqRemoved = pq .remove (element );
232+ boolean refRemoved = reference .remove (element );
233+ assertEquals ("remove() should return true if value was present" , refCount > 0 , pqRemoved );
234+ assertEquals ("remove() should return true if value was present" , refCount > 0 , refRemoved );
235+ int pqCountAfter = 0 , refCountAfter = 0 ;
236+ for (Integer val : pq ) if (val .equals (element )) pqCountAfter ++;
237+ for (Integer val : reference ) if (val .equals (element )) refCountAfter ++;
238+ assertEquals ("Should remove only one instance (value)" , Math .max (0 , refCount - 1 ), refCountAfter );
239+ assertEquals ("Should remove only one instance (value)" , Math .max (0 , pqCount - 1 ), pqCountAfter );
240+ assertEquals ("pq and reference should match counts after removal" , refCountAfter , pqCountAfter );
241+ assertEquals ("size after removal should match" , reference .size (), pq .size ());
242+ Integer pqTop = pq .top ();
243+ Integer refTop = reference .peek ();
244+ if (pqTop != null && refTop != null ) {
245+ assertEquals ("top() value difference after removal?" , refTop .intValue (), pqTop .intValue ());
246+ } else {
247+ assertEquals ("top() value difference after removal?" , refTop , pqTop );
248+ }
249+ }
250+ pq .checkValidity ();
251+ }
225252
253+ /** Randomly add elements, comparing against the reference java.util.PriorityQueue by value. */
254+ public void testInsertions () {
255+ int maxElement = RandomNumbers .randomIntBetween (random (), 1 , 10_000 );
256+ int size = maxElement / 2 + 1 ;
257+ var reference = new java .util .PriorityQueue <Integer >();
258+ var pq = new IntegerQueue (size );
259+ Random localRandom = nonAssertingRandom (random ());
260+ HashMap <Integer , Integer > ints = new HashMap <>();
226261 for (int i = 0 , iters = size * 2 ; i < iters ; i ++) {
227262 Integer element = ints .computeIfAbsent (localRandom .nextInt (maxElement ), k -> k );
228-
229- var action = localRandom . nextInt ( 100 );
230- if ( action < 25 ) {
231- // removals, possibly misses.
232- assertEquals ( "remove() difference: " + i , reference .remove (element ), pq . remove ( element ) );
263+ var dropped = pq . insertWithOverflow ( element );
264+ reference . add ( element );
265+ Integer droppedReference ;
266+ if ( reference . size () > size ) {
267+ droppedReference = reference .remove ();
233268 } else {
234- // additions.
235- var dropped = pq .insertWithOverflow (element );
236-
237- reference .add (element );
238- Integer droppedReference ;
239- if (reference .size () > size ) {
240- droppedReference = reference .remove ();
241- } else {
242- droppedReference = null ;
243- }
244-
245- assertEquals ("insertWithOverflow() difference." , dropped , droppedReference );
269+ droppedReference = null ;
270+ }
271+ if (dropped != null && droppedReference != null ) {
272+ assertEquals ("insertWithOverflow() dropped value difference." , dropped .intValue (), droppedReference .intValue ());
273+ } else {
274+ assertEquals ("insertWithOverflow() dropped value difference." , droppedReference , dropped );
246275 }
247-
248276 assertEquals ("insertWithOverflow() size difference?" , reference .size (), pq .size ());
249- assertEquals ("top() difference?" , reference .peek (), pq .top ());
277+ Integer pqTop = pq .top ();
278+ Integer refTop = reference .peek ();
279+ if (pqTop != null && refTop != null ) {
280+ assertEquals ("top() value difference?" , refTop .intValue (), pqTop .intValue ());
281+ } else {
282+ assertEquals ("top() value difference?" , refTop , pqTop );
283+ }
250284 }
251-
252285 pq .checkValidity ();
253286 }
254287
0 commit comments