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

step.grid.ExpiringMap Maven / Gradle / Ivy

The newest version!
/*******************************************************************************
 * Copyright (C) 2020, exense GmbH
 *  
 * This file is part of STEP
 *  
 * STEP is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *  
 * STEP 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 Affero General Public License for more details.
 *  
 * You should have received a copy of the GNU Affero General Public License
 * along with STEP.  If not, see .
 ******************************************************************************/
package step.grid;

import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Consumer;

import org.jvnet.hk2.internal.Closeable;

public class ExpiringMap implements Map, Closeable{
	
	long keepaliveTimeout;
	
	Timer keepaliveTimeoutCheckTimer;
	
	private ConcurrentHashMap map = new ConcurrentHashMap<>();
	
	private class Wrapper {
		
		volatile long lasttouch;
		
		final V value;

		public Wrapper(V value) {
			super();
			this.value = value;
			lasttouch = System.currentTimeMillis();
		}
	}

	public ExpiringMap(long keepaliveTimeout) {
		this(keepaliveTimeout, keepaliveTimeout/10);
	}
	
	public ExpiringMap(long keepaliveTimeout, long checkIntervalMs) {
		super();
		
		this.keepaliveTimeout = keepaliveTimeout;
		
		keepaliveTimeoutCheckTimer = new Timer();
		keepaliveTimeoutCheckTimer.schedule(new TimerTask() {
			@Override
			public void run() {
				try {
					keepaliveTimeoutCheck();
				} catch (Exception e) {
					
				}
			}
		}, checkIntervalMs,checkIntervalMs);
	}
	
	private synchronized void keepaliveTimeoutCheck() {
		if(keepaliveTimeout>0) {
			long now = System.currentTimeMillis();
			List expired = new LinkedList<>();
			Set.Wrapper>> set = map.entrySet();
			for(Map.Entry.Wrapper> entry:set) {
				if(entry.getValue().lasttouch+keepaliveTimeout m) {
		throw new RuntimeException("not implemented");
	}

	@Override
	public synchronized void clear() {
		map.clear();
	}

	@Override
	public Set keySet() {
		return map.keySet();
	}

	@Override
	public Collection values() {
		List values = new ArrayList<>();
		for(ExpiringMap.Wrapper entry:map.values()) {
			values.add(entry.value);
		}
		return values;
	}

	@Override
	public Set> entrySet() {
		Set> result = new HashSet<>();
		for(java.util.Map.Entry.Wrapper> e:map.entrySet()) {
			result.add(new Entry(e.getKey(), e.getValue().value));
		}
		return result;
	}
	
	private class Entry implements java.util.Map.Entry {
		T key;
		
		V value;
		
		public Entry(T key, V value) {
			super();
			this.key = key;
			this.value = value;
		}

		@Override
		public T getKey() {
			return key;
		}

		@Override
		public V getValue() {
			return value;
		}

		@Override
		public V setValue(V value) {
			throw new RuntimeException("Not implemented");
		}
	}

	@Override
	public boolean close() {
		keepaliveTimeoutCheckTimer.cancel();
		return true;
	}
	
	public synchronized void putOrTouch(T key, V value) {
		if(containsKey(key)) {
			touch(key);
		} else {
			put(key, value);
		}
	}
	
	public synchronized void touch(T key) {
		Wrapper v = map.get(key);
		if(v!=null) {
			v.lasttouch = System.currentTimeMillis();
		}
	}

	@Override
	public boolean isClosed() {
		return false;
	}

	private Consumer> expiryCallback;

	public void setExpiryCallback(Consumer> expiryCallback) {
		this.expiryCallback = expiryCallback;
	}

	private void notifyExpiry(List values) {
		if (expiryCallback != null) {
			expiryCallback.accept(values);
		}
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy