/** * 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 com.googlecode.concurrentlinkedhashmap.ConcurrentLinkedHashMap; import java.util.concurrent.ConcurrentMap; /** * 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. * * 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 = new Long(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; } }