blob: 76f1e570aceea49799153b2f7b929e2677252a60 [file] [log] [blame]
/**
* Copyright 2011, Big Switch Networks, Inc.
* Originally created by David Erickson, Stanford University
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License. You may obtain
* a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
**/
package net.floodlightcontroller.util;
import java.util.Set;
import java.util.concurrent.ConcurrentMap;
import com.googlecode.concurrentlinkedhashmap.ConcurrentLinkedHashMap;
/**
* The key is any object/hash-code
* The value is time-stamp in milliseconds
* The time interval denotes the interval for which the entry should remain in the hashmap.
* If an entry is present in the Linkedhashmap, it does not mean that it's valid (recently seen)
*
* @param <K> Type of the values in this cache
*/
public class TimedCache<K> {
private final long timeoutInterval; //specified in milliseconds.
private ConcurrentMap<K, Long> cache;
/**
* @param capacity the maximum number of entries in the cache before the
* oldest entry is evicted.
* @param timeToLive specified in milliseconds
*/
public TimedCache(int capacity, int timeToLive) {
cache = new ConcurrentLinkedHashMap.Builder<K, Long>()
.maximumWeightedCapacity(capacity)
.build();
this.timeoutInterval = timeToLive;
}
public long getTimeoutInterval() {
return this.timeoutInterval;
}
/**
* Always try to update the cache and set the last-seen value for this key.
* <p/>
* Return true, if a valid existing field was updated, else return false.
* (note: if multiple threads update simultaneously, one of them will succeed,
* other wills return false)
*
* @param key
* @return boolean
*/
public boolean update(K key) {
long curr = System.currentTimeMillis();
Long prev = cache.putIfAbsent(key, curr);
if (prev == null) {
return false;
}
if (curr - prev > this.timeoutInterval) {
if (cache.replace(key, prev, curr)) {
return false;
}
}
return true;
}
/**
* Gets all the cached entries.
* <p/>
* Modification to the returned set will be reflected to the cache.
*
* @return cached entries
*/
Set<K> getCachedEntries() {
return cache.keySet();
}
}