package edu.colostate.vchill.cache; import java.util.ArrayList; /** * Storage class for VCHILL's Cache module. * Instances of this class are what is stored in the CacheMap. * * @author Jochen Deyke * @version 2007-09-28 */ class CacheSweep<E> { private final ArrayList<E> rays; private volatile boolean complete; /** * Default constructor */ public CacheSweep() { this.rays = new ArrayList<E>(500); //initial size this.complete = false; } /** * Gets a ray out of the cache * * @param ray index of the desired ray * @return the ray if it is in the cache, null otherwise */ public E getData(final int ray) { synchronized (this.rays) { return ray < this.rays.size() ? this.rays.get(ray) : null; } } /** * Gets a ray out of the cache. If the ray is not yet available, waits * for the ray to become available or the sweep to be marked complete. * * @param ray index of the desired ray * @return the ray if it is in the cache, null otherwise */ public E getDataWait(final int ray) { synchronized (this.rays) { while (!this.complete && ray >= this.rays.size()) try { this.rays.wait(); } catch (InterruptedException ie) { } return ray < this.rays.size() ? this.rays.get(ray) : null; } } /** * Gets a ray out of the cache. If the ray is not yet available, waits * for the ray to become available or the sweep to be marked complete. * * @param ray index of the desired ray * @param timeout the maximum number of milliseconds to wait * @return the ray if it is in the cache, null otherwise */ public E getDataWait(final int ray, final long timeout) { synchronized (this.rays) { if (!this.complete && ray >= this.rays.size()) try { this.rays.wait(timeout); } catch (InterruptedException ie) { } return ray < this.rays.size() ? this.rays.get(ray) : null; } } /** * Adds a ray to the cache * * @param data the ray to add */ public void addRay(final E data) { synchronized (this.rays) { this.rays.add(data); this.rays.notifyAll(); } } /** * Checks how many rays are chached * * @return the number of rays currently stored of this type. * This value may change as rays are added. */ public int getNumberOfRays() { synchronized (this.rays) { return this.rays.size(); } } /** * Marks a Type as complete. * <p/> * This allows extra memory to be freed, * and getRay to be sure that no more rays will be added. */ public void setCompleteFlag() { synchronized (this.rays) { this.complete = true; this.trim(); //free extra memory this.rays.notifyAll(); } } /** * Checks if a type completely cached * * @return <code>true</code> if type has been marked complete, * <code>false</code> otherwise */ public boolean getCompleteFlag() { synchronized (this.rays) { return this.complete; } } /** * Checks if part of the type is already cached * * @return <code>true</code> if there are no rays in this type and it has been marked complete, * <code>false</code> otherwise */ public boolean isEmpty() { synchronized (this.rays) { if (this.complete) return false; return this.rays.isEmpty(); } } /** * Frees excess memory by removing null entries from the cache */ public void trim() { synchronized (this.rays) { this.rays.remove(null); this.rays.trimToSize(); } } }