Optimize barrier-implied flushes 80/20580/3
authorRobert Varga <rovarga@cisco.com>
Sat, 16 May 2015 00:21:19 +0000 (02:21 +0200)
committerRobert Varga <rovarga@cisco.com>
Sat, 16 May 2015 12:25:25 +0000 (14:25 +0200)
Original code did a full queue scan up to the current request. This
is inefficient if there are previously-completed barriers, as we end up
checking the same slots multiple times.

Remember the offset of last completed future and only flush slots from
that offset on subsequent barrier completion.

Change-Id: I9715f9f7818de611c01d0cd2eaa7637ac5372e91
Signed-off-by: Robert Varga <rovarga@cisco.com>
openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/connection/OutboundQueueImpl.java

index 2d94b679adfd9fa9bfcfb165bf42d189be817bc0..5d22435dddf8aaa3f410e22c53c148c9c58bf1f9 100644 (file)
@@ -37,6 +37,7 @@ final class OutboundQueueImpl implements OutboundQueue {
     // Updated from Netty only
     private int flushOffset;
     private int completeCount;
+    private int lastBarrierOffset = -1;
 
     OutboundQueueImpl(final OutboundQueueManager<?> manager, final long baseXid, final int maxQueue) {
         /*
@@ -233,29 +234,31 @@ final class OutboundQueueImpl implements OutboundQueue {
 
             // This has been a barrier -- make sure we complete all preceding requests
             if (entry.isBarrier()) {
-                LOG.debug("Barrier XID {} completed, cascading completion to XIDs {} to {}", xid, baseXid, xid - 1);
-                for (int i = 0; i < offset; ++i) {
-                    final OutboundQueueEntry e = queue[i];
-                    if (!e.isCompleted() && e.complete(null)) {
-                        completeCount++;
-                    }
-                }
+                LOG.debug("Barrier XID {} completed, cascading completion to XIDs {} to {}", xid, baseXid + lastBarrierOffset + 1, xid - 1);
+                completeRequests(offset);
+                lastBarrierOffset = offset;
             }
         }
         return entry;
     }
 
-    void completeAll() {
-        for (OutboundQueueEntry entry : queue) {
+    private void completeRequests(final int toOffset) {
+        for (int i = lastBarrierOffset + 1; i < toOffset; ++i) {
+            final OutboundQueueEntry entry = queue[i];
             if (!entry.isCompleted() && entry.complete(null)) {
                 completeCount++;
             }
         }
     }
 
+    void completeAll() {
+        completeRequests(queue.length);
+    }
+
     int failAll(final Throwable cause) {
         int ret = 0;
-        for (OutboundQueueEntry entry : queue) {
+        for (int i = lastBarrierOffset + 1; i < queue.length; ++i) {
+            final OutboundQueueEntry entry = queue[i];
             if (!entry.isCompleted()) {
                 entry.fail(cause);
                 ret++;