diff --git a/src/main/java/net/floodlightcontroller/core/IOFSwitch.java b/src/main/java/net/floodlightcontroller/core/IOFSwitch.java index c020251e1cd7524717b985078e7e279c04fb75f8..14daabf1b6047f6b2b425b98edbe5e3993915aba 100644 --- a/src/main/java/net/floodlightcontroller/core/IOFSwitch.java +++ b/src/main/java/net/floodlightcontroller/core/IOFSwitch.java @@ -24,6 +24,7 @@ import java.util.Map; import java.util.concurrent.Future; import net.floodlightcontroller.core.types.MacVlanPair; +import net.floodlightcontroller.util.TimedHashMap; import org.jboss.netty.channel.Channel; import org.openflow.protocol.OFFeaturesReply; @@ -296,4 +297,11 @@ public interface IOFSwitch { * Clear all flowmods on this switch */ public void clearAllFlowMods(); + + /** + * Return a TimedHashMap associated with the switch + * @param data + * @return + */ + public TimedHashMap<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 3b0fa21dbe39953d0ee7cce6eb87629d0ec6f39b..81c76e8b34188749d9b8d7747ed715c65c8bbf34 100644 --- a/src/main/java/net/floodlightcontroller/core/internal/OFSwitchImpl.java +++ b/src/main/java/net/floodlightcontroller/core/internal/OFSwitchImpl.java @@ -31,6 +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 org.jboss.netty.channel.Channel; import org.openflow.protocol.OFFeaturesReply; @@ -70,6 +71,7 @@ public class OFSwitchImpl implements IOFSwitch { protected Map<MacVlanPair,Short> macVlanToPortMap; protected Map<Integer,OFStatisticsFuture> statsFutureMap; protected boolean connected; + protected TimedHashMap<Long> timedCache; public static IOFSwitchFeatures switchFeatures; @@ -84,6 +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 // Defaults properties for an ideal switch this.setAttribute(PROP_FASTWILDCARDS, (Integer) OFMatch.OFPFW_ALL); @@ -352,4 +355,9 @@ public class OFSwitchImpl implements IOFSwitch { log.error("Failed to clear all flows on switch {} - {}", this, e); } } + + @Override + public TimedHashMap<Long> getTimedCache() { + return timedCache; + } } diff --git a/src/main/java/net/floodlightcontroller/topology/internal/TopologyImpl.java b/src/main/java/net/floodlightcontroller/topology/internal/TopologyImpl.java index 15b1a5ef6608cabfc77c6ca134372e6ac99c8e2d..8cfa8c3bcd98a0622340a80324519604dd3e4eaa 100644 --- a/src/main/java/net/floodlightcontroller/topology/internal/TopologyImpl.java +++ b/src/main/java/net/floodlightcontroller/topology/internal/TopologyImpl.java @@ -215,6 +215,10 @@ public class TopologyImpl implements IOFMessageListener, IOFSwitchListener, public TopologyImpl() { this.lock = new ReentrantReadWriteLock(); this.updates = new LinkedBlockingQueue<Update>(); + this.links = new HashMap<LinkTuple, LinkInfo>(); + this.portLinks = new HashMap<SwitchPortTuple, Set<LinkTuple>>(); + this.switchLinks = new HashMap<IOFSwitch, Set<LinkTuple>>(); + } private void doUpdatesThread() throws InterruptedException { @@ -262,9 +266,6 @@ public class TopologyImpl implements IOFMessageListener, IOFSwitchListener, floodlightProvider.addOFMessageListener(OFType.PACKET_IN, this); floodlightProvider.addOFMessageListener(OFType.PORT_STATUS, this); floodlightProvider.addOFSwitchListener(this); - links = new HashMap<LinkTuple, LinkInfo>(); - portLinks = new HashMap<SwitchPortTuple, Set<LinkTuple>>(); - switchLinks = new HashMap<IOFSwitch, Set<LinkTuple>>(); ScheduledExecutorService ses = floodlightProvider.getScheduledExecutor(); diff --git a/src/main/java/net/floodlightcontroller/util/TimedHashMap.java b/src/main/java/net/floodlightcontroller/util/TimedHashMap.java index fca0e57202e998ccf88f00c1032100b67875f0b3..4b80b9f79f6269e9e04797d3c4d91a0dbc974b7d 100644 --- a/src/main/java/net/floodlightcontroller/util/TimedHashMap.java +++ b/src/main/java/net/floodlightcontroller/util/TimedHashMap.java @@ -25,14 +25,15 @@ import java.util.Map; // 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 +// If an entry is present in the Linkedhashmap, it does not mean that it's valid (recently seen) -public class TimedHashMap<K, V> extends LinkedHashMap<K, V> { +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) { @@ -40,12 +41,42 @@ public class TimedHashMap<K, V> extends LinkedHashMap<K, V> { this.timeoutInterval = ti; } - protected boolean removeEldestEntry(Map.Entry<K,V> eldest) { - return (((Long)eldest.getValue()) < System.currentTimeMillis() - this.timeoutInterval); + 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