/** * A queue of bodies. A collection designed for holding bodies prior to processing. * The bodies of the queue can be accessed in a FIFO (first-in-first-out) manner, * i.e., the body that was first inserted by 'add' is retrieved first by 'poll'. * The number of elements of the queue is not limited. */ public class BodyQueue { private int capacity; private int head = 0; private int tail = 0; private Body[] queue; public BodyQueue() { this(4); } /** * Initializes this queue with an initial capacity. * Precondition: initialCapacity > 0. */ public BodyQueue(int initialCapacity) { this.capacity = initialCapacity; this.queue = new Body[this.capacity]; } /** * Initializes this queue as an independent copy of the specified queue. * Calling methods of this queue will not affect the specified queue * and vice versa. * Precondition: other != null. */ public BodyQueue(BodyQueue other) { this.capacity = other.capacity; this.head = other.size(); this.tail = 0; this.queue = new Body[this.capacity]; for (int i = 0, j = other.tail; i < this.head; i++, j++) { this.queue[i] = other.queue[j % other.capacity]; } } /** * Adds the specified body 'b' to this queue. */ public void add(Body b) { if ((head + 1) % capacity == tail) { doubleCapacity(); } queue[head] = b; head = (head + 1) % capacity; } /** * Retrieves and removes the head of this queue, or returns 'null' * if this queue is empty. */ public Body poll() { if (tail == head) { tail = 0; head = 0; return null; } Body b = queue[tail]; queue[tail] = null; tail = (tail + 1) % capacity; return b; } /** * Returns the number of bodies in this queue. */ public int size() { return (head - tail + capacity) % capacity; } /** * Double the capacity of the queue. */ private void doubleCapacity() { Body[] tmp = new Body[capacity * 2]; head = size(); for (int i = 0, j = tail; i < head; i++, j++) { tmp[i] = queue[j % capacity]; } tail = 0; capacity *= 2; queue = tmp; } }