[ONOS-3833] Added data structure to store load balance path info

Change-Id: Icf73a7c91652c2532db889fb4df70232a16650a2
diff --git a/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/DefaultFlowClassifier.java b/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/DefaultFlowClassifier.java
index 7915ce0..ce27fc7 100644
--- a/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/DefaultFlowClassifier.java
+++ b/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/DefaultFlowClassifier.java
@@ -15,11 +15,13 @@
  */
 package org.onosproject.vtnrsc;
 
+import static com.google.common.base.Preconditions.checkNotNull;
+
 import java.util.Objects;
+
 import org.onlab.packet.IpPrefix;
 
 import com.google.common.base.MoreObjects;
-import static com.google.common.base.Preconditions.checkNotNull;
 
 /**
  * Provides Default flow classifier.
diff --git a/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/DefaultPortChain.java b/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/DefaultPortChain.java
index 89b94b3..d2c2e2e 100644
--- a/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/DefaultPortChain.java
+++ b/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/DefaultPortChain.java
@@ -18,10 +18,16 @@
 import static com.google.common.base.MoreObjects.toStringHelper;
 import static com.google.common.base.Preconditions.checkNotNull;
 
+import java.util.Iterator;
 import java.util.List;
+import java.util.Map;
 import java.util.Objects;
+import java.util.Optional;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
 
 import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableSet;
 
 /**
  * Implementation of port chain.
@@ -35,6 +41,9 @@
     private final List<PortPairGroupId> portPairGroupList;
     private final List<FlowClassifierId> flowClassifierList;
 
+    private final Map<FiveTuple, LoadBalanceId> sfcLoadBalanceIdMap = new ConcurrentHashMap<>();
+    private final Map<LoadBalanceId, List<PortPairId>> sfcLoadBalancePathMap = new ConcurrentHashMap<>();
+
     /**
      * Default constructor to create port chain.
      *
@@ -58,6 +67,23 @@
         this.flowClassifierList = flowClassifierList;
     }
 
+    /**
+     * Match for two given paths.
+     *
+     * @param path1 path of sfc
+     * @param path2 path of sfc
+     * @return true if the given path are same false otherwise
+     */
+    private boolean comparePath(List<PortPairId> path1, List<PortPairId> path2) {
+        Iterator it = path1.iterator();
+        for (PortPairId portPairId: path2) {
+            if (!portPairId.equals(it.next())) {
+                return false;
+            }
+        }
+        return true;
+    }
+
     @Override
     public PortChainId portChainId() {
         return portChainId;
@@ -89,6 +115,47 @@
     }
 
     @Override
+    public void addLoadBalancePath(FiveTuple fiveTuple, LoadBalanceId id,
+                                   List<PortPairId> path) {
+        this.sfcLoadBalanceIdMap.put(fiveTuple, id);
+        this.sfcLoadBalancePathMap.put(id, path);
+    }
+
+    @Override
+    public LoadBalanceId getLoadBalanceId(FiveTuple fiveTuple) {
+        return this.sfcLoadBalanceIdMap.get(fiveTuple);
+    }
+
+    @Override
+    public Set<FiveTuple> getLoadBalanceIdMapKeys() {
+        return ImmutableSet.copyOf(sfcLoadBalanceIdMap.keySet());
+    }
+
+    @Override
+    public List<PortPairId> getLoadBalancePath(LoadBalanceId id) {
+        return ImmutableList.copyOf(this.sfcLoadBalancePathMap.get(id));
+    }
+
+    @Override
+    public List<PortPairId> getLoadBalancePath(FiveTuple fiveTuple) {
+        return ImmutableList.copyOf(this.sfcLoadBalancePathMap.get(this.sfcLoadBalanceIdMap.get(fiveTuple)));
+    }
+
+    @Override
+    public Optional<LoadBalanceId> matchPath(List<PortPairId> path) {
+
+        LoadBalanceId id = null;
+        for (Map.Entry<LoadBalanceId, List<PortPairId>> entry : sfcLoadBalancePathMap.entrySet()) {
+            List<PortPairId> tempPath = entry.getValue();
+            if (comparePath(path, tempPath)) {
+                id = entry.getKey();
+                break;
+            }
+        }
+        return Optional.of(id);
+    }
+
+    @Override
     public int hashCode() {
         return Objects.hash(portChainId, tenantId, name, description,
                             portPairGroupList, flowClassifierList);
diff --git a/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/DefaultPortPairGroup.java b/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/DefaultPortPairGroup.java
index 877cc6c..d455ff3 100644
--- a/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/DefaultPortPairGroup.java
+++ b/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/DefaultPortPairGroup.java
@@ -19,7 +19,9 @@
 import static com.google.common.base.Preconditions.checkNotNull;
 
 import java.util.List;
+import java.util.Map;
 import java.util.Objects;
+import java.util.concurrent.ConcurrentHashMap;
 
 import com.google.common.collect.ImmutableList;
 
@@ -33,6 +35,7 @@
     private final String name;
     private final String description;
     private final List<PortPairId> portPairList;
+    private final Map<PortPairId, Integer> portPairLoadMap;
 
     /**
      * Default constructor to create Port Pair Group.
@@ -52,6 +55,10 @@
         this.name = name;
         this.description = description;
         this.portPairList = portPairList;
+        portPairLoadMap = new ConcurrentHashMap<>();
+        for (PortPairId portPairId : portPairList) {
+            portPairLoadMap.put(portPairId, new Integer(0));
+        }
     }
 
     @Override
@@ -80,6 +87,18 @@
     }
 
     @Override
+    public void addLoad(PortPairId portPairId) {
+        int load = portPairLoadMap.get(portPairId);
+        load = load + 1;
+        portPairLoadMap.put(portPairId, new Integer(load));
+    }
+
+    @Override
+    public int getLoad(PortPairId portPairId) {
+        return portPairLoadMap.get(portPairId);
+    }
+
+    @Override
     public int hashCode() {
         return Objects.hash(portPairGroupId, tenantId, name, description,
                             portPairList);
diff --git a/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/PortChain.java b/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/PortChain.java
index d147eaa..ba87010 100644
--- a/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/PortChain.java
+++ b/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/PortChain.java
@@ -16,6 +16,8 @@
 package org.onosproject.vtnrsc;
 
 import java.util.List;
+import java.util.Optional;
+import java.util.Set;
 
 /**
  * Abstraction of an entity providing Port Chain information.
@@ -70,6 +72,55 @@
     List<FlowClassifierId> flowClassifiers();
 
     /**
+     * Adds a new load balanced path.
+     *
+     * @param fiveTuple five tuple from the packet
+     * @param id load balance path identifier
+     * @param path load balanced path of list of port pairs
+     */
+    void addLoadBalancePath(FiveTuple fiveTuple, LoadBalanceId id,
+                            List<PortPairId> path);
+
+    /**
+     * Get the load balance id from five tuple.
+     *
+     * @param fiveTuple five tuple from the packet
+     * @return load balance identifier for the given packet
+     */
+    LoadBalanceId getLoadBalanceId(FiveTuple fiveTuple);
+
+    /**
+     * Get the keys set from load balanced id map.
+     *
+     * @return set of five tuple info
+     */
+    Set<FiveTuple> getLoadBalanceIdMapKeys();
+
+    /**
+     * Get the load balanced path from load balance Id.
+     *
+     * @param id load balance id.
+     * @return path containing list of port pairs
+     */
+    List<PortPairId> getLoadBalancePath(LoadBalanceId id);
+
+    /**
+     * Get the load balanced path from five tuple.
+     *
+     * @param fiveTuple five tuple from the packet
+     * @return path containing list of port pairs
+     */
+    List<PortPairId> getLoadBalancePath(FiveTuple fiveTuple);
+
+    /**
+     * Match the given path with existing load balanced paths.
+     *
+     * @param path load balanced path
+     * @return load balance id if the path matches, null otherwise.
+     */
+    Optional<LoadBalanceId> matchPath(List<PortPairId> path);
+
+    /**
      * Returns whether this port chain is an exact match to the port chain given
      * in the argument.
      * <p>
diff --git a/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/PortPairGroup.java b/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/PortPairGroup.java
index f647b57..abc3349 100644
--- a/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/PortPairGroup.java
+++ b/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/PortPairGroup.java
@@ -59,6 +59,21 @@
     List<PortPairId> portPairs();
 
     /**
+     * Adds the load on the given port pair id.
+     *
+     * @param portPairId port pair id.
+     */
+    public void addLoad(PortPairId portPairId);
+
+    /**
+     * Get the load on the given port pair id.
+     *
+     * @param portPairId port pair id
+     * @return load on the given port pair id.
+     */
+    public int getLoad(PortPairId portPairId);
+
+    /**
      * Returns whether this port pair group is an exact match to the
      * port pair group given in the argument.
      * <p>