Author: markt
Date: Wed May 13 17:44:47 2015
New Revision: 1679251

URL: http://svn.apache.org/r1679251
Log:
Lay some groundwork for processing priority frames

Added:
    tomcat/trunk/java/org/apache/coyote/http2/AbstractStream.java   (with props)
    tomcat/trunk/test/org/apache/coyote/http2/TestAbstractStream.java   (with 
props)
Modified:
    tomcat/trunk/java/org/apache/coyote/http2/Http2UpgradeHandler.java
    tomcat/trunk/java/org/apache/coyote/http2/Stream.java

Added: tomcat/trunk/java/org/apache/coyote/http2/AbstractStream.java
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/http2/AbstractStream.java?rev=1679251&view=auto
==============================================================================
--- tomcat/trunk/java/org/apache/coyote/http2/AbstractStream.java (added)
+++ tomcat/trunk/java/org/apache/coyote/http2/AbstractStream.java Wed May 13 
17:44:47 2015
@@ -0,0 +1,113 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+package org.apache.coyote.http2;
+
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Set;
+
+/**
+ * Used to managed prioritisation.
+ */
+abstract class AbstractStream {
+
+    private static final int DEFAULT_WEIGHT = 16;
+
+    private final Integer identifier;
+
+    private volatile AbstractStream parentStream = null;
+    private final Set<AbstractStream> childStreams = new HashSet<>();
+    private volatile int weight = DEFAULT_WEIGHT;
+
+    public Integer getIdentifier() {
+        return identifier;
+    }
+
+
+    public AbstractStream(Integer identifier) {
+        this.identifier = identifier;
+    }
+
+
+    public void rePrioritise(Stream parent, boolean exclusive, int weight) {
+        // Check if new parent is a descendant of this stream
+        if (isDescendant(parent)) {
+            parent.detachFromParent();
+            parentStream.addChild(parent);
+        }
+
+        if (exclusive) {
+            // Need to move children of the new parent to be children of this
+            // stream. Slightly convoluted to avoid concurrent modification.
+            Iterator<AbstractStream> parentsChildren = 
parent.getChildStreams().iterator();
+            while (parentsChildren.hasNext()) {
+                AbstractStream parentsChild = parentsChildren.next();
+                parentsChildren.remove();
+                this.addChild(parentsChild);
+            }
+        }
+        parent.addChild(this);
+        this.weight = weight;
+    }
+
+
+    void detachFromParent() {
+        if (parentStream != null) {
+            parentStream.getChildStreams().remove(this);
+            parentStream = null;
+        }
+    }
+
+
+    void addChild(AbstractStream child) {
+        child.setParent(this);
+        childStreams.add(child);
+    }
+
+
+    private void setParent(AbstractStream parent) {
+        this.parentStream = parent;
+    }
+
+
+    boolean isDescendant(AbstractStream stream) {
+        if (childStreams.contains(stream)) {
+            return true;
+        }
+        for (AbstractStream child : childStreams) {
+            if (child.isDescendant(stream)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+
+    AbstractStream getParentStream() {
+        return parentStream;
+    }
+
+
+    void setParentStream(AbstractStream parentStream) {
+        this.parentStream = parentStream;
+    }
+
+
+    Set<AbstractStream> getChildStreams() {
+        return childStreams;
+    }
+}

Propchange: tomcat/trunk/java/org/apache/coyote/http2/AbstractStream.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: tomcat/trunk/java/org/apache/coyote/http2/Http2UpgradeHandler.java
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/http2/Http2UpgradeHandler.java?rev=1679251&r1=1679250&r2=1679251&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/coyote/http2/Http2UpgradeHandler.java 
(original)
+++ tomcat/trunk/java/org/apache/coyote/http2/Http2UpgradeHandler.java Wed May 
13 17:44:47 2015
@@ -45,11 +45,13 @@ import org.apache.tomcat.util.res.String
  * network.http.spdy.enforce-tls-profile=false in order for FireFox to be able
  * to connect.
  */
-public class Http2UpgradeHandler implements InternalHttpUpgradeHandler {
+public class Http2UpgradeHandler extends AbstractStream implements 
InternalHttpUpgradeHandler {
 
     private static final Log log = 
LogFactory.getLog(Http2UpgradeHandler.class);
     private static final StringManager sm = 
StringManager.getManager(Http2UpgradeHandler.class);
 
+    private static final Integer STREAM_ID_ZERO = Integer.valueOf(0);
+
     private static final int FRAME_TYPE_SETTINGS = 4;
     private static final int FRAME_TYPE_WINDOW_UPDATE = 8;
 
@@ -68,6 +70,12 @@ public class Http2UpgradeHandler impleme
 
     private final Map<Integer,Stream> streams = new HashMap<>();
 
+
+    public Http2UpgradeHandler() {
+        super (STREAM_ID_ZERO);
+    }
+
+
     @Override
     public void init(WebConnection unused) {
         initialized = true;
@@ -271,7 +279,7 @@ public class Http2UpgradeHandler impleme
             Integer key = Integer.valueOf(streamId);
             Stream stream = streams.get(key);
             if (stream == null) {
-                stream = new Stream(key, 
remoteSettings.getInitialWindowSize());
+                stream = new Stream(key, this);
             }
             stream.incrementWindowSize(windowSizeIncrement);
         }
@@ -362,6 +370,11 @@ public class Http2UpgradeHandler impleme
     }
 
 
+    ConnectionSettings getRemoteSettings() {
+        return remoteSettings;
+    }
+
+
     @Override
     public void destroy() {
         // NO-OP

Modified: tomcat/trunk/java/org/apache/coyote/http2/Stream.java
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/http2/Stream.java?rev=1679251&r1=1679250&r2=1679251&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/coyote/http2/Stream.java (original)
+++ tomcat/trunk/java/org/apache/coyote/http2/Stream.java Wed May 13 17:44:47 
2015
@@ -16,20 +16,15 @@
  */
 package org.apache.coyote.http2;
 
-public class Stream {
-
-    private final Integer identifier;
+public class Stream extends AbstractStream {
 
     private volatile long flowControlWindowSize;
 
-    public Stream(Integer identifier, long intitalWindowSize) {
-        this.identifier = identifier;
-        flowControlWindowSize = intitalWindowSize;
-    }
-
 
-    public Integer getIdentifier() {
-        return identifier;
+    public Stream(Integer identifier, Http2UpgradeHandler handler) {
+        super(identifier);
+        setParentStream(handler);
+        flowControlWindowSize = 
handler.getRemoteSettings().getInitialWindowSize();
     }
 
 

Added: tomcat/trunk/test/org/apache/coyote/http2/TestAbstractStream.java
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/test/org/apache/coyote/http2/TestAbstractStream.java?rev=1679251&view=auto
==============================================================================
--- tomcat/trunk/test/org/apache/coyote/http2/TestAbstractStream.java (added)
+++ tomcat/trunk/test/org/apache/coyote/http2/TestAbstractStream.java Wed May 
13 17:44:47 2015
@@ -0,0 +1,172 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+package org.apache.coyote.http2;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+/*
+ * This tests use A=1, B=2, etc to map stream IDs to the names used in the
+ * figures.
+ */
+public class TestAbstractStream {
+
+    @Test
+    public void testDependenciesFig3() {
+        // Setup
+        Http2UpgradeHandler handler = new Http2UpgradeHandler();
+        Stream a = new Stream(Integer.valueOf(1), handler);
+        Stream b = new Stream(Integer.valueOf(2), handler);
+        Stream c = new Stream(Integer.valueOf(3), handler);
+        Stream d = new Stream(Integer.valueOf(4), handler);
+        b.rePrioritise(a, false, 16);
+        c.rePrioritise(a, false, 16);
+
+        // Action
+        d.rePrioritise(a, false, 16);
+
+        // Check parents
+        Assert.assertEquals(handler, a.getParentStream());
+        Assert.assertEquals(a, b.getParentStream());
+        Assert.assertEquals(a, c.getParentStream());
+        Assert.assertEquals(a, d.getParentStream());
+
+        // Check children
+        Assert.assertEquals(3,  a.getChildStreams().size());
+        Assert.assertTrue(a.getChildStreams().contains(b));
+        Assert.assertTrue(a.getChildStreams().contains(c));
+        Assert.assertTrue(a.getChildStreams().contains(d));
+        Assert.assertEquals(0,  b.getChildStreams().size());
+        Assert.assertEquals(0,  c.getChildStreams().size());
+        Assert.assertEquals(0,  d.getChildStreams().size());
+    }
+
+
+    @Test
+    public void testDependenciesFig4() {
+        // Setup
+        Http2UpgradeHandler handler = new Http2UpgradeHandler();
+        Stream a = new Stream(Integer.valueOf(1), handler);
+        Stream b = new Stream(Integer.valueOf(2), handler);
+        Stream c = new Stream(Integer.valueOf(3), handler);
+        Stream d = new Stream(Integer.valueOf(4), handler);
+        b.rePrioritise(a, false, 16);
+        c.rePrioritise(a, false, 16);
+
+        // Action
+        d.rePrioritise(a, true, 16);
+
+        // Check parents
+        Assert.assertEquals(handler, a.getParentStream());
+        Assert.assertEquals(d, b.getParentStream());
+        Assert.assertEquals(d, c.getParentStream());
+        Assert.assertEquals(a, d.getParentStream());
+
+        // Check children
+        Assert.assertEquals(1,  a.getChildStreams().size());
+        Assert.assertTrue(a.getChildStreams().contains(d));
+        Assert.assertEquals(2,  d.getChildStreams().size());
+        Assert.assertTrue(d.getChildStreams().contains(b));
+        Assert.assertTrue(d.getChildStreams().contains(c));
+        Assert.assertEquals(0,  b.getChildStreams().size());
+        Assert.assertEquals(0,  c.getChildStreams().size());
+    }
+
+
+    @Test
+    public void testDependenciesFig5NonExclusive() {
+        // Setup
+        Http2UpgradeHandler handler = new Http2UpgradeHandler();
+        Stream a = new Stream(Integer.valueOf(1), handler);
+        Stream b = new Stream(Integer.valueOf(2), handler);
+        Stream c = new Stream(Integer.valueOf(3), handler);
+        Stream d = new Stream(Integer.valueOf(4), handler);
+        Stream e = new Stream(Integer.valueOf(5), handler);
+        Stream f = new Stream(Integer.valueOf(6), handler);
+        b.rePrioritise(a, false, 16);
+        c.rePrioritise(a, false, 16);
+        d.rePrioritise(c, false, 16);
+        e.rePrioritise(c, false, 16);
+        f.rePrioritise(d, false, 16);
+
+        // Action
+        a.rePrioritise(d, false, 16);
+
+        // Check parents
+        Assert.assertEquals(handler, d.getParentStream());
+        Assert.assertEquals(d, f.getParentStream());
+        Assert.assertEquals(d, a.getParentStream());
+        Assert.assertEquals(a, b.getParentStream());
+        Assert.assertEquals(a, c.getParentStream());
+        Assert.assertEquals(c, e.getParentStream());
+
+        // Check children
+        Assert.assertEquals(2,  d.getChildStreams().size());
+        Assert.assertTrue(d.getChildStreams().contains(a));
+        Assert.assertTrue(d.getChildStreams().contains(f));
+        Assert.assertEquals(0,  f.getChildStreams().size());
+        Assert.assertEquals(2,  a.getChildStreams().size());
+        Assert.assertTrue(a.getChildStreams().contains(b));
+        Assert.assertTrue(a.getChildStreams().contains(c));
+        Assert.assertEquals(0,  b.getChildStreams().size());
+        Assert.assertEquals(1,  c.getChildStreams().size());
+        Assert.assertTrue(c.getChildStreams().contains(e));
+        Assert.assertEquals(0,  e.getChildStreams().size());
+    }
+
+
+    @Test
+    public void testDependenciesFig5Exclusive() {
+        // Setup
+        Http2UpgradeHandler handler = new Http2UpgradeHandler();
+        Stream a = new Stream(Integer.valueOf(1), handler);
+        Stream b = new Stream(Integer.valueOf(2), handler);
+        Stream c = new Stream(Integer.valueOf(3), handler);
+        Stream d = new Stream(Integer.valueOf(4), handler);
+        Stream e = new Stream(Integer.valueOf(5), handler);
+        Stream f = new Stream(Integer.valueOf(6), handler);
+        b.rePrioritise(a, false, 16);
+        c.rePrioritise(a, false, 16);
+        d.rePrioritise(c, false, 16);
+        e.rePrioritise(c, false, 16);
+        f.rePrioritise(d, false, 16);
+
+        // Action
+        a.rePrioritise(d, true, 16);
+
+        // Check parents
+        Assert.assertEquals(handler, d.getParentStream());
+        Assert.assertEquals(d, a.getParentStream());
+        Assert.assertEquals(a, b.getParentStream());
+        Assert.assertEquals(a, c.getParentStream());
+        Assert.assertEquals(a, f.getParentStream());
+        Assert.assertEquals(c, e.getParentStream());
+
+        // Check children
+        Assert.assertEquals(1,  d.getChildStreams().size());
+        Assert.assertTrue(d.getChildStreams().contains(a));
+        Assert.assertEquals(3,  a.getChildStreams().size());
+        Assert.assertTrue(a.getChildStreams().contains(b));
+        Assert.assertTrue(a.getChildStreams().contains(c));
+        Assert.assertTrue(a.getChildStreams().contains(f));
+        Assert.assertEquals(0,  b.getChildStreams().size());
+        Assert.assertEquals(0,  f.getChildStreams().size());
+        Assert.assertEquals(1,  c.getChildStreams().size());
+        Assert.assertTrue(c.getChildStreams().contains(e));
+        Assert.assertEquals(0,  e.getChildStreams().size());
+    }
+}

Propchange: tomcat/trunk/test/org/apache/coyote/http2/TestAbstractStream.java
------------------------------------------------------------------------------
    svn:eol-style = native



---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org
For additional commands, e-mail: dev-h...@tomcat.apache.org

Reply via email to