Speed up StackedOutboundQueue.reserve() 21/22021/7
authorRobert Varga <rovarga@cisco.com>
Sat, 6 Jun 2015 02:02:50 +0000 (04:02 +0200)
committerRobert Varga <rovarga@cisco.com>
Tue, 9 Jun 2015 13:31:18 +0000 (15:31 +0200)
In the case of multiple segments being present, we do not need to
completely synchronize if the corresponding segment has already been
allocated. Communicate this fact when allocating segments and check this
flag before embarking on the entire synchronized affair during
reserve().

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

index 3c3ceee3fba0c624915984f0ac1d0ef03942ca15..efe71aa77ec3f484ec7ae43c76a2367611837e32 100644 (file)
@@ -36,8 +36,9 @@ final class StackedOutboundQueue implements OutboundQueue {
     private final List<StackedSegment> uncompletedSegments = new ArrayList<>(2);
     private final OutboundQueueManager<?> manager;
 
-    private volatile long lastXid = -1;
+    private volatile long allocatedXid = -1;
     private volatile long barrierXid = -1;
+    private volatile long lastXid = -1;
 
     @GuardedBy("unflushedSegments")
     private Integer shutdownOffset;
@@ -62,6 +63,8 @@ final class StackedOutboundQueue implements OutboundQueue {
             LOG.debug("Adding segment {}", newSegment);
             unflushedSegments.add(newSegment);
         }
+
+        allocatedXid = uncompletedSegments.get(uncompletedSegments.size() - 1).getEndXid();
     }
 
     /*
@@ -73,27 +76,31 @@ final class StackedOutboundQueue implements OutboundQueue {
         final StackedSegment fastSegment = firstSegment;
 
         if (xid >= fastSegment.getBaseXid() + StackedSegment.SEGMENT_SIZE) {
-            LOG.debug("Queue {} falling back to slow reservation for XID {}", this, xid);
+           if (xid >= allocatedXid) {
+                // Multiple segments, this a slow path
+                LOG.debug("Queue {} falling back to slow reservation for XID {}", this, xid);
 
-            // Multiple segments, this a slow path
-            synchronized (unflushedSegments) {
-                LOG.debug("Queue {} executing slow reservation for XID {}", this, xid);
+                synchronized (unflushedSegments) {
+                    LOG.debug("Queue {} executing slow reservation for XID {}", this, xid);
 
-                // Shutdown was scheduled, need to fail the reservation
-                if (shutdownOffset != null) {
-                    LOG.debug("Queue {} is being shutdown, failing reservation", this);
-                    return null;
-                }
+                    // Shutdown was scheduled, need to fail the reservation
+                    if (shutdownOffset != null) {
+                        LOG.debug("Queue {} is being shutdown, failing reservation", this);
+                        return null;
+                    }
 
-                // Ensure we have the appropriate segment for the specified XID
-                final StackedSegment slowSegment = firstSegment;
-                final int slowOffset = (int) (xid - slowSegment.getBaseXid());
-                Verify.verify(slowOffset >= 0);
+                    // Ensure we have the appropriate segment for the specified XID
+                    final StackedSegment slowSegment = firstSegment;
+                    final int slowOffset = (int) (xid - slowSegment.getBaseXid());
+                    Verify.verify(slowOffset >= 0);
 
-                // Now, we let's see if we need to allocate a new segment
-                ensureSegment(slowSegment, slowOffset);
+                    // Now, we let's see if we need to allocate a new segment
+                    ensureSegment(slowSegment, slowOffset);
 
-                LOG.debug("Queue {} slow reservation finished", this);
+                    LOG.debug("Queue {} slow reservation finished", this);
+                }
+            } else {
+                LOG.debug("Queue {} XID {} is already backed", this, xid);
             }
         }
 
index 23bdb0be34975ad6489274b92cd043072f70286c..b9030b817094c5741830af9aa239545119490831 100644 (file)
@@ -91,6 +91,10 @@ final class StackedSegment {
         return baseXid;
     }
 
+    long getEndXid() {
+        return endXid;
+    }
+
     OutboundQueueEntry getEntry(final int offset) {
         return entries[offset];
     }