MeterManager optimiziation. Use entryset instead of keyset avoiding some store access,
also add MeterStore getAllMeters(DeviceId).

Change-Id: I8dac9558cdb8b5c758e0e402cd0724c6cae16daf
diff --git a/core/api/src/main/java/org/onosproject/net/meter/MeterStore.java b/core/api/src/main/java/org/onosproject/net/meter/MeterStore.java
index a63d272..2dcb4ee 100644
--- a/core/api/src/main/java/org/onosproject/net/meter/MeterStore.java
+++ b/core/api/src/main/java/org/onosproject/net/meter/MeterStore.java
@@ -91,6 +91,15 @@
     Collection<Meter> getAllMeters();
 
     /**
+     * Returns all meters stored in the store for a
+     * precise device.
+     *
+     * @param deviceId the device to get the meter list from
+     * @return a collection of meters
+     */
+    Collection<Meter> getAllMeters(DeviceId deviceId);
+
+    /**
      * Update the store by deleting the failed meter.
      * Notifies the delegate that the meter failed to allow it
      * to nofity the app.
diff --git a/incubator/net/src/main/java/org/onosproject/incubator/net/meter/impl/MeterManager.java b/incubator/net/src/main/java/org/onosproject/incubator/net/meter/impl/MeterManager.java
index 34429a8..1fea477 100644
--- a/incubator/net/src/main/java/org/onosproject/incubator/net/meter/impl/MeterManager.java
+++ b/incubator/net/src/main/java/org/onosproject/incubator/net/meter/impl/MeterManager.java
@@ -15,7 +15,6 @@
  */
 package org.onosproject.incubator.net.meter.impl;
 
-import org.apache.commons.lang3.tuple.Pair;
 import com.google.common.collect.Maps;
 import org.apache.felix.scr.annotations.Activate;
 import org.apache.felix.scr.annotations.Component;
@@ -55,7 +54,6 @@
 
 import java.util.Collection;
 import java.util.Map;
-import java.util.function.Function;
 import java.util.stream.Collectors;
 
 import static org.slf4j.LoggerFactory.getLogger;
@@ -252,30 +250,27 @@
         public void pushMeterMetrics(DeviceId deviceId, Collection<Meter> meterEntries) {
             //FIXME: FOLLOWING CODE CANNOT BE TESTED UNTIL SOMETHING THAT
             //FIXME: IMPLEMENTS METERS EXISTS
-            Map<Pair<DeviceId, MeterId>, Meter> storedMeterMap = store.getAllMeters().stream()
-                    .collect(Collectors.toMap(m -> Pair.of(m.deviceId(), m.id()), Function.identity()));
+            Collection<Meter> allMeters = store.getAllMeters(deviceId);
 
             Map<MeterId, Meter> meterEntriesMap = meterEntries.stream()
                     .collect(Collectors.toMap(Meter::id, Meter -> Meter));
 
-            storedMeterMap.keySet().stream()
-                    .filter(m -> m.getLeft().equals(deviceId)).forEach(m -> {
-                if ((storedMeterMap.get(m).state().equals(MeterState.PENDING_ADD) ||
-                        storedMeterMap.get(m).state().equals(MeterState.ADDED)) &&
-                        !meterEntriesMap.containsKey(m.getRight())) {
+            allMeters.stream().forEach(m -> {
+                if ((m.state().equals(MeterState.PENDING_ADD) ||
+                        m.state().equals(MeterState.ADDED)) &&
+                        !meterEntriesMap.containsKey(m.id())) {
                     // The meter is missing in the device. Reinstall!
-                    Meter meter = storedMeterMap.get(Pair.of(deviceId, m.getRight()));
                     provider().performMeterOperation(deviceId,
-                            new MeterOperation(meter, MeterOperation.Type.ADD));
+                            new MeterOperation(m, MeterOperation.Type.ADD));
                 }
-
             });
 
             meterEntries.stream()
-                    .filter(m -> storedMeterMap.remove(Pair.of(m.deviceId(), m.id())) != null)
+                    .filter(m -> allMeters.stream()
+                            .anyMatch(sm -> sm.deviceId().equals(deviceId) && sm.id().equals(m.id())))
                     .forEach(m -> store.updateMeterState(m));
 
-            storedMeterMap.values().forEach(m -> {
+            allMeters.forEach(m -> {
                 if (m.state() == MeterState.PENDING_ADD) {
                     provider().performMeterOperation(m.deviceId(),
                                                      new MeterOperation(m,
diff --git a/incubator/store/src/main/java/org/onosproject/incubator/store/meter/impl/DistributedMeterStore.java b/incubator/store/src/main/java/org/onosproject/incubator/store/meter/impl/DistributedMeterStore.java
index 25276d5..cd0d707 100644
--- a/incubator/store/src/main/java/org/onosproject/incubator/store/meter/impl/DistributedMeterStore.java
+++ b/incubator/store/src/main/java/org/onosproject/incubator/store/meter/impl/DistributedMeterStore.java
@@ -273,6 +273,14 @@
     }
 
     @Override
+    public Collection<Meter> getAllMeters(DeviceId deviceId) {
+        return Collections2.transform(
+                Collections2.filter(meters.asJavaMap().values(),
+                        (MeterData m) -> m.meter().deviceId().equals(deviceId)),
+                MeterData::meter);
+    }
+
+    @Override
     public void failedMeter(MeterOperation op, MeterFailReason reason) {
         MeterKey key = MeterKey.key(op.meter().deviceId(), op.meter().id());
         meters.computeIfPresent(key, (k, v) ->