BUG-2350: optimize SchemaRootCodecContext.getYangIdentifierChild() 93/13793/3
authorRobert Varga <rovarga@cisco.com>
Sat, 20 Dec 2014 23:15:39 +0000 (00:15 +0100)
committerRobert Varga <rovarga@cisco.com>
Wed, 24 Dec 2014 12:57:22 +0000 (13:57 +0100)
This particular method has been found to dominate deletion-heavy
workloads, where it can account for up to 30% of time due to loading of
classes.

Eliminate this cost by instantiating a LoadingCache, which short-cuts
the class load.

Change-Id: I45c3f4acd67d85da30f26b71f73226a5beaf2876
Signed-off-by: Robert Varga <rovarga@cisco.com>
code-generator/binding-data-codec/src/main/java/org/opendaylight/yangtools/binding/data/codec/impl/SchemaRootCodecContext.java

index be328ca199ddd388df298159df847e3d90b6f46d..1fafb40ac4a1408a3d0c2656c934b8bde16a1b92 100644 (file)
@@ -17,7 +17,7 @@ import org.opendaylight.yangtools.yang.binding.ChildOf;
 import org.opendaylight.yangtools.yang.binding.DataRoot;
 import org.opendaylight.yangtools.yang.binding.util.BindingReflections;
 import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
 import org.opendaylight.yangtools.yang.model.api.ChoiceNode;
 import org.opendaylight.yangtools.yang.model.api.DataNodeContainer;
@@ -26,7 +26,7 @@ import org.opendaylight.yangtools.yang.model.api.SchemaContext;
 
 class SchemaRootCodecContext extends DataContainerCodecContext<SchemaContext> {
 
-    private final LoadingCache<Class<?>, DataContainerCodecContext<?>> children = CacheBuilder.newBuilder().build(
+    private final LoadingCache<Class<?>, DataContainerCodecContext<?>> childrenByClass = CacheBuilder.newBuilder().build(
             new CacheLoader<Class<?>, DataContainerCodecContext<?>>() {
                 @Override
                 public DataContainerCodecContext<?> load(final Class<?> key) {
@@ -38,6 +38,22 @@ class SchemaRootCodecContext extends DataContainerCodecContext<SchemaContext> {
                 }
             });
 
+    private final LoadingCache<QName, DataContainerCodecContext<?>> childrenByQName = CacheBuilder.newBuilder().build(
+        new CacheLoader<QName, DataContainerCodecContext<?>>() {
+            @Override
+            public DataContainerCodecContext<?> load(final QName qname) {
+                final DataSchemaNode childSchema = schema().getDataChildByName(qname);
+                Preconditions.checkArgument(childSchema != null, "Argument %s is not valid child of %s", qname, schema());
+
+                if (childSchema instanceof DataNodeContainer || childSchema instanceof ChoiceNode) {
+                    final Class<?> childCls = factory().getRuntimeContext().getClassForSchema(childSchema);
+                    return getStreamChild(childCls);
+                } else {
+                    throw new UnsupportedOperationException("Unsupported child type " + childSchema.getClass());
+                }
+            }
+        });
+
     private SchemaRootCodecContext(final DataContainerCodecPrototype<SchemaContext> dataPrototype) {
         super(dataPrototype);
     }
@@ -56,7 +72,7 @@ class SchemaRootCodecContext extends DataContainerCodecContext<SchemaContext> {
 
     @Override
     protected DataContainerCodecContext<?> getStreamChild(final Class<?> childClass) {
-        return children.getUnchecked(childClass);
+        return childrenByClass.getUnchecked(childClass);
     }
 
     @Override
@@ -65,23 +81,13 @@ class SchemaRootCodecContext extends DataContainerCodecContext<SchemaContext> {
     }
 
     @Override
-    protected YangInstanceIdentifier.PathArgument getDomPathArgument() {
+    protected PathArgument getDomPathArgument() {
         throw new UnsupportedOperationException();
     }
 
     @Override
-    protected NodeCodecContext getYangIdentifierChild(final YangInstanceIdentifier.PathArgument arg) {
-        // FIXME: Optimize this
-        QName childQName = arg.getNodeType();
-        DataSchemaNode childSchema = schema().getDataChildByName(childQName);
-        Preconditions.checkArgument(childSchema != null, "Argument %s is not valid child of %s", arg, schema());
-        if (childSchema instanceof DataNodeContainer || childSchema instanceof ChoiceNode) {
-            Class<?> childCls = factory().getRuntimeContext().getClassForSchema(childSchema);
-            DataContainerCodecContext<?> childNode = getStreamChild(childCls);
-            return childNode;
-        } else {
-            throw new UnsupportedOperationException();
-        }
+    protected NodeCodecContext getYangIdentifierChild(final PathArgument arg) {
+        return childrenByQName.getUnchecked(arg.getNodeType());
     }
 
     @Override