CachedList.java |
/*************************************** * * * JBoss: The OpenSource J2EE WebOS * * * * Distributable under LGPL license. * * See terms of license at gnu.org. * * * ***************************************/ package org.jboss.util.collection; import java.util.List; import java.util.LinkedList; import java.util.AbstractList; import java.util.Iterator; import java.lang.ref.ReferenceQueue; import org.jboss.util.SoftObject; import org.jboss.util.Objects; /** * A wrapper around a <code>List</code> which translates added objects * into {@link SoftObject} references, allowing the VM to garbage collect * objects in the collection when memory is low. * * @version <tt>$Revision: 1.3 $</tt> * @author <a href="mailto:jason@planet57.com">Jason Dillon</a> */ public class CachedList extends AbstractList { /** Reference queue. */ protected final ReferenceQueue queue = new ReferenceQueue(); /** Wrapped list. */ protected final List list; /** * Construct a <tt>CachedList</tt>. * * @param list List to wrap. */ public CachedList(final List list) { this.list = list; } /** * Construct a <tt>CachedList</tt> using a <tt>LinkedList</tt> for * storage. */ public CachedList() { this(new LinkedList()); } /** * Dereference the object at the given index. */ private Object getObject(final int index) { Object obj = list.get(index); return Objects.deref(obj); } /** * Returns the element at the specified position in this list. * * @param index Index of element to return. * @return The element at the specified position. */ public Object get(final int index) { maintain(); return getObject(index); } /** * Return the size of the list. * * @return The number of elements in the list. */ public int size() { maintain(); return list.size(); } /** * Replaces the element at the specified position in this list with the * specified element. * * @param index Index of element to replace. * @param obj Element to be stored at the specified postion. * @return The previous element at the given index. */ public Object set(final int index, final Object obj) { maintain(); SoftObject soft = SoftObject.create(obj, queue); soft = (SoftObject)list.set(index, soft); return Objects.deref(soft); } /** * Inserts the specified element at the specified position in this list * (optional operation). Shifts the element currently at that position * (if any) and any subsequent elements to the right (adds one to their * indices). * * @param index Index at which the specified element is to be inserted. * @param obj Element to be inserted. */ public void add(final int index, final Object obj) { maintain(); SoftObject soft = SoftObject.create(obj, queue); list.add(index, soft); } /** * Removes the element at the specified position in this list (optional * operation). Shifts any subsequent elements to the left (subtracts one * from their indices). Returns the element that was removed from the list. * * @param index The index of the element to remove. * @return The element previously at the specified position. */ public Object remove(final int index) { maintain(); Object obj = list.remove(index); return Objects.deref(obj); } /** * Maintains the collection by removing garbage collected objects. */ private void maintain() { SoftObject obj; int count = 0; while ((obj = (SoftObject)queue.poll()) != null) { count++; list.remove(obj); } if (count != 0) { // some temporary debugging fluff System.err.println("vm reclaimed " + count + " objects"); } } }
CachedList.java |