/******************************************************************************* * Copyright (c) 2011 Laurent CARON * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Laurent CARON (laurent.caron at gmail dot com) - initial API and implementation *******************************************************************************/ package org.mihalis.opal.utils; import java.util.ArrayList; import java.util.List; /** * Instance of this class are queues that have a fixed size.<br/> * When the queue is full, the elements are shifted and the first element is * lost. * * @param <T> Type of objects stored in this queue */ public class FixedSizeQueue<T> { private T[] buffer; private int index; /** * Constructor * * @param capacity initial capacity */ @SuppressWarnings("unchecked") public FixedSizeQueue(final int capacity) { this.buffer = (T[]) new Object[capacity]; this.index = 0; } /** * Store an element in the buffer * * @param element element to store */ public void put(final T element) { if (this.index == this.buffer.length) { // Full System.arraycopy(this.buffer, 1, this.buffer, 0, this.buffer.length - 1); this.buffer[this.index - 1] = element; } else { this.buffer[this.index++] = element; } } /** * @return all values stored in this queue */ public List<T> getValues() { final List<T> list = new ArrayList<T>(this.index); for (int i = 0; i < this.index; i++) { if (this.buffer[i] != null) { list.add(this.buffer[i]); } } return list; } /** * @return size of the buffer */ public int getSize() { return this.index; } /** * @param newSize new size of the buffer. If newSize is lower than the * actual size, the buffer will contain the last elements that * have been stored */ @SuppressWarnings("unchecked") public void resizeTo(int newSize) { if (newSize < 0) { newSize = 1; } if (newSize == this.buffer.length) { return; } final T[] resizedBuffer = (T[]) new Object[newSize]; if (newSize > this.buffer.length) { System.arraycopy(this.buffer, 0, resizedBuffer, 0, this.buffer.length); } else { final int startPos = Math.max(0, this.index - newSize); System.arraycopy(this.buffer, startPos, resizedBuffer, 0, newSize); this.index = newSize; } this.buffer = resizedBuffer; } /** * Test method * * @param args */ public static void main(final String[] args) { final FixedSizeQueue<Integer> buffer = new FixedSizeQueue<Integer>(5); System.out.println("Filling..."); for (int i = 0; i < 10; i++) { buffer.put(i); System.out.println("i=" + i + ", size=" + buffer.getSize() + ", values=" + buffer.getValues()); } System.out.println("Resize to 10..."); buffer.resizeTo(10); System.out.println("size=" + buffer.getSize() + ", values=" + buffer.getValues()); buffer.put(10); System.out.println("size=" + buffer.getSize() + ", values=" + buffer.getValues()); System.out.println("Resize to 3..."); buffer.resizeTo(3); System.out.println("size=" + buffer.getSize() + ", values=" + buffer.getValues()); buffer.put(11); System.out.println("size=" + buffer.getSize() + ", values=" + buffer.getValues()); System.out.println("Resize to 5..."); buffer.resizeTo(5); buffer.put(12); buffer.put(13); buffer.put(14); System.out.println("size=" + buffer.getSize() + ", values=" + buffer.getValues()); System.out.println("Resize to 3..."); buffer.resizeTo(3); System.out.println("size=" + buffer.getSize() + ", values=" + buffer.getValues()); } }