Use ArrayDeque for TransactionInvokerImpl.pendingTransactions 45/86245/26
authorRobert Varga <robert.varga@pantheon.tech>
Thu, 5 Dec 2019 21:41:22 +0000 (22:41 +0100)
committerStephen Kitt <skitt@redhat.com>
Tue, 7 Jan 2020 16:04:52 +0000 (16:04 +0000)
Rework the copy logic to operate on pure Iterator, disconnecting us
from the List API. This makes the choice of interface/implementation
a much broader one -- and pick Queue/ArrayDeque. It is a much better
structure for the job at hand.

JIRA: OVSDB-428
Change-Id: I22a4da6f4194d10e0932470bf2054441a9c1d3c1
Signed-off-by: Robert Varga <robert.varga@pantheon.tech>
southbound/southbound-impl/src/main/java/org/opendaylight/ovsdb/southbound/transactions/md/TransactionInvokerImpl.java
southbound/southbound-impl/src/test/java/org/opendaylight/ovsdb/southbound/transactions/md/TransactionInvokerImplTest.java

index 1bd39f7eb58cc88fd6094924dc7ed2a9fe2fde6a..4c78ecefd1610c62b08d97e5d70aab520103b6dc 100644 (file)
@@ -12,11 +12,14 @@ import com.google.common.util.concurrent.FutureCallback;
 import com.google.common.util.concurrent.Futures;
 import com.google.common.util.concurrent.MoreExecutors;
 import com.google.common.util.concurrent.ThreadFactoryBuilder;
+import java.util.ArrayDeque;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.HashMap;
+import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
+import java.util.Queue;
 import java.util.concurrent.BlockingQueue;
 import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Executors;
@@ -48,7 +51,7 @@ public class TransactionInvokerImpl implements TransactionInvoker,TransactionCha
     @GuardedBy("this")
     private final Map<ReadWriteTransaction, TransactionCommand> transactionToCommand = new HashMap<>();
     @GuardedBy("this")
-    private final List<ReadWriteTransaction> pendingTransactions = new ArrayList<>();
+    private final Queue<ReadWriteTransaction> pendingTransactions = new ArrayDeque<>();
 
     private BindingTransactionChain chain;
 
@@ -162,10 +165,18 @@ public class TransactionInvokerImpl implements TransactionInvoker,TransactionCha
         AsyncTransaction<?, ?> transaction = failedTransactionQueue.poll();
         List<TransactionCommand> commands = new ArrayList<>();
         if (transaction != null) {
-            int index = pendingTransactions.lastIndexOf(transaction);
-            for (ReadWriteTransaction tx : pendingTransactions.subList(index, pendingTransactions.size())) {
-                commands.add(transactionToCommand.get(tx));
+            // Process all pending transactions, looking for the failed one...
+            final Iterator<ReadWriteTransaction> it = pendingTransactions.iterator();
+            while (it.hasNext()) {
+                final ReadWriteTransaction current = it.next();
+                if (transaction.equals(current)) {
+                    // .. collect current and all remaining pending transactions
+                    commands.add(transactionToCommand.get(current));
+                    it.forEachRemaining(tx -> commands.add(transactionToCommand.get(tx)));
+                    break;
+                }
             }
+
             resetTransactionQueue();
         }
         return commands;
index 64b97551d1f22c2592ca87cd4cf7c52bdb7b6b44..06a52f760a17ec6527d5c9e912297b6d99944a69 100644 (file)
@@ -21,7 +21,6 @@ import com.google.common.collect.ImmutableList;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.HashMap;
-import java.util.List;
 import java.util.Map;
 import java.util.Queue;
 import java.util.concurrent.ExecutorService;
@@ -125,7 +124,7 @@ public class TransactionInvokerImplTest {
         final ReadWriteTransaction transaction = mock(ReadWriteTransaction.class);
         invoker.recordPendingTransaction(command, transaction);
 
-        List<ReadWriteTransaction> testPendingTransactions = getInternalState(invoker, "pendingTransactions");
+        Queue<ReadWriteTransaction> testPendingTransactions = getInternalState(invoker, "pendingTransactions");
         assertEquals(1, testPendingTransactions.size());
         assertTrue(testPendingTransactions.contains(transaction));