diff --git a/lib/concurrentlinkedhashmap-lru-1.2.jar b/lib/concurrentlinkedhashmap-lru-1.2.jar new file mode 100644 index 0000000000000000000000000000000000000000..f91d67025ee6b158c476e15a2f1bbda768cb19a6 Binary files /dev/null and b/lib/concurrentlinkedhashmap-lru-1.2.jar differ diff --git a/lib/jython-2.5.2.jar b/lib/jython-2.5.2.jar new file mode 100644 index 0000000000000000000000000000000000000000..3f54290b8ce17d767b1dfebaedbad61133ae1a79 Binary files /dev/null and b/lib/jython-2.5.2.jar differ diff --git a/src/main/java/net/floodlightcontroller/core/IOFSwitch.java b/src/main/java/net/floodlightcontroller/core/IOFSwitch.java index 14daabf1b6047f6b2b425b98edbe5e3993915aba..e1ba7ef84ef32c53068a2e66d646ea6c1b846f2c 100644 --- a/src/main/java/net/floodlightcontroller/core/IOFSwitch.java +++ b/src/main/java/net/floodlightcontroller/core/IOFSwitch.java @@ -24,7 +24,7 @@ import java.util.Map; import java.util.concurrent.Future; import net.floodlightcontroller.core.types.MacVlanPair; -import net.floodlightcontroller.util.TimedHashMap; +import net.floodlightcontroller.util.TimedCache; import org.jboss.netty.channel.Channel; import org.openflow.protocol.OFFeaturesReply; @@ -303,5 +303,5 @@ public interface IOFSwitch { * @param data * @return */ - public TimedHashMap<Long> getTimedCache(); + public TimedCache<Long> getTimedCache(); } diff --git a/src/main/java/net/floodlightcontroller/core/internal/OFSwitchImpl.java b/src/main/java/net/floodlightcontroller/core/internal/OFSwitchImpl.java index 81c76e8b34188749d9b8d7747ed715c65c8bbf34..46a3c9bf91182ec70cabc61929c40bcbaa52951d 100644 --- a/src/main/java/net/floodlightcontroller/core/internal/OFSwitchImpl.java +++ b/src/main/java/net/floodlightcontroller/core/internal/OFSwitchImpl.java @@ -31,7 +31,7 @@ import net.floodlightcontroller.core.FloodlightContext; import net.floodlightcontroller.core.IFloodlightProvider; import net.floodlightcontroller.core.IOFSwitch; import net.floodlightcontroller.core.types.MacVlanPair; -import net.floodlightcontroller.util.TimedHashMap; +import net.floodlightcontroller.util.TimedCache; import org.jboss.netty.channel.Channel; import org.openflow.protocol.OFFeaturesReply; @@ -71,7 +71,7 @@ public class OFSwitchImpl implements IOFSwitch { protected Map<MacVlanPair,Short> macVlanToPortMap; protected Map<Integer,OFStatisticsFuture> statsFutureMap; protected boolean connected; - protected TimedHashMap<Long> timedCache; + protected TimedCache<Long> timedCache; public static IOFSwitchFeatures switchFeatures; @@ -86,7 +86,7 @@ public class OFSwitchImpl implements IOFSwitch { this.switchClusterId = null; this.connected = true; this.statsFutureMap = new ConcurrentHashMap<Integer,OFStatisticsFuture>(); - this.timedCache = new TimedHashMap<Long>( 5*1000 ); // 5 seconds interval + this.timedCache = new TimedCache<Long>(100, 5*1000 ); // 5 seconds interval // Defaults properties for an ideal switch this.setAttribute(PROP_FASTWILDCARDS, (Integer) OFMatch.OFPFW_ALL); @@ -357,7 +357,7 @@ public class OFSwitchImpl implements IOFSwitch { } @Override - public TimedHashMap<Long> getTimedCache() { + public TimedCache<Long> getTimedCache() { return timedCache; } } diff --git a/src/main/java/net/floodlightcontroller/util/TimedCache.java b/src/main/java/net/floodlightcontroller/util/TimedCache.java new file mode 100644 index 0000000000000000000000000000000000000000..ce95c979ed0601d01718d7f6556654075d17044c --- /dev/null +++ b/src/main/java/net/floodlightcontroller/util/TimedCache.java @@ -0,0 +1,90 @@ +/** +* 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 static final long serialVersionUID = 1L; + + private final long timeoutInterval; //specified in milliseconds. + private ConcurrentMap<K, Long> cache; + private long cacheHits; + private long totalHits; + + public TimedCache(int capacity, int timeToLive) { + cache = new ConcurrentLinkedHashMap.Builder<K, Long>() + .maximumWeightedCapacity(capacity) + .build(); + this.timeoutInterval = timeToLive; + this.cacheHits = 0; + this.totalHits = 0; + } + + public long getTimeoutInterval() { + return this.timeoutInterval; + } + + public long getCacheHits() { + return cacheHits; + } + + public long getTotalHits() { + return totalHits; + } + + /** + * 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); + + this.totalHits++; + if (prev == null) { + return false; + } + + if (curr - prev > this.timeoutInterval) { + if (cache.replace(key, prev, curr)) { + return false; + } + } + + this.cacheHits++; + return true; + } +} \ No newline at end of file diff --git a/src/main/java/net/floodlightcontroller/util/TimedHashMap.java b/src/main/java/net/floodlightcontroller/util/TimedHashMap.java deleted file mode 100644 index 4b80b9f79f6269e9e04797d3c4d91a0dbc974b7d..0000000000000000000000000000000000000000 --- a/src/main/java/net/floodlightcontroller/util/TimedHashMap.java +++ /dev/null @@ -1,82 +0,0 @@ -/** -* 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.LinkedHashMap; -import java.util.Map; - - -// 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) - - -public class TimedHashMap<K> extends LinkedHashMap<K, Long> { - - private static final long serialVersionUID = 1L; - - private final long timeoutInterval; //specified in milliseconds. - private long cacheHits = 0; - - public TimedHashMap(int ti) - { - super(); - this.timeoutInterval = ti; - } - - protected boolean removeEldestEntry(Map.Entry<K, Long> eldest) { - return eldest.getValue() < (System.currentTimeMillis() - this.timeoutInterval); - } - - public long getTimeoutInterval() - { - return this.timeoutInterval; - } - - public long getCacheHits() - { - return cacheHits; - } - - /** - * Return true if key is present; otherwise add key to cache - * @param key - * @return - */ - public boolean isPresent(K key) - { - Long old = this.get(key); - Long cur = new Long(System.currentTimeMillis()); - - if (old == null) { - this.put(key, cur); - return false; - } - - if (cur - old > this.timeoutInterval) { - this.remove(key); // this may be unnecessary - this.put(key, cur); - return false; - } - - cacheHits++; - return true; - } -} \ No newline at end of file