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

org.xson.web.cache.SoftCache Maven / Gradle / Ivy

Go to download

xco-web is an easy to use control layer framework, is part of the SOA system, using xml language to describe the controller.

The newest version!
package org.xson.web.cache;

import java.lang.ref.ReferenceQueue;
import java.lang.ref.SoftReference;
import java.util.LinkedList;

public class SoftCache extends AbstractCache {

	private final LinkedList		hardLinksToAvoidGarbageCollection;
	private final ReferenceQueue	queueOfGarbageCollectedEntries;
	private final ICache					delegate;
	private int								numberOfHardLinks;

	public SoftCache(ICache delegate, int size) {
		this.delegate = delegate;
		// this.numberOfHardLinks = 256;
		this.numberOfHardLinks = size;
		this.hardLinksToAvoidGarbageCollection = new LinkedList();
		this.queueOfGarbageCollectedEntries = new ReferenceQueue();
	}

	@Override
	public String getId() {
		return delegate.getId();
	}

	@Override
	public int getSize() {
		removeGarbageCollectedItems();
		return delegate.getSize();
	}

	public void setSize(int size) {
		this.numberOfHardLinks = size;
	}

	// @Override
	// public void putObject(Object key, Object value) {
	// removeGarbageCollectedItems();
	// delegate.putObject(key, new SoftEntry(key, value, queueOfGarbageCollectedEntries));
	// }

	@Override
	public void putObject(Object key, Object value, Integer time) {
		removeGarbageCollectedItems();
		delegate.putObject(key, new SoftEntry(key, value, queueOfGarbageCollectedEntries));
	}

	@Override
	public Object getObject(Object key) {
		Object result = null;
		@SuppressWarnings("unchecked")
		// assumed delegate cache is totally managed by this cache
		SoftReference softReference = (SoftReference) delegate.getObject(key);
		if (softReference != null) {
			result = softReference.get();
			if (result == null) {
				delegate.removeObject(key);
			} else {
				// See #586 (and #335) modifications need more than a read lock
				synchronized (hardLinksToAvoidGarbageCollection) {
					hardLinksToAvoidGarbageCollection.addFirst(result);
					if (hardLinksToAvoidGarbageCollection.size() > numberOfHardLinks) {
						hardLinksToAvoidGarbageCollection.removeLast();
					}
				}
			}
		}
		return result;
	}

	@Override
	public Object removeObject(Object key) {
		removeGarbageCollectedItems();
		return delegate.removeObject(key);
	}

	@Override
	public void clear() {
		synchronized (hardLinksToAvoidGarbageCollection) {
			hardLinksToAvoidGarbageCollection.clear();
		}
		removeGarbageCollectedItems();
		delegate.clear();
	}

	private void removeGarbageCollectedItems() {
		SoftEntry sv;
		while ((sv = (SoftEntry) queueOfGarbageCollectedEntries.poll()) != null) {
			delegate.removeObject(sv.key);
		}
	}

	private static class SoftEntry extends SoftReference {
		private final Object	key;

		private SoftEntry(Object key, Object value, ReferenceQueue garbageCollectionQueue) {
			super(value, garbageCollectionQueue);
			this.key = key;
		}
	}

}