org.ow2.carol.cmi.ha.TOHashTable Maven / Gradle / Ivy
/**
* High Availability Service (HA) for JOnAS
*
* Copyright (C) 2006 Distributed Systems Lab.
* Universidad Polit??cnica de Madrid (Spain)
* Contact: http://lsd.ls.fi.upm.es/lsd
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
* USA
*
* --------------------------------------------------------------------------
* $Id: TOHashTable.java 1293 2007-10-07 09:52:15Z loris $
* --------------------------------------------------------------------------
*/
package org.ow2.carol.cmi.ha;
import java.util.Collection;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import org.ow2.util.log.Log;
import org.ow2.util.log.LogFactory;
public class TOHashTable implements Map {
/**
* Logger.
*/
private static Log logger = LogFactory.getLog(TOHashTable.class);
private int timeout = 600000;
private final ProcessThread processThread;
private final Map map;
public TOHashTable(final int timeout){
map = new ConcurrentHashMap();
this.timeout = timeout*1000;
processThread = new ProcessThread(map);
processThread.setDaemon(true);
processThread.start();
}
public int getTimeout() {
return timeout;
}
public void setTimeout(final int timeout) {
this.timeout = timeout;
}
public V put(final K key, final V o) {
Info i = new Info(o, System.currentTimeMillis() + timeout);
Info previous = map.put(key, i);
if (previous != null) {
return previous.o;
} else {
return null;
}
}
public V get(final Object key) {
Info i = map.get(key);
if (i != null) {
return i.o;
} else {
return null;
}
}
public V remove(final Object key) {
Info i = map.remove(key);
if (i != null) {
return i.o;
} else {
return null;
}
}
public void clear() {
map.clear();
}
public boolean containsKey(final Object key) {
return map.containsKey(key);
}
public boolean containsValue(final Object value) {
throw new UnsupportedOperationException();
}
public Set> entrySet() {
throw new UnsupportedOperationException();
}
public boolean isEmpty() {
return map.isEmpty();
}
public Set keySet() {
return map.keySet();
}
public void putAll(final Map extends K, ? extends V> t) {
throw new UnsupportedOperationException();
}
public int size() {
return map.size();
}
public Collection values() {
throw new UnsupportedOperationException();
}
private class Info {
/**
* The timer
*/
V o;
long timeoutMoment = 0;
/**
* Constructor
* @param key
* @param o
* @param toht
*/
Info(final V o, final long timeoutMoment) {
this.o = o;
this.timeoutMoment = timeoutMoment;
}
}
/**
* This Thread process object in table.
* @author Francisco Perez-Sorrosal (fpsorrosal@[email protected])
* @author Alberto Paz-Jimenez (apaz@[email protected])
*/
class ProcessThread extends Thread {
private volatile Thread test;
private final Map table;
public ProcessThread(final Map table) {
this.table = table;
}
@Override
public void run() {
logger.debug("ProcessMessage thread started");
test = Thread.currentThread();
long currentTime = System.currentTimeMillis();
while (test == Thread.currentThread()) {
int removed = 0;
Iterator i = table.values().iterator();
while(i.hasNext()) {
Info info = i.next();
if (info.timeoutMoment <= currentTime) {
i.remove();
if (logger.isDebugEnabled()) {
removed++;
}
}
}
if (removed > 0) {
logger.debug("Removed: {0} objects from TOHashTable.", removed);
}
// Execute every 60 seconds
synchronized (this) {
try {
wait(60000);
} catch (InterruptedException e) {
test = null;
}
}
}
}
public void stopExecution() {
logger.debug("ProcessMessage thread stoped");
synchronized (this) {
test = null;
notify();
}
}
}
}