X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=blobdiff_plain;ds=sidebyside;f=opendaylight%2Fsal%2Fapi%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fcontroller%2Fsal%2Fmatch%2FMatch.java;h=a00c3dcb3422d6e20c619bd35d616b62fb6bbab3;hb=531621aac4cff9d39cbd8668a53bdeba8a0e6d81;hp=30c25af57f688539c7bf569aa4ecccf0f804af26;hpb=144cfa4b4a926b7d0c3d5f60ada050c609762699;p=controller.git diff --git a/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/match/Match.java b/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/match/Match.java index 30c25af57f..a00c3dcb34 100644 --- a/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/match/Match.java +++ b/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/match/Match.java @@ -1,4 +1,3 @@ - /* * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved. * @@ -15,17 +14,22 @@ import java.net.Inet6Address; import java.net.InetAddress; import java.util.ArrayList; import java.util.Arrays; +import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Map.Entry; +import java.util.TreeMap; +import java.util.concurrent.ConcurrentMap; +import java.util.concurrent.ConcurrentHashMap; import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlElement; import javax.xml.bind.annotation.XmlRootElement; +import org.opendaylight.controller.sal.core.Property; import org.opendaylight.controller.sal.utils.EtherTypes; import org.opendaylight.controller.sal.utils.IPProtocols; import org.opendaylight.controller.sal.utils.NetUtils; @@ -51,7 +55,9 @@ public class Match implements Cloneable, Serializable { reversableMatches = Collections.unmodifiableMap(map); } private Map fields; - private int matches; // concise way to tell which fields the match is set for (may remove if not needed) + private int matches; // concise way to tell which fields the match + // is set for (may remove if not needed) + private ConcurrentMap props; public Match() { fields = new HashMap(); @@ -63,6 +69,81 @@ public class Match implements Cloneable, Serializable { matches = match.matches; } + /** + * Gets the list of metadata currently registered with this match + * + * @return List of metadata currently registered + */ + public List getMetadatas() { + if (this.props != null) { + // Return all the values in the map + Collection res = this.props.values(); + if (res == null) { + return Collections.emptyList(); + } + return new ArrayList(res); + } + return Collections.emptyList(); + } + + /** + * Gets the metadata registered with a name if present + * + * @param name the name of the property to be extracted + * + * @return List of metadata currently registered + */ + public Property getMetadata(String name) { + if (name == null) { + return null; + } + if (this.props != null) { + // Return the Property associated to the name + return this.props.get(name); + } + return null; + } + + /** + * Sets the metadata associated to a name. If the name or prop is NULL, + * an exception NullPointerException will be raised. + * + * @param name the name of the property to be set + * @param prop, property to be set + */ + public void setMetadata(String name, Property prop) { + if (this.props == null) { + props = new ConcurrentHashMap(); + } + + if (this.props != null) { + this.props.put(name, prop); + } + } + + /** + * Remove the metadata associated to a name. If the name is NULL, + * nothing will be removed. + * + * @param name the name of the property to be set + * @param prop, property to be set + * + * @return List of metadata currently registered + */ + public void removeMetadata(String name) { + if (this.props == null) { + return; + } + + if (this.props != null) { + this.props.remove(name); + } + // It's intentional to keep the this.props still allocated + // till the parent data structure will be alive, so to avoid + // unnecessary allocation/deallocation, even if it's holding + // nothing + } + /** * Generic setter for frame/packet/message's header fields against which to match * Note: For MAC addresses, please pass the cloned value to this function @@ -354,7 +435,7 @@ public class Match implements Cloneable, Serializable { .getSubnetMaskLength(thisMask); int otherMaskLen = (otherMask == null) ? ((otherAddress instanceof Inet4Address) ? 32 : 128) : NetUtils .getSubnetMaskLength(otherMask); - if (otherMaskLen < thisMaskLen) { + if (thisMaskLen < otherMaskLen) { intersection.setField(new MatchField(type, NetUtils.getSubnetPrefix(otherAddress, otherMaskLen), otherMask)); } else { @@ -441,7 +522,20 @@ public class Match implements Cloneable, Serializable { public int hashCode() { final int prime = 31; int result = 1; - result = prime * result + ((fields == null) ? 0 : fields.hashCode()); + if (this.fields == null) { + result = prime * result; + } else { + // use a tree map as the order of hashMap is not guaranteed. + // 2 Match objects with fields in different order are still equal. + // Hence the hashCode should be the same too. + TreeMap tm = new TreeMap(this.fields); + for (MatchType field : tm.keySet()) { + MatchField f = tm.get(field); + int fieldHashCode = (field==null ? 0 : field.calculateConsistentHashCode()) ^ + (f==null ? 0 : f.hashCode()); + result = prime * result + fieldHashCode; + } + } result = prime * result + matches; return result; } @@ -473,6 +567,13 @@ public class Match implements Cloneable, Serializable { @Override public String toString() { - return "Match[" + fields.values() + "]"; + StringBuilder builder = new StringBuilder(); + builder.append("Match [fields="); + builder.append(fields); + builder.append(", matches="); + builder.append(matches); + builder.append("]"); + return builder.toString(); } + }