/******************************************************************************* * Copyright (c) 2003-2005, 2013 Till Zoppke. * All rights reserved. This program and the accompanying materials * are made available under the terms of the GNU Public License v3.0 * which accompanies this distribution, and is available at * http://www.gnu.org/licenses/gpl.html * * Contributors: * Till Zoppke - initial API and implementation ******************************************************************************/ /* * Created on 25.03.2004 */ package eniac.simulation; /** * Class EventQueue is a priority Queue for Events implemented as a heap. * * @author till zopppke */ public class EventQueue { private static final int DEFAULT_SIZE = 100; // vector containing discreteElements maintaining a heap property private EEvent[] _elements = new EEvent[DEFAULT_SIZE]; private int _size = 0; // =========================== constructors // ================================= /** * Constructs an initially empty discreteEventQueue */ public EventQueue() { // empty } // ======================== private methods // ================================= // compares two elements by calling compareTo private boolean lessThan(int i, int j) { return _elements[i].time < _elements[j].time; } // increases the specified element so that the heap property will maintained private void increase(int i) { int parent = (i - 1) / 2; while (i > 0 && lessThan(i, parent)) { swap(i, parent); i = parent; parent = (i - 1) / 2; } } // lets the specified element sink private void reHeap() { int i = 0; int j = 2 * i + 1; boolean done = false; while (j < _size && !done) { // compare left child to right child if (j + 1 < _size && lessThan(j + 1, j)) { j++; } // compare parent to smaller child if (lessThan(j, i)) { swap(i, j); i = j; j = 2 * j + 1; } else { done = true; } } } // swaps two elements in the elements Vector private void swap(int i, int j) { EEvent temp = _elements[i]; _elements[i] = _elements[j]; _elements[j] = temp; } private void checkSize(int n) { while (_size + n > _elements.length) { EEvent[] temp = _elements; _elements = new EEvent[_elements.length + DEFAULT_SIZE]; System.arraycopy(temp, 0, _elements, 0, temp.length); } } // ========================= public methods // ================================= /** * Checks whether this discreteEventQueue contains more events * * @see java.util.Enumeration#hasMoreElements() */ public synchronized boolean isEmpty() { return _size == 0; } /** * Returns the next event (that will happen in the nearest future) * * @see java.util.Enumeration#nextElement() */ public synchronized EEvent removeFirst() { EEvent retour = _elements[0]; _elements[0] = _elements[--_size]; reHeap(); return retour; } public synchronized EEvent getFirst() { return _elements[0]; } /** * inserts a discreteEvent by maintaining the heap property * * @param e * the Element to be inserted */ public synchronized void insert(EEvent e) { checkSize(1); _elements[_size] = e; increase(_size++); } public synchronized void insert(EEvent[] elements) { checkSize(elements.length); for (int i = 0; i < elements.length; ++i) { _elements[_size] = elements[i]; increase(_size++); } } public synchronized void empty() { _size = 0; } }