Fix statistics race condition on big flows
[openflowplugin.git] / openflowplugin-impl / src / main / java / org / opendaylight / openflowplugin / impl / registry / group / DeviceGroupRegistryImpl.java
index b0b5d8780069c95f2b71c9b0889f8fd19c622270..6fb6d5c9ec6ed6f0897725a59b1857b6f9f90567 100644 (file)
@@ -8,38 +8,60 @@
 
 package org.opendaylight.openflowplugin.impl.registry.group;
 
-import com.google.common.collect.ImmutableList;
+import com.google.common.annotations.VisibleForTesting;
 import java.util.ArrayList;
+import java.util.Collections;
 import java.util.List;
+import java.util.function.Consumer;
 import org.opendaylight.openflowplugin.api.openflow.registry.group.DeviceGroupRegistry;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.GroupId;
 
-/**
- * Created by Martin Bobak <mbobak@cisco.com> on 15.4.2015.
- */
 public class DeviceGroupRegistryImpl implements DeviceGroupRegistry {
 
-    private final List<GroupId> groupIdList = new ArrayList<>();
-    private final List<GroupId> marks = new ArrayList<>();
+    private final List<GroupId> groupIds = Collections.synchronizedList(new ArrayList<>());
+    private final List<GroupId> marks = Collections.synchronizedList(new ArrayList<>());
 
     @Override
     public void store(final GroupId groupId) {
-        groupIdList.add(groupId);
+        groupIds.add(groupId);
     }
 
     @Override
-    public void markToBeremoved(final GroupId groupId) {
+    public void addMark(final GroupId groupId) {
         marks.add(groupId);
     }
 
     @Override
-    public void removeMarked() {
-        groupIdList.removeAll(marks);
+    public boolean hasMark(final GroupId groupId) {
+        return marks.contains(groupId);
+    }
+
+    @Override
+    public void processMarks() {
+        groupIds.removeAll(marks);
         marks.clear();
     }
 
     @Override
-    public List<GroupId> getAllGroupIds() {
-        return ImmutableList.copyOf(groupIdList);
+    public void forEach(final Consumer<GroupId> consumer) {
+        synchronized (groupIds) {
+            groupIds.forEach(consumer);
+        }
+    }
+
+    @Override
+    public int size() {
+        return groupIds.size();
+    }
+
+    @Override
+    public void close() {
+        groupIds.clear();
+        marks.clear();
+    }
+
+    @VisibleForTesting
+    List<GroupId> getAllGroupIds() {
+        return groupIds;
     }
 }