1010 */
1111package org .simplesim .core .scheduling ;
1212
13- import java .util .ArrayList ;
13+ import java .util .Collections ;
1414import java .util .HashMap ;
15- import java .util .Iterator ;
1615import java .util .List ;
1716import java .util .PriorityQueue ;
1817import java .util .Queue ;
2322 * Just as the other bucket queues, this one is also based on a simple time to
2423 * bucket mapping, each bucket containing events with equal time stamps. In this
2524 * implementation, an additional {@code PriorityQueue} is used to accelerate
26- * access to the minimal time stamp by {@code getMin()}. Within this queue, an
27- * {@code EventQueueEntry} couples the time stamp with the bucket. Because of
28- * the underlying heap structure, the look-up of the first element is faster
29- * than in a {@code HashedBucketQueue}.
25+ * lookup of the minimal time stamp by {@code getMin()}. Thus, the queue has to
26+ * be maintained in parallel to the map and kept in sync.
3027 * <p>
31- * Note: This queue type performs best for dequeuing <i>all</i> events
32- * with minimal time stamp ({@link #dequeueAll()}). It is well suited for a
33- * global event queue and has a performance similar to the
34- * {@code SortedBucketQueue}.
28+ * Note: This queue type performs best for dequeuing <i>all</i> events with
29+ * minimal time stamp ({@link #dequeueAll()}). It is well suited for a global
30+ * event queue and has a performance similar to the {@code SortedBucketQueue}.
3531 *
3632 * @param <E> event type
3733 *
4137public final class HeapBucketQueue <E > extends AbstractBucketQueue <E , HashMap <Time , List <E >>> {
4238
4339 // additional heap structure to facilitate getMin()
44- private final Queue <EventQueueEntry < List < E >> > queue =new PriorityQueue <>();
40+ private final Queue <Time > queue =new PriorityQueue <>();
4541
4642 public HeapBucketQueue () {
4743 super (new HashMap <>());
4844 }
4945
50- private Queue <EventQueueEntry <List <E >>> getQueue () {
51- return queue ;
52- }
46+ private Queue <Time > getQueue () { return queue ; }
5347
54- /*
55- * (non-Javadoc)
56- *
57- * @see org.simplesim.core.scheduling.EventQueue#dequeue(java.lang.Object)
58- */
5948 @ Override
60- public Time dequeue (E event ) {
61- final Iterator <EventQueueEntry <List <E >>> iterator =getQueue ().iterator ();
62- while (iterator .hasNext ()) {
63- final EventQueueEntry <List <E >> entry =iterator .next ();
64- final List <E > bucket =entry .getEvent ();
65- if (bucket .contains (event )) {
66- bucket .remove (event );
67- if (bucket .isEmpty ()) {
68- getMap ().remove (entry .getTime ());
69- getQueue ().remove (entry );
70- }
71- size --;
72- return entry .getTime ();
73- }
74- }
75- return null ;
49+ void removeEmptyBucket (Time time ) {
50+ super .removeEmptyBucket (time );
51+ getQueue ().remove (time );
7652 }
7753
7854 /*
7955 * (non-Javadoc)
8056 *
81- * @see org.simplesim.core.scheduling.EventQueue#dequeue()
57+ * @see org.simplesim.core.scheduling.EventQueue#enqueue(java.lang.Object,
58+ * org.simplesim.core.scheduling.Time)
8259 */
83- @ Override
84- public E dequeue () {
85- if (isEmpty ()) return null ;
86- final Time min =getMin ();
87- final List <E > bucket =getMap ().get (min );
88- if (bucket .isEmpty ()) throw new UnexpectedEmptyBucketException ();
89- final E result =bucket .remove (bucket .size ()-1 );
90- if (bucket .isEmpty ()) {
91- getMap ().remove (min );
92- getQueue ().poll ();
93- }
94- size --;
95- return result ;
96- }
97-
9860 @ Override
9961 public void enqueue (E event , Time time ) {
100- List <E > bucket =getMap ().get (time );
101- if (bucket ==null ) { // time stamp has not been added to queue, yet
102- bucket =new ArrayList <>();
103- getMap ().put (time ,bucket );
104- getQueue ().add (new EventQueueEntry <>(time ,bucket ));
105- } // now we definitely have a valid entry queued in the heap
106- bucket .add (event ); // add the event to the bucket
107- size ++;
62+ if (!getMap ().containsKey (time )) getQueue ().add (time );
63+ super .enqueue (event ,time );
10864 }
10965
11066 /*
@@ -116,16 +72,7 @@ public void enqueue(E event, Time time) {
11672 @ Override
11773 public List <E > dequeueAll (Time time ) {
11874 final List <E > bucket =super .dequeueAll (time );
119- if (!bucket .isEmpty ()) { // remove bucket also from queue
120- final Iterator <EventQueueEntry <List <E >>> iterator =getQueue ().iterator ();
121- while (iterator .hasNext ()) {
122- final EventQueueEntry <List <E >> entry =iterator .next ();
123- if (time .equals (entry .getTime ())) {
124- iterator .remove ();
125- return bucket ;
126- }
127- }
128- }
75+ if (!bucket .isEmpty ()) getQueue ().remove (time );
12976 return bucket ;
13077 }
13178
@@ -136,11 +83,8 @@ public List<E> dequeueAll(Time time) {
13683 */
13784 @ Override
13885 public List <E > dequeueAll () {
139- final List <E > bucket =getMap ().remove (getMin ());
140- if (bucket .isEmpty ()) throw new UnexpectedEmptyBucketException ();
141- getQueue ().poll ();
142- size -=bucket .size ();
143- return bucket ;
86+ if (getQueue ().isEmpty ()) return Collections .emptyList ();
87+ return super .dequeueAll (getQueue ().poll ());
14488 }
14589
14690 /*
@@ -149,8 +93,6 @@ public List<E> dequeueAll() {
14993 * @see org.simplesim.core.scheduling.EventQueue#getMin()
15094 */
15195 @ Override
152- public Time getMin () {
153- return getQueue ().peek ().getTime ();
154- }
96+ public Time getMin () { return getQueue ().peek (); }
15597
15698}
0 commit comments