package org.jboss.resteasy.client.jaxrs.cache; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.MultivaluedMap; import java.util.concurrent.atomic.AtomicLong; /** * In-memory BrowserCache. Uses an underlying cache, with ConcurrentMapCache as * the default. You specify maximum bytes you want the cache to have. The * default is 2Megabytes. If the cache exceeds this amount, it is wiped clean. * This rather draconian approach to cache reaping is to avoid synchronization * that you would normally have to do in a sophisticated cache. * <p/> * With high concurrent access, because this is not a sophisticated cache, * sometimes a cache entry may be lost. It is consistent though. * * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a> * @version $Revision: 1 $ */ public class LightweightBrowserCache implements BrowserCache { protected long maxBytes = 2000000; // 2 meg default protected BrowserCache internalCache = null; protected AtomicLong bytes = new AtomicLong(0); public LightweightBrowserCache() { this(new MapCache()); } public LightweightBrowserCache(BrowserCache cache) { this.internalCache = cache; } public BrowserCache getInternalCache() { return internalCache; } public void setInternalCache(BrowserCache internalCache) { this.internalCache = internalCache; } public long getMaxBytes() { return maxBytes; } public void setMaxBytes(long maxBytes) { this.maxBytes = maxBytes; } public Entry getAny(String key) { return internalCache.getAny(key); } public Entry remove(String key, MediaType type) { Entry entry = internalCache.remove(key, type); if (entry != null) bytes.addAndGet(-1 * entry.getCached().length); return entry; } public long getByteCount() { return bytes.get(); } public Entry get(String key, MediaType accept) { return internalCache.get(key, accept); } public Entry put(String key, MediaType mediaType, MultivaluedMap<String, String> headers, byte[] cached, int expires, String etag, String lastModified) { Entry previousValue = internalCache.get(key, mediaType); int sizeDiff = -1; if (previousValue == null) sizeDiff = cached.length; else sizeDiff = cached.length - previousValue.getCached().length; if (bytes.addAndGet(sizeDiff) > maxBytes) { clear(); bytes.addAndGet(sizeDiff); } return internalCache.put(key, mediaType, headers, cached, expires, etag, lastModified); } public void clear() { internalCache.clear(); bytes.set(0); } }