/******************************************************************************* * Copyright (c) 2010 Bug Labs, Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * - Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * - Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * - Neither the name of Bug Labs, Inc. nor the names of its contributors may be * used to endorse or promote products derived from this software without * specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. *******************************************************************************/ package com.buglabs.osgi.log; import java.util.Collection; import java.util.Iterator; import java.util.LinkedList; import java.util.List; import java.util.ListIterator; import java.util.Queue; /** * A queue type that silently truncates older (FIFO) elements after size has been reached. * This class decorates java.util.LinkedList. * * @author kgilmer * */ class FixedSizeQueue implements Queue<Object> { private final LinkedList<Object> list; private final int size; /** * @param size number of elements to store before removing older entries. Must be 2 our greater. */ public FixedSizeQueue(int size) { if (size < 2) { throw new IllegalArgumentException("Size of queue must be at least 2."); } this.size = size; list = new LinkedList<Object>(); } /** * @param size number of elements to store before removing older entries. * @param c collection to add. Collection may be truncated if size is greater than size. */ public FixedSizeQueue(int size, Collection<Object> c) { if (size < 2) { throw new IllegalArgumentException("Size of queue must be at least 2."); } this.size = size; list = new LinkedList<Object>(c); checkAndRemove(); } public void add(int index, Object element) { list.add(index, element); checkAndRemove(); } public boolean add(Object e) { boolean o = list.add(e); checkAndRemove(); return o; } /** * Reduce the size of the list until it matches the defined size. */ private synchronized void checkAndRemove() { while (list.size() > size) { list.removeFirst(); } } public boolean addAll(Collection<? extends Object> c) { //TODO it would be more efficient for large collections to only insert up to the size of the queue. boolean b = list.addAll(c); checkAndRemove(); return b; } public boolean addAll(int index, Collection<? extends Object> c) { //TODO it would be more efficient for large collections to only insert up to the size of the queue. return list.addAll(index, c); } public void addFirst(Object e) { list.addFirst(e); checkAndRemove(); } public void addLast(Object e) { list.addLast(e); checkAndRemove(); } public void clear() { list.clear(); } public Object clone() { return list.clone(); } public boolean contains(Object o) { return list.contains(o); } public boolean containsAll(Collection<?> c) { return list.containsAll(c); } public Iterator<Object> descendingIterator() { return list.descendingIterator(); } public Object element() { return list.element(); } public boolean equals(Object arg0) { return list.equals(arg0); } public Object get(int index) { return list.get(index); } public Object getFirst() { return list.getFirst(); } public Object getLast() { return list.getLast(); } public int hashCode() { return list.hashCode(); } public int indexOf(Object o) { return list.indexOf(o); } public boolean isEmpty() { return list.isEmpty(); } public Iterator<Object> iterator() { return list.iterator(); } public int lastIndexOf(Object o) { return list.lastIndexOf(o); } public ListIterator<Object> listIterator() { return list.listIterator(); } public ListIterator<Object> listIterator(int index) { return list.listIterator(index); } public boolean offer(Object e) { if (list.size() >= size) { return false; } return list.offer(e); } public boolean offerFirst(Object e) { if (list.size() >= size) { return false; } return list.offerFirst(e); } public boolean offerLast(Object e) { if (list.size() >= size) { return false; } return list.offerLast(e); } public Object peek() { return list.peek(); } public Object peekFirst() { return list.peekFirst(); } public Object peekLast() { return list.peekLast(); } public Object poll() { return list.poll(); } public Object pollFirst() { return list.pollFirst(); } public Object pollLast() { return list.pollLast(); } public Object pop() { return list.pop(); } public void push(Object e) { list.push(e); } public Object remove() { return list.remove(); } public Object remove(int index) { return list.remove(index); } public boolean remove(Object o) { return list.remove(o); } public boolean removeAll(Collection<?> c) { return list.removeAll(c); } public Object removeFirst() { return list.removeFirst(); } public boolean removeFirstOccurrence(Object o) { return list.removeFirstOccurrence(o); } public Object removeLast() { return list.removeLast(); } public boolean removeLastOccurrence(Object o) { return list.removeLastOccurrence(o); } public boolean retainAll(Collection<?> c) { return list.retainAll(c); } public Object set(int index, Object element) { Object o = list.set(index, element); checkAndRemove(); return o; } public int size() { return list.size(); } public List<Object> subList(int fromIndex, int toIndex) { return list.subList(fromIndex, toIndex); } public Object[] toArray() { return list.toArray(); } public <T> T[] toArray(T[] a) { return list.toArray(a); } public String toString() { return list.toString(); } }