Move LeafRefPath creation from fast path 98/75798/1
authorRobert Varga <robert.varga@pantheon.tech>
Wed, 5 Sep 2018 18:15:00 +0000 (20:15 +0200)
committerRobert Varga <nite@hq.sk>
Thu, 6 Sep 2018 08:21:50 +0000 (08:21 +0000)
LeafRefValidation is the fast path and LeafRefPath we are creating
is in an invariant. Cache it in LeafRefContext as needed.

JIRA: YANGTOOLS-892
Change-Id: I40ef136630b7cdacca84b2f08a9e0491daa03c14
Signed-off-by: Robert Varga <robert.varga@pantheon.tech>
(cherry picked from commit 4b7393b11151722f44c19236684c661cf5f8edd0)

yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/leafref/LeafRefContext.java
yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/leafref/LeafRefValidatation.java

index 4445ff31757d8f8297d0f459e77a28adfcf9d40c..409e6ba1aa755193c045ed0a67bd3bd16e265753 100644 (file)
@@ -14,6 +14,7 @@ import org.opendaylight.yangtools.yang.model.api.Module;
 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
 import org.opendaylight.yangtools.yang.model.api.SchemaPath;
 
+// FIXME: 3.0.0 hide this class
 public final class LeafRefContext {
 
     private final QName currentNodeQName;
@@ -22,7 +23,7 @@ public final class LeafRefContext {
     private final Module module;
 
     private final LeafRefPath leafRefTargetPath;
-    private final LeafRefPath absoluteLeafRefTargetPath ;
+    private final LeafRefPath absoluteLeafRefTargetPath;
     private final String leafRefTargetPathString;
 
     private final boolean isReferencedBy;
@@ -32,6 +33,11 @@ public final class LeafRefContext {
     private final Map<QName, LeafRefContext> referencedByChilds;
     private final Map<QName, LeafRefContext> referencedByLeafRefCtx;
 
+    // FIXME: this looks like it's related to absoluteLeafRefTargetPath, but the original use in LeafRefValidation
+    //        fast path did not make it clear. Analyze the relationship between this field and
+    //        absoluteLeafRefTargetPath.
+    private volatile LeafRefPath leafRefNodePath = null;
+
     LeafRefContext(final LeafRefContextBuilder leafRefContextBuilder) {
         this.currentNodeQName = leafRefContextBuilder.getCurrentNodeQName();
         this.currentNodePath = leafRefContextBuilder.getCurrentNodePath();
@@ -127,4 +133,16 @@ public final class LeafRefContext {
         return referencedByLeafRefCtx;
     }
 
+    LeafRefPath getLeafRefNodePath() {
+        LeafRefPath ret = leafRefNodePath;
+        if (ret == null) {
+            synchronized (this) {
+                ret = leafRefNodePath;
+                if (ret == null) {
+                    ret = leafRefNodePath = LeafRefUtils.schemaPathToLeafRefPath(currentNodePath, module);
+                }
+            }
+        }
+        return ret;
+    }
 }
index b54cdbc78e314f76b3f7c44a3def29dfa6a10cd1..d62c359d24f178635a1c74d5f9b7e0a5a888107d 100644 (file)
@@ -37,7 +37,6 @@ import org.opendaylight.yangtools.yang.data.api.schema.ValueNode;
 import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeCandidate;
 import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeCandidateNode;
 import org.opendaylight.yangtools.yang.data.api.schema.tree.ModificationType;
-import org.opendaylight.yangtools.yang.model.api.SchemaPath;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -320,35 +319,28 @@ public final class LeafRefValidatation {
             return;
         }
 
-        final Map<QName, LeafRefContext> allReferencedByLeafRefCtxs = referencedByCtx.getAllReferencedByLeafRefCtxs();
-        for (final LeafRefContext leafRefContext : allReferencedByLeafRefCtxs.values()) {
+        for (final LeafRefContext leafRefContext : referencedByCtx.getAllReferencedByLeafRefCtxs().values()) {
             if (leafRefContext.isReferencing()) {
-                final Set<Object> values = new HashSet<>();
-
-                final SchemaPath leafRefNodeSchemaPath = leafRefContext.getCurrentNodePath();
-                final LeafRefPath leafRefNodePath = LeafRefUtils.schemaPathToLeafRefPath(leafRefNodeSchemaPath,
-                                leafRefContext.getLeafRefContextModule());
-                final Iterable<QNameWithPredicate> pathFromRoot = leafRefNodePath.getPathFromRoot();
-                addValues(values, tree.getRootNode().getDataAfter(), pathFromRoot, null, QNameWithPredicate.ROOT);
-                leafRefsValues.put(leafRefContext, values);
+                leafRefsValues.put(leafRefContext, extractRootValues(leafRefContext));
             }
         }
 
         if (!leafRefsValues.isEmpty()) {
-            final Set<Object> leafRefTargetNodeValues = new HashSet<>();
-            final SchemaPath nodeSchemaPath = referencedByCtx.getCurrentNodePath();
-            final LeafRefPath nodePath = LeafRefUtils.schemaPathToLeafRefPath(nodeSchemaPath, referencedByCtx
-                    .getLeafRefContextModule());
-            addValues(leafRefTargetNodeValues, tree.getRootNode().getDataAfter(), nodePath.getPathFromRoot(), null,
-                    QNameWithPredicate.ROOT);
-            leafRefTargetNodeDataLog(leaf, referencedByCtx, modificationType, leafRefsValues,
-                    leafRefTargetNodeValues);
+            final Set<Object> values = extractRootValues(referencedByCtx);
+            leafRefTargetNodeDataLog(leaf, referencedByCtx, modificationType, leafRefsValues, values);
         } else {
             leafRefTargetNodeDataLog(leaf, referencedByCtx, modificationType, null, null);
         }
         validatedLeafRefCtx.add(referencedByCtx);
     }
 
+    private Set<Object> extractRootValues(final LeafRefContext context) {
+        final Set<Object> values = new HashSet<>();
+        addValues(values, tree.getRootNode().getDataAfter(), context.getLeafRefNodePath().getPathFromRoot(), null,
+            QNameWithPredicate.ROOT);
+        return values;
+    }
+
     private void leafRefTargetNodeDataLog(final NormalizedNode<?, ?> leaf, final LeafRefContext referencedByCtx,
             final ModificationType modificationType, final Map<LeafRefContext, Set<?>> leafRefsValues,
             final Set<Object> leafRefTargetNodeValues) {