All Downloads are FREE. Search and download functionalities are using the official Maven repository.

net.sf.microlog.core.CyclicBuffer Maven / Gradle / Ivy

The newest version!
/*
 * Copyright 2008 The Microlog project @sourceforge.net
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 * http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package net.sf.microlog.core;

import java.util.Vector;

/**
 * A class that stores Objects in a cyclic buffer. The
 * CyclicBuffer is totally synchronized.
 * 
 * @author Johan Karlsson ([email protected])
 */
public class CyclicBuffer {

	public static final int DEFAULT_BUFFER_SIZE = 10;

	private int bufferSize;
	private Object[] buffer;
	int currentIndex = -1;
	int currentOldestIndex = -1;

	private int length;

	/**
	 * Create a CyclicBuffer with the default buffer size.
	 */
	public CyclicBuffer() {
		bufferSize = DEFAULT_BUFFER_SIZE;
		buffer = new Object[bufferSize];
	}

	/**
	 * Create a CyclicBuffer with the specified buffer size.
	 * 
	 * @param bufferSize
	 *            the size of the buffer.
	 */
	public CyclicBuffer(int bufferSize) throws IllegalArgumentException {
		if (bufferSize < 0) {
			throw new IllegalArgumentException(
					"Not allowed to resize to a negative size.");
		}

		this.bufferSize = bufferSize;
		buffer = new Object[bufferSize];
	}

	/**
	 * Get the buffer size.
	 * 
	 * @return the bufferSize the size of the buffer.
	 */
	public int getBufferSize() {
		return bufferSize;
	}

	/**
	 * The current length of the buffer, i.e. how many Objects that
	 * are stored in the buffer.
	 * 
	 * @return the length of the buffer.
	 */
	public int length() {
		return length;
	}

	/**
	 * Resize the buffer. The old objects are discarded.
	 * 
	 * @param newSize
	 *            the new size of the buffer.
	 * @throws IllegalArgumentException
	 *             if the newSize is negative.
	 */
	public synchronized void resize(int newSize)
			throws IllegalArgumentException {
		if (newSize < 0) {
			throw new IllegalArgumentException(
					"Not allowed to resize to a negative size.");
		}

		this.bufferSize = newSize;
		buffer = new Object[bufferSize];
	}

	/**
	 * 
	 * @param object
	 *            the Object to add.
	 * @throws IllegalArgumentException
	 *             if the object is null.
	 */
	public synchronized void add(Object object) throws IllegalArgumentException {
		if (object == null) {
			throw new IllegalArgumentException(
					"You are not allowed to add an Object that is null.");
		}

		currentIndex = (currentIndex + 1) % buffer.length;
		buffer[currentIndex] = object;

		if (length < bufferSize) {
			length++;
			currentOldestIndex = 0;
		} else {
			currentOldestIndex = (currentOldestIndex + 1) % buffer.length;
		}
	}

	/**
	 * Get the oldest Object in the buffer. This is removed from
	 * the buffer.
	 * 
	 * @return the oldest Object in the buffer. If no more objects
	 *         are in the buffer, null is returned.
	 */
	public synchronized Object get() {
		Object object = null;

		if (length > 0) {
			object = buffer[currentOldestIndex];
			buffer[currentOldestIndex] = null;
			length--;
			if (length != 0) {
				currentOldestIndex = (currentOldestIndex + 1) % buffer.length;
			} else {
				currentOldestIndex = -1;
				currentIndex = -1;
			}
		}

		return object;
	}

	/**
	 * Clear the buffer. The buffer size is still the same.
	 */
	public synchronized void clear() {
		Object object = buffer[currentIndex];

		while (object != null) {
			buffer[currentIndex] = null;
			currentIndex = currentIndex - 1;
			length = length - 1;

			if (currentIndex == -1) {
				currentIndex = bufferSize - 1;
			}

			object = buffer[currentIndex];
		}

		currentIndex = -1;
		currentOldestIndex = -1;
	}

	/**
	 * Get the internal buffer as a Vector. The content is copied.
	 * 
	 * @return a Vector with buffer content.
	 */
	public synchronized Vector getAsVector() {
		Vector vector = new Vector(length);

		for (int index = 0; index < length; index++) {
			vector.addElement(buffer[index]);
		}

		return vector;
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy