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

com.almende.util.ObjectCache Maven / Gradle / Ivy

There is a newer version: 3.1.1
Show newest version
/*
 * Copyright: Almende B.V. (2014), Rotterdam, The Netherlands
 * License: The Apache Software License, Version 2.0
 */
package com.almende.util;

import java.util.ArrayList;
import java.util.Map;
import java.util.SortedSet;
import java.util.TreeSet;
import java.util.concurrent.ConcurrentHashMap;

/**
 * The Class ObjectCache.
 */
public class ObjectCache {
	private int								maxSize	= 1000;
	private Map>		cache	= new ConcurrentHashMap>(
															maxSize);
	private SortedSet>			scores	= new TreeSet>();
	private static Map	caches	= new ConcurrentHashMap();
	
	/**
	 * Instantiates a new object cache.
	 * 
	 * @param label
	 *            the label
	 * @param config
	 *            the config
	 */
	protected ObjectCache(final String label, final Map config) {
		if (config != null) {
			configCache(config);
		}
		caches.put(label, this);
	}
	
	/**
	 * Instantiates a new object cache.
	 * 
	 * @param label
	 *            the label
	 */
	protected ObjectCache(final String label) {
		this(label, null);
	}
	
	/**
	 * Gets the.
	 * 
	 * @param label
	 *            the label
	 * @return the object cache
	 */
	public static ObjectCache get(final String label) {
		if (!caches.containsKey(label)) {
			new ObjectCache(label);
		}
		return caches.get(label);
	}
	
	/**
	 * Reinitialize cache, using given configuration. (currently only
	 * "ObjectCache"."maxSize" is used from config)
	 * 
	 * @param config
	 *            the config
	 */
	public void configCache(final Map config) {
		synchronized (cache) {
			final Integer max = (Integer) config.get("maxSize");
			if (max != null) {
				maxSize = max;
			}
			cache = new ConcurrentHashMap>(maxSize + 1);
			scores = new TreeSet>();
		}
	}
	
	/**
	 * Get value instance from cache, if exiting. Returns null if no va;ue is
	 * stored in cache.
	 * 
	 * @param 
	 *            the generic type
	 * @param key
	 *            the key
	 * @param type
	 *            the type
	 * @return the t
	 */
	public  T get(final String key, final Class type) {
		final MetaInfo result = cache.get(key);
		if (result != null
				&& type.isAssignableFrom(result.getValue().getClass())) {
			result.use();
			return type.cast(result.getValue());
		}
		return null;
	}
	
	/**
	 * Contains key.
	 * 
	 * @param key
	 *            the key
	 * @return true, if successful
	 */
	public boolean containsKey(final String key) {
		return cache.containsKey(key);
	}
	
	/**
	 * Put agent instance into the cache from later retrieval. Runs eviction
	 * policy after entry of agent.
	 * 
	 * @param 
	 *            the generic type
	 * @param key
	 *            the key
	 * @param value
	 *            the value
	 */
	public  void put(final String key, final T value) {
		final MetaInfo entry = new MetaInfo(key, value);
		cache.put(key, entry);
		final int overshoot = cache.size() - maxSize;
		if (overshoot > 0) {
			evict(overshoot);
		}
		scores.add(entry);
	}
	
	/**
	 * Evict.
	 * 
	 * @param amount
	 *            the amount
	 */
	protected void evict(final int amount) {
		final ArrayList> toEvict = new ArrayList>(
				amount);
		if (scores.size() <= amount) {
			cache.clear();
			scores.clear();
			return;
		}
		for (int i = 0; i < amount; i++) {
			if (scores.size() > 0) {
				final MetaInfo entry = scores.first();
				toEvict.add(entry);
				scores.remove(entry);
			}
		}
		for (final MetaInfo entry : toEvict) {
			cache.remove(entry.getKey());
		}
	}
	
	/**
	 * Remove specific agent from cache.
	 * 
	 * @param key
	 *            the key
	 */
	public void delete(final String key) {
		final MetaInfo item = cache.remove(key);
		if (item != null) {
			scores.remove(item);
		}
	}
	
	/**
	 * Size.
	 * 
	 * @return the int
	 */
	public int size() {
		return cache.size();
	}
	
	/**
	 * Checks if is empty.
	 * 
	 * @return true, if is empty
	 */
	public boolean isEmpty() {
		return cache.isEmpty();
	}
	
	/**
	 * Clear.
	 */
	public void clear() {
		cache.clear();
	}
	
}

/**
 * The Class MetaInfo.
 * 
 * @param 
 *            the generic type
 */
class MetaInfo implements Comparable> {
	private final String	key;
	private T				value;
	private int				count	= 0;
	private final long		created;
	
	/**
	 * Instantiates a new meta info.
	 * 
	 * @param key
	 *            the key
	 * @param value
	 *            the value
	 */
	public MetaInfo(final String key, final T value) {
		created = System.currentTimeMillis();
		this.key = key;
		this.value = value;
	}
	
	/**
	 * Use.
	 */
	public void use() {
		count++;
	}
	
	/**
	 * Gets the key.
	 * 
	 * @return the key
	 */
	public String getKey() {
		return this.key;
	}
	
	/**
	 * Gets the age.
	 * 
	 * @return the age
	 */
	public long getAge() {
		return (System.currentTimeMillis() - created);
	}
	
	/**
	 * Score.
	 * 
	 * @return the double
	 */
	public double score() {
		if (getAge() == 0) {
			return count / 0.001;
		}
		return count / getAge();
	}
	
	/**
	 * Gets the value.
	 * 
	 * @return the value
	 */
	public T getValue() {
		return value;
	}
	
	/**
	 * Sets the value.
	 * 
	 * @param value
	 *            the new value
	 */
	public void setValue(final T value) {
		this.value = value;
	}
	
	/*
	 * (non-Javadoc)
	 * 
	 * @see java.lang.Comparable#compareTo(java.lang.Object)
	 */
	@Override
	public int compareTo(final MetaInfo o) {
		return Double.compare(score(), o.score());
	}
	
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy