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

org.jgroups.util.SuppressCache Maven / Gradle / Ivy

package org.jgroups.util;

import java.util.Collection;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;

/**
 * Cache which keeps a timestamp and counter for every key. When a timestamp has expired (based on an expiry time), the
 * corresponding key is removed.

* This cache is mainly used to suppress identical warning messages (in TP), e.g. if we get 1000 warnings about reception * of messages from P (who's not in our cluster), we can print such a message only every 60 seconds (expiry time = 60 secs). * @author Bela Ban * @since 3.2 */ public class SuppressCache { protected final ConcurrentMap map=new ConcurrentHashMap<>(); protected final T NULL_KEY=(T)new Object(); /** * Adds a new key to the hashmap, or updates the Value associated with the existing key if present. If expiry_time * is greater than the age of the Value, the key will be removed. * @param key The key * @param expiry_time Expiry time (in ms) * @return Null if the key was present and not expired, or the Value associated with the existing key * (its count incremented) */ public Value putIfAbsent(T key, long expiry_time) { if(key == null) key=NULL_KEY; Value val=map.get(key); if(val == null) { val=new Value(); Value existing=map.putIfAbsent(key, val); if(existing == null) return val; val=existing; } // key already exists if(val.update().age() > expiry_time) { map.remove(key); map.putIfAbsent(key, new Value()); return val; } return null; } public void clear() {map.clear();} public void retainAll(Collection list) { if(list != null) map.keySet().retainAll(list); } public void removeAll(Collection list) { if(list != null) map.keySet().removeAll(list); } public void removeExpired(long expiry_time) { map.entrySet().stream().filter(entry -> entry.getValue().age() >= expiry_time).forEach(entry -> map.remove(entry.getKey())); } /** Returns the total count of all values */ public int size() { int count=0; for(Value val: map.values()) count+=val.count(); return count; } public String toString() { StringBuilder sb=new StringBuilder(); for(Map.Entry entry: map.entrySet()) { sb.append(entry.getKey()).append(": ").append(entry.getValue()).append("\n"); } return sb.toString(); } public static final class Value { public Value() { this.timestamp=System.currentTimeMillis(); this.count=1; } protected final long timestamp; // time of last update protected int count; // number of accesses since last update public long age() {return System.currentTimeMillis() - timestamp;} public synchronized Value update() {count++; return this;} public int count() {return count;} public String toString() {return count + " update(s) in " + age() + " ms";} } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy