package eu.hgross.blaubot.core.acceptor.discovery;
import net.jodah.expiringmap.ExpirationPolicy;
import net.jodah.expiringmap.ExpiringMap;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import eu.hgross.blaubot.util.Log;
/**
* Helper to determine if an object is alive or dead. Can be used for keepAlive purposes as well as
* a seen cache for SDP lookups or similar use cases.
*
* @author Henning Gross {@literal (mail.to@henning-gross.de)}
*/
public class TimeoutList<T> {
private static final String LOG_TAG = "TimeoutList";
private static final boolean DO_LOG = false;
private ExpiringMap<T, Long> devicesMap;
/**
* @param timeout the timeout after which a device is assumed to be dead
*/
public TimeoutList(long timeout) {
this.devicesMap = ExpiringMap.builder()
.expiration(timeout, TimeUnit.MILLISECONDS)
.expirationPolicy(ExpirationPolicy.CREATED)
.build();
}
/**
* Reports an item as alive.
*
* @param item the item to be reported as alive
*/
public void report(T item) {
long seenAliveTimestamp = System.currentTimeMillis();
if (DO_LOG && Log.logDebugMessages()) {
Log.d(LOG_TAG, item + " reported");
}
Long prev = devicesMap.put(item, seenAliveTimestamp);
if (prev != null && prev.equals(item)) {
devicesMap.resetExpiration(item);
}
}
/**
* Removes an item from the alive list.
*
* @param item the item that is no longer alive.
*/
public void remove(T item) {
if (DO_LOG && Log.logDebugMessages()) {
Log.d(LOG_TAG, item + " removed");
}
devicesMap.remove(item);
}
/**
* Checks whether an item is considered alive
*
* @param item the item to check for
* @return true, if item is alive
*/
public boolean contains(T item) {
return devicesMap.containsKey(item);
}
/**
* Returns a list (copy) of alive items.
*
* @return the list of alive items
*/
public Set<T> getItems() {
return new HashSet<>(devicesMap.keySet());
}
}