chris@1: /*
chris@1: * SONEWS News Server
chris@1: * see AUTHORS for the list of contributors
chris@1: *
chris@1: * This program is free software: you can redistribute it and/or modify
chris@1: * it under the terms of the GNU General Public License as published by
chris@1: * the Free Software Foundation, either version 3 of the License, or
chris@1: * (at your option) any later version.
chris@1: *
chris@1: * This program is distributed in the hope that it will be useful,
chris@1: * but WITHOUT ANY WARRANTY; without even the implied warranty of
chris@1: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
chris@1: * GNU General Public License for more details.
chris@1: *
chris@1: * You should have received a copy of the GNU General Public License
chris@1: * along with this program. If not, see .
chris@1: */
chris@1:
chris@1: package org.sonews.util;
chris@1:
chris@1: import java.util.HashMap;
chris@1: import java.util.HashSet;
chris@1: import java.util.Map;
chris@1: import java.util.Set;
chris@1: import java.util.concurrent.ConcurrentHashMap;
chris@1:
chris@1: /**
chris@1: * Implementation of a Map that will loose its stored values after a
chris@1: * configurable amount of time.
chris@1: * This class may be used to cache config values for example.
chris@1: * @author Christian Lins
chris@1: * @since sonews/0.5.0
chris@1: */
cli@37: public class TimeoutMap extends ConcurrentHashMap
chris@1: {
chris@1:
cli@37: private static final long serialVersionUID = 453453467700345L;
cli@37: private int timeout = 60000; // 60 sec
cli@37: private transient Map timeoutMap = new HashMap();
chris@1:
cli@37: /**
cli@37: * Constructor.
cli@37: * @param timeout Timeout in milliseconds
cli@37: */
cli@37: public TimeoutMap(final int timeout)
cli@37: {
cli@37: this.timeout = timeout;
cli@37: }
chris@1:
cli@37: /**
cli@37: * Uses default timeout (60 sec).
cli@37: */
cli@37: public TimeoutMap()
cli@37: {
cli@37: }
chris@1:
cli@37: /**
cli@37: *
cli@37: * @param key
cli@37: * @return true if key is still valid.
cli@37: */
cli@37: protected boolean checkTimeOut(Object key)
cli@37: {
cli@37: synchronized (this.timeoutMap) {
cli@37: if (this.timeoutMap.containsKey(key)) {
cli@37: long keytime = this.timeoutMap.get(key);
cli@37: if ((System.currentTimeMillis() - keytime) < this.timeout) {
cli@37: return true;
cli@37: } else {
cli@37: remove(key);
cli@37: return false;
cli@37: }
cli@37: } else {
cli@37: return false;
cli@37: }
cli@37: }
cli@37: }
chris@1:
cli@37: @Override
cli@37: public boolean containsKey(Object key)
cli@37: {
cli@37: return checkTimeOut(key);
cli@37: }
cli@37:
cli@37: @Override
cli@37: public synchronized V get(Object key)
cli@37: {
cli@37: if (checkTimeOut(key)) {
cli@37: return super.get(key);
cli@37: } else {
cli@37: return null;
cli@37: }
cli@37: }
cli@37:
cli@37: @Override
cli@37: public V put(K key, V value)
cli@37: {
cli@37: synchronized (this.timeoutMap) {
cli@37: removeStaleKeys();
cli@37: this.timeoutMap.put(key, System.currentTimeMillis());
cli@37: return super.put(key, value);
cli@37: }
cli@37: }
cli@37:
cli@37: /**
cli@37: * @param arg0
cli@37: * @return
cli@37: */
cli@37: @Override
cli@37: public V remove(Object arg0)
cli@37: {
cli@37: synchronized (this.timeoutMap) {
cli@37: this.timeoutMap.remove(arg0);
cli@37: V val = super.remove(arg0);
cli@37: return val;
cli@37: }
cli@37: }
cli@37:
cli@37: protected void removeStaleKeys()
cli@37: {
cli@37: synchronized (this.timeoutMap) {
cli@37: Set