X-Git-Url: https://gerrit.onap.org/r/gitweb?a=blobdiff_plain;f=aai-core%2Fsrc%2Fmain%2Fjava%2Forg%2Fonap%2Faai%2Fquery%2Fbuilder%2FTraversalURIOptimizedQuery.java;h=b96847c28a263615195300de94b22cc7774df35d;hb=5026c0765b945cdad70cc4be4487e372d8c6a55f;hp=0e2a9cad873417469cc18f81da1a2b10935996f8;hpb=82b88bb0b1551acb6acc0c2e1037b80d0253c34f;p=aai%2Faai-common.git diff --git a/aai-core/src/main/java/org/onap/aai/query/builder/TraversalURIOptimizedQuery.java b/aai-core/src/main/java/org/onap/aai/query/builder/TraversalURIOptimizedQuery.java index 0e2a9cad..b96847c2 100644 --- a/aai-core/src/main/java/org/onap/aai/query/builder/TraversalURIOptimizedQuery.java +++ b/aai-core/src/main/java/org/onap/aai/query/builder/TraversalURIOptimizedQuery.java @@ -4,6 +4,8 @@ * ================================================================================ * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved. * ================================================================================ + * Modifications Copyright © 2024 Deutsche Telekom. + * ================================================================================ * Licensed 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 @@ -20,16 +22,20 @@ package org.onap.aai.query.builder; +import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Optional; import java.util.stream.Collectors; +import org.apache.commons.lang3.tuple.ImmutablePair; import org.apache.tinkerpop.gremlin.process.traversal.Step; import org.apache.tinkerpop.gremlin.process.traversal.Traversal; import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversal; import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversalSource; +import org.apache.tinkerpop.gremlin.process.traversal.step.filter.HasStep; +import org.apache.tinkerpop.gremlin.process.traversal.step.util.HasContainer; import org.apache.tinkerpop.gremlin.process.traversal.util.TraversalHelper; import org.apache.tinkerpop.gremlin.structure.Vertex; import org.onap.aai.db.props.AAIProperties; @@ -37,7 +43,7 @@ import org.onap.aai.introspection.Introspector; import org.onap.aai.introspection.Loader; import org.onap.aai.schema.enums.ObjectMetadata; -public class TraversalURIOptimizedQuery extends TraversalQuery { +public class TraversalURIOptimizedQuery extends TraversalQuery { protected Map stepToAaiUri = new HashMap<>(); @@ -46,21 +52,27 @@ public class TraversalURIOptimizedQuery extends TraversalQuery { optimize = true; } + public TraversalURIOptimizedQuery(Loader loader, GraphTraversalSource source, + GraphTraversal traversal) { + super(loader, source); + optimize = true; + } + public TraversalURIOptimizedQuery(Loader loader, GraphTraversalSource source, Vertex start) { super(loader, source, start); optimize = true; } protected TraversalURIOptimizedQuery(GraphTraversal traversal, Loader loader, GraphTraversalSource source, - GraphTraversalBuilder gtb) { - super(traversal, loader, source, gtb); + GraphTraversalBuilder graphTraversalBuilder) { + super(traversal, loader, source, graphTraversalBuilder); optimize = true; } protected TraversalURIOptimizedQuery(GraphTraversal traversal, Loader loader, GraphTraversalSource source, - GraphTraversalBuilder gtb, Map stepToAaiUri) { - super(traversal, loader, source, gtb); - optimize = gtb.optimize; + GraphTraversalBuilder graphTraversalBuilder, Map stepToAaiUri) { + super(traversal, loader, source, graphTraversalBuilder); + optimize = graphTraversalBuilder.optimize; this.stepToAaiUri = stepToAaiUri; } @@ -74,7 +86,7 @@ public class TraversalURIOptimizedQuery extends TraversalQuery { } if (start == null) { - Traversal.Admin admin = source.V().asAdmin(); + Traversal.Admin admin = source.V().asAdmin(); TraversalHelper.insertTraversal(admin.getEndStep(), completeTraversal, admin); this.completeTraversal = (Traversal.Admin) admin; @@ -84,31 +96,74 @@ public class TraversalURIOptimizedQuery extends TraversalQuery { } private Traversal.Admin pivotTraversal(Traversal.Admin traversalAdmin) { - - List steps = traversalAdmin.getSteps(); - - Traversal.Admin traversalAdminStart = traversalAdmin.clone(); - // if we do not have an index or other conditions do no optimization if (stepToAaiUri.isEmpty()) { return traversalAdmin; } - int lastURIStepKey = getLastURIStepKey(); + Traversal.Admin traversalAdminStart = traversalAdmin.clone(); + List steps = traversalAdmin.getSteps(); // clean up traversal steps for (int i = 0; i < steps.size(); i++) { traversalAdminStart.removeStep(0); } - ((GraphTraversal) traversalAdminStart).has(AAIProperties.AAI_URI, stepToAaiUri.get(lastURIStepKey)); - for (int i = lastURIStepKey; i < steps.size(); i++) { + int lastURIStepIndex = getLastURIStepIndex(); + ((GraphTraversal) traversalAdminStart).has(AAIProperties.AAI_URI, + stepToAaiUri.get(lastURIStepIndex)); + + ImmutablePair indexAndStepCountTuple = getHasContainerAdjustedIndexAndSplitPosition(steps, + lastURIStepIndex); + int adjustedIndex = indexAndStepCountTuple.getKey(); + for (int i = adjustedIndex; i < steps.size(); i++) { + Step step = steps.get(i); + boolean isFirstStep = i == adjustedIndex; + if (isFirstStep && step instanceof HasStep) { + int splitPosition = indexAndStepCountTuple.getValue(); + List newContainers = ((HasStep) step).getHasContainers().stream() + .skip(splitPosition) + .collect(Collectors.toList()); + traversalAdminStart + .addStep(new HasStep(traversalAdminStart, newContainers.toArray(new HasContainer[0]))); + i++; + } traversalAdminStart.addStep(steps.get(i)); } return traversalAdminStart; } + /** + * Adjust lastURIStepIndex by the number of steps that are in hasContainers. + * A HasContainer can contain multiple steps, which skews the original index. + * Returns the step index and split position inside the hasContainer + * + * @param steps the list of steps to go through + * @param lastURIStepIndex the list index to adjust + * @return a Tuple of the form (index, splitPosition) + */ + private ImmutablePair getHasContainerAdjustedIndexAndSplitPosition(List steps, + int lastURIStepIndex) { + int stepCount = 0; + for (int j = 0; j <= lastURIStepIndex; j++) { + Step step = steps.get(j); + if (step instanceof HasStep) { + stepCount += ((HasStep) step).getHasContainers().size(); + } else { + stepCount++; + } + if (stepCount == lastURIStepIndex) { + int splitPosition = stepCount + 1 - lastURIStepIndex; + return new ImmutablePair<>(j + 1, splitPosition); + } else if (stepCount > lastURIStepIndex) { + int splitPosition = stepCount + 1 - lastURIStepIndex; + return new ImmutablePair<>(j, splitPosition); + } + } + return new ImmutablePair<>(lastURIStepIndex, lastURIStepIndex); + } + @Override public QueryBuilder createKeyQuery(Introspector obj) { super.createKeyQuery(obj); @@ -159,14 +214,14 @@ public class TraversalURIOptimizedQuery extends TraversalQuery { } if (!stepToAaiUri.isEmpty()) { - uri = stepToAaiUri.get(getLastURIStepKey()) + uri; + uri = stepToAaiUri.get(getLastURIStepIndex()) + uri; } return Optional.of(uri); } - protected int getLastURIStepKey() { - return stepToAaiUri.keySet().stream().mapToInt(Integer::intValue).max().getAsInt(); + protected int getLastURIStepIndex() { + return Collections.max(stepToAaiUri.keySet()); } private Map getStepToAaiUriWithoutStepGreaterThan(final int index) {