+ protected static boolean layer3MatchEquals(Layer3Match statsLayer3Match, Layer3Match storedLayer3Match){
+ boolean verdict = true;
+ if(statsLayer3Match instanceof Ipv4Match && storedLayer3Match instanceof Ipv4Match){
+ Ipv4Match statsIpv4Match = (Ipv4Match)statsLayer3Match;
+ Ipv4Match storedIpv4Match = (Ipv4Match)storedLayer3Match;
+
+ if (verdict) {
+ verdict = compareNullSafe(
+ storedIpv4Match.getIpv4Destination(), statsIpv4Match.getIpv4Destination());
+ }
+ if (verdict) {
+ verdict = compareNullSafe(
+ statsIpv4Match.getIpv4Source(), storedIpv4Match.getIpv4Source());
+ }
+ } else {
+ Boolean nullCheckOut = checkNullValues(storedLayer3Match, statsLayer3Match);
+ if (nullCheckOut != null) {
+ verdict = nullCheckOut;
+ } else {
+ verdict = storedLayer3Match.equals(statsLayer3Match);
+ }
+ }
+
+ return verdict;
+ }
+
+ private static boolean compareNullSafe(Ipv4Prefix statsIpv4, Ipv4Prefix storedIpv4) {
+ boolean verdict = true;
+ Boolean checkDestNullValuesOut = checkNullValues(storedIpv4, statsIpv4);
+ if (checkDestNullValuesOut != null) {
+ verdict = checkDestNullValuesOut;
+ } else if(!IpAddressEquals(statsIpv4, storedIpv4)){
+ verdict = false;
+ }
+
+ return verdict;
+ }
+
+ private static Boolean checkNullValues(Object v1, Object v2) {
+ Boolean verdict = null;
+ if (v1 == null && v2 != null) {
+ verdict = Boolean.FALSE;
+ } else if (v1 != null && v2 == null) {
+ verdict = Boolean.FALSE;
+ } else if (v1 == null && v2 == null) {
+ verdict = Boolean.TRUE;
+ }
+
+ return verdict;
+ }
+
+ /**
+ * TODO: why don't we use the default Ipv4Prefix.equals()?
+ *
+ * @param statsIpAddress
+ * @param storedIpAddress
+ * @return true if IPv4prefixes equals
+ */
+ private static boolean IpAddressEquals(Ipv4Prefix statsIpAddress, Ipv4Prefix storedIpAddress) {
+ IntegerIpAddress statsIpAddressInt = StrIpToIntIp(statsIpAddress.getValue());
+ IntegerIpAddress storedIpAddressInt = StrIpToIntIp(storedIpAddress.getValue());
+
+ if(IpAndMaskBasedMatch(statsIpAddressInt,storedIpAddressInt)){