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

org.kernelab.basis.HistoryQueueMap Maven / Gradle / Ivy

There is a newer version: 0.0.19-RELEASE
Show newest version
package org.kernelab.basis;

import java.io.Serializable;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.LinkedList;
import java.util.Map;
import java.util.Queue;
import java.util.Set;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;

public class HistoryQueueMap implements Map
{
	public static interface ReserveRule extends Serializable
	{
		public boolean reserve(K key, V value);
	}

	private int						history;

	private Queue				queue;

	private Map				map;

	private ReserveRule		reserve;

	protected final ReadWriteLock	lock	= new ReentrantReadWriteLock();

	public HistoryQueueMap(int history)
	{
		this(history, null);
	}

	public HistoryQueueMap(int history, ReserveRule reserve)
	{
		this(history, reserve, new HashMap());
	}

	public HistoryQueueMap(int history, ReserveRule reserve, Map map)
	{
		this.setHistory(history);
		this.setReserve(reserve);
		this.setMap(map);
		this.setQueue(new LinkedQueue());
	}

	public int clean(boolean reserved)
	{
		this.lock.writeLock().lock();
		try
		{
			return this.truncate(reserved, -1, null).size();
		}
		finally
		{
			this.lock.writeLock().unlock();
		}
	}

	public void clear()
	{
		this.lock.writeLock().lock();
		try
		{
			this.getMap().clear();
		}
		finally
		{
			this.lock.writeLock().unlock();
		}
	}

	public boolean containsKey(Object key)
	{
		this.lock.readLock().lock();
		try
		{
			return this.getMap().containsKey(key);
		}
		finally
		{
			this.lock.readLock().unlock();
		}
	}

	public boolean containsValue(Object value)
	{
		this.lock.readLock().lock();
		try
		{
			return this.getMap().containsValue(value);
		}
		finally
		{
			this.lock.readLock().unlock();
		}
	}

	public Set> entrySet()
	{
		this.lock.readLock().lock();
		try
		{
			return Collections.unmodifiableSet(new LinkedHashSet>(this.getMap().entrySet()));
		}
		finally
		{
			this.lock.readLock().unlock();
		}
	}

	protected Map fetch(int limit, boolean removing, boolean reserved, Map result)
	{
		Iterator iter = this.getQueue().iterator();

		ReserveRule reserve = reserved ? this.getReserve() : null;

		if (result == null)
		{
			result = new LinkedHashMap();
		}

		K key;
		V value;

		int rest = limit;

		while (iter.hasNext() && (rest > 0 || limit < 0))
		{
			key = iter.next();
			value = this.getMap().get(key);

			if (reserve == null || !reserve.reserve(key, value))
			{
				if (removing)
				{
					iter.remove();
					this.getMap().remove(key);
				}
				result.put(key, value);
				rest--;
			}
		}

		return result;
	}

	public V get(Object key)
	{
		this.lock.readLock().lock();
		try
		{
			return this.getMap().get(key);
		}
		finally
		{
			this.lock.readLock().unlock();
		}
	}

	public int getHistory()
	{
		this.lock.readLock().lock();
		try
		{
			return history;
		}
		finally
		{
			this.lock.readLock().unlock();
		}
	}

	protected int getHistory(boolean sync)
	{
		if (sync)
		{
			return this.getHistory();
		}
		else
		{
			return history;
		}
	}

	protected Map getMap()
	{
		return map;
	}

	protected Queue getQueue()
	{
		return queue;
	}

	public ReserveRule getReserve()
	{
		return reserve;
	}

	public boolean isEmpty()
	{
		this.lock.readLock().lock();
		try
		{
			return this.getMap().isEmpty();
		}
		finally
		{
			this.lock.readLock().unlock();
		}
	}

	public Set keySet()
	{
		this.lock.readLock().lock();
		try
		{
			return Collections.unmodifiableSet(new LinkedHashSet(this.getMap().keySet()));
		}
		finally
		{
			this.lock.readLock().unlock();
		}
	}

	public Map look(int limit, boolean reserved, Map result)
	{
		this.lock.readLock().lock();
		try
		{
			return this.fetch(limit, false, reserved, result);
		}
		finally
		{
			this.lock.readLock().unlock();
		}
	}

	public V put(K key, V value)
	{
		this.lock.writeLock().lock();
		try
		{
			if (this.getMap().containsKey(key))
			{
				this.removeFromQueue(key);
			}

			this.getQueue().offer(key);

			V old = this.getMap().put(key, value);

			this.truncateOne(true);

			return old;
		}
		finally
		{
			this.lock.writeLock().unlock();
		}
	}

	public void putAll(Map m)
	{
		this.lock.writeLock().lock();
		try
		{
			this.removeFromQueue(m.keySet());

			this.getQueue().addAll(m.keySet());

			this.getMap().putAll(m);

			this.truncateBatch(true);
		}
		finally
		{
			this.lock.writeLock().unlock();
		}
	}

	public V remove(Object key)
	{
		this.lock.writeLock().lock();
		try
		{
			return this.getMap().remove(key);
		}
		finally
		{
			this.lock.writeLock().unlock();
		}
	}

	protected void removeFromQueue(Collection keys)
	{
		if (!keys.isEmpty())
		{
			Iterator iter = this.getQueue().iterator();

			while (iter.hasNext())
			{
				if (keys.contains(iter.next()))
				{
					iter.remove();
				}
			}
		}
	}

	protected void removeFromQueue(K key)
	{
		Iterator iter = this.getQueue().iterator();

		while (iter.hasNext())
		{
			if (Tools.equals(key, iter.next()))
			{
				iter.remove();
				break;
			}
		}
	}

	public void setHistory(int history)
	{
		this.lock.writeLock().lock();
		try
		{
			this.history = history;
		}
		finally
		{
			this.lock.writeLock().unlock();
		}
	}

	protected void setMap(Map map)
	{
		this.map = map;
	}

	protected void setQueue(Queue queue)
	{
		this.queue = queue;
	}

	public void setReserve(ReserveRule reserve)
	{
		this.reserve = reserve;
	}

	public int size()
	{
		this.lock.readLock().lock();
		try
		{
			return this.getMap().size();
		}
		finally
		{
			this.lock.readLock().unlock();
		}
	}

	public int size(boolean sync)
	{
		if (sync)
		{
			return this.size();
		}
		else
		{
			return this.getMap().size();
		}
	}

	public Map take(int limit, boolean reserved, Map result)
	{
		this.lock.writeLock().lock();
		try
		{
			return this.truncate(reserved, limit, result);
		}
		finally
		{
			this.lock.writeLock().unlock();
		}
	}

	protected Map truncate(boolean reserved, int limit, Map result)
	{
		return this.fetch(limit, true, reserved, result);
	}

	protected Map truncateBatch(boolean reserved)
	{
		int limit = 0;

		if (this.getHistory(false) >= 0 && (limit = this.size(false) - this.getHistory(false)) > 0)
		{
			return this.truncate(reserved, limit, null);
		}
		else
		{
			return Collections.emptyMap();
		}
	}

	protected Map truncateOne(boolean reserved)
	{
		if (this.getHistory(false) >= 0 && this.size(false) - this.getHistory(false) > 0)
		{
			return this.truncate(reserved, 1, null);
		}
		else
		{
			return Collections.emptyMap();
		}
	}

	public Collection values()
	{
		this.lock.readLock().lock();
		try
		{
			return Collections.unmodifiableList(new LinkedList(this.getMap().values()));
		}
		finally
		{
			this.lock.readLock().unlock();
		}
	}
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy