Skip to content

Commit

Permalink
Avoid object allocations for HTTP2 child streams.
Browse files Browse the repository at this point in the history
Motivation:

We are allocating a hash map for every HTTP2 Stream to store it's children.
Most streams are leafs in the priority tree and don't have children.

Modification:

 - Only allocate children when we actually use them.
 - Make EmptyIntObjectMap not throw a UnsupportedOperationException on remove, but return null instead (as is stated in it's javadoc).

Result:

Fewer unnecessary allocations.
  • Loading branch information
buchgr authored and Scottmitch committed Apr 3, 2015
1 parent 5de91c0 commit 42bcaef
Show file tree
Hide file tree
Showing 2 changed files with 13 additions and 7 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
import io.netty.handler.codec.http2.Http2StreamRemovalPolicy.Action;
import io.netty.util.collection.IntObjectHashMap;
import io.netty.util.collection.IntObjectMap;
import io.netty.util.collection.PrimitiveCollections;

import java.util.ArrayList;
import java.util.Collection;
Expand Down Expand Up @@ -216,7 +217,7 @@ private class DefaultStream implements Http2Stream {
private State state = IDLE;
private short weight = DEFAULT_PRIORITY_WEIGHT;
private DefaultStream parent;
private IntObjectMap<DefaultStream> children = newChildMap();
private IntObjectMap<DefaultStream> children = PrimitiveCollections.emptyIntObjectMap();
private int totalChildWeights;
private int prioritizableForTree = 1;
private boolean resetSent;
Expand Down Expand Up @@ -503,6 +504,12 @@ private void notifyHalfClosed(Http2Stream stream) {
}
}

private void initChildrenIfEmpty() {
if (children == PrimitiveCollections.<DefaultStream>emptyIntObjectMap()) {
children = new IntObjectHashMap<DefaultStream>(4);
}
}

@Override
public final boolean remoteSideOpen() {
return state == HALF_CLOSED_LOCAL || state == OPEN || state == RESERVED_REMOTE;
Expand Down Expand Up @@ -539,7 +546,7 @@ final IntObjectMap<DefaultStream> removeAllChildren() {
totalChildWeights = 0;
prioritizableForTree = isPrioritizable() ? 1 : 0;
IntObjectMap<DefaultStream> prevChildren = children;
children = newChildMap();
children = PrimitiveCollections.emptyIntObjectMap();
return prevChildren;
}

Expand All @@ -561,6 +568,9 @@ final void takeChild(DefaultStream child, boolean exclusive, List<ParentChangedE
}
}

// Lazily initialize the children to save object allocations.
initChildrenIfEmpty();

if (children.put(child.id(), child) == null) {
totalChildWeights += child.weight();
incrementPrioritizableForTree(child.prioritizableForTree(), oldParent);
Expand Down Expand Up @@ -673,10 +683,6 @@ public <V> V remove(Object key) {
}
}

private static IntObjectMap<DefaultStream> newChildMap() {
return new IntObjectHashMap<DefaultStream>(4);
}

/**
* Allows a correlation to be made between a stream and its old parent before a parent change occurs
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ public void putAll(IntObjectMap<Object> sourceMap) {

@Override
public Object remove(int key) {
throw new UnsupportedOperationException("remove");
return null;
}

@Override
Expand Down

0 comments on commit 42bcaef

Please sign in to comment.