Hey there,

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]

Reply via email to