Avoid object allocations for HTTP2 child streams.

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.
This commit is contained in:
Jakob Buchgraber 2015-04-03 10:51:29 -07:00 committed by Scott Mitchell
parent 330bc39d91
commit e40c27d9ed
2 changed files with 13 additions and 7 deletions

View File

@ -38,6 +38,7 @@ import io.netty.buffer.ByteBuf;
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;
@ -216,7 +217,7 @@ public class DefaultHttp2Connection implements Http2Connection {
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;
@ -503,6 +504,12 @@ public class DefaultHttp2Connection implements Http2Connection {
}
}
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;
@ -539,7 +546,7 @@ public class DefaultHttp2Connection implements Http2Connection {
totalChildWeights = 0;
prioritizableForTree = isPrioritizable() ? 1 : 0;
IntObjectMap<DefaultStream> prevChildren = children;
children = newChildMap();
children = PrimitiveCollections.emptyIntObjectMap();
return prevChildren;
}
@ -561,6 +568,9 @@ public class DefaultHttp2Connection implements Http2Connection {
}
}
// Lazily initialize the children to save object allocations.
initChildrenIfEmpty();
if (children.put(child.id(), child) == null) {
totalChildWeights += child.weight();
incrementPrioritizableForTree(child.prioritizableForTree(), oldParent);
@ -673,10 +683,6 @@ public class DefaultHttp2Connection implements Http2Connection {
}
}
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
*/

View File

@ -68,7 +68,7 @@ public final class PrimitiveCollections {
@Override
public Object remove(int key) {
throw new UnsupportedOperationException("remove");
return null;
}
@Override