Thanks for all the feedback! Ideally, I think this makes the most sense as a Map --since it's most common use cases are as a Map-- and the javadoc would spell out usage scenarios and challenges (something I will work on).
I've changed two points: TimedMapKey is now private and the backing store is no longer synchronized (as per Arun's suggestions). Synchronization can be left to the client developer.
Even though I wouldn't want to have client code accessing entries via iterator in normal usage, I don't think calling keySet() should throw an UnsupportedOperationException since examining the keySet of such a map could be very useful in debugging caching issues.
Thanks,
-Joe
Joseph Rosenblum | 25th Street Networks Easy, Reliable Web Hosting @ http://www.25thstreet.net/
package net.twentyfifth.util;
import java.util.*;
/**
* This class will expire the keys in a given map after the interval
* specified in the constructor. Note: the behavior of this class is such
* that if you configure a TimerMap with a 5 minute timeout, and if 4:59
* after you add a certain key, you re-add a duplicate of that key, the
* original TimerTask to remove the key will run 1 second later (and then
* again 5 minutes later).
*
* @author Joseph Rosenblum <[EMAIL PROTECTED]>
*/
public class TimerMap implements Map {
protected final long delay;
private final Map timerMap = new HashMap();
private Timer timer;
public TimerMap(long delay) {
this.delay = delay;
timer = new Timer();
}
public void finalize() {
timer.cancel();
}
public long getDelay(Object key) {
return delay;
}
public int size() {
return this.timerMap.size();
}
public boolean isEmpty() {
return this.timerMap.isEmpty();
}
public boolean containsKey(Object key) {
return this.timerMap.containsKey(key);
}
public boolean containsValue(Object value) {
return this.timerMap.containsValue(value);
}
public Object get(Object key) {
return this.timerMap.get(key);
}
public Object put(Object key, Object value) {
Object prevKey = this.timerMap.put(key, value);
timer.schedule(new TimedMapKey(key), delay);
return prevKey;
}
public Object remove(Object key) {
return this.timerMap.remove(key);
}
public void putAll(Map t) {
Iterator i = t.keySet().iterator();
while (i.hasNext()) {
Object key = i.next();
Object val = t.get(key);
this.put(key, val);
}
}
public void clear() {
}
public Set keySet() {
return this.timerMap.keySet();
}
public Collection values() {
return this.timerMap.values();
}
public Set entrySet() {
return this.timerMap.entrySet();
}
/**
* Basically wraps map keys in a TimerTask that
* will remove them from the timerMap after the delay
* interval has expired.
*/
private final class TimedMapKey extends TimerTask {
private final Object key;
TimedMapKey(Object key) {
this.key = key;
}
public void run() {
timerMap.remove(key);
}
}
}
--------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
