Search in sources :

Example 1 with GraphObjectsBatch

use of org.finos.legend.engine.plan.execution.result.graphFetch.GraphObjectsBatch in project legend-engine by finos.

the class ExecutionNodeExecutor method visit.

@Override
public Result visit(GlobalGraphFetchExecutionNode globalGraphFetchExecutionNode) {
    final Span topSpan = GlobalTracer.get().activeSpan();
    final boolean isGraphRoot = globalGraphFetchExecutionNode.parentIndex == null;
    if (isGraphRoot) {
        final boolean enableConstraints = globalGraphFetchExecutionNode.enableConstraints == null ? false : globalGraphFetchExecutionNode.enableConstraints;
        final boolean checked = globalGraphFetchExecutionNode.checked == null ? false : globalGraphFetchExecutionNode.checked;
        // Handle batching at root level
        final AtomicLong rowCount = new AtomicLong(0L);
        final AtomicLong objectCount = new AtomicLong(0L);
        final DoubleSummaryStatistics memoryStatistics = new DoubleSummaryStatistics();
        GraphFetchResult graphFetchResult = (GraphFetchResult) globalGraphFetchExecutionNode.localGraphFetchExecutionNode.accept(new ExecutionNodeExecutor(this.profiles, this.executionState));
        Stream<?> objectStream = graphFetchResult.getGraphObjectsBatchStream().map(batch -> {
            List<?> parentObjects = batch.getObjectsForNodeIndex(0);
            boolean nonEmptyObjectList = !parentObjects.isEmpty();
            ExecutionState newState = new ExecutionState(this.executionState).setGraphObjectsBatch(batch);
            if (globalGraphFetchExecutionNode.children != null && !globalGraphFetchExecutionNode.children.isEmpty() && nonEmptyObjectList) {
                globalGraphFetchExecutionNode.children.forEach(c -> c.accept(new ExecutionNodeExecutor(this.profiles, newState)));
            }
            rowCount.addAndGet(batch.getRowCount());
            if (nonEmptyObjectList) {
                long currentObjectCount = objectCount.addAndGet(parentObjects.size());
                memoryStatistics.accept(batch.getTotalObjectMemoryUtilization() / (parentObjects.size() * 1.0));
                if (graphFetchResult.getGraphFetchSpan() != null) {
                    Span graphFetchSpan = graphFetchResult.getGraphFetchSpan();
                    graphFetchSpan.setTag("batchCount", memoryStatistics.getCount());
                    graphFetchSpan.setTag("objectCount", currentObjectCount);
                    graphFetchSpan.setTag("avgMemoryUtilizationInBytesPerObject", memoryStatistics.getAverage());
                }
            }
            if (!nonEmptyObjectList) {
                if (topSpan != null && rowCount.get() > 0) {
                    topSpan.setTag("lastQueryRowCount", rowCount);
                }
            }
            if (checked) {
                return parentObjects.stream().map(x -> (IChecked<?>) x).map(x -> x.getValue() instanceof Constrained ? ((Constrained<?>) x.getValue()).toChecked(x.getSource(), enableConstraints) : x).collect(Collectors.toList());
            }
            if (enableConstraints) {
                return parentObjects.stream().map(x -> x instanceof Constrained ? ((Constrained<?>) x).withConstraintsApplied() : x).collect(Collectors.toList());
            }
            return parentObjects;
        }).flatMap(Collection::stream);
        boolean realizeAsConstant = this.executionState.inAllocation && ExecutionNodeResultHelper.isResultSizeRangeSet(globalGraphFetchExecutionNode) && ExecutionNodeResultHelper.isSingleRecordResult(globalGraphFetchExecutionNode);
        if (realizeAsConstant) {
            return new ConstantResult(objectStream.findFirst().orElseThrow(() -> new RuntimeException("Constant value not found")));
        }
        return new StreamingObjectResult<>(objectStream, new PartialClassBuilder(globalGraphFetchExecutionNode), graphFetchResult);
    } else {
        GraphObjectsBatch graphObjectsBatch = this.executionState.graphObjectsBatch;
        List<?> parentObjects = graphObjectsBatch.getObjectsForNodeIndex(globalGraphFetchExecutionNode.parentIndex);
        if ((parentObjects != null) && !parentObjects.isEmpty()) {
            if (globalGraphFetchExecutionNode.xStorePropertyFetchDetails != null && globalGraphFetchExecutionNode.xStorePropertyFetchDetails.supportsCaching && this.executionState.graphFetchCaches != null) {
                graphObjectsBatch.setXStorePropertyCachesForNodeIndex(globalGraphFetchExecutionNode.localGraphFetchExecutionNode.nodeIndex, findGraphFetchCacheByTargetCrossKeys(globalGraphFetchExecutionNode));
            }
            globalGraphFetchExecutionNode.localGraphFetchExecutionNode.accept(new ExecutionNodeExecutor(this.profiles, this.executionState));
            if (globalGraphFetchExecutionNode.children != null && !globalGraphFetchExecutionNode.children.isEmpty()) {
                globalGraphFetchExecutionNode.children.forEach(c -> c.accept(new ExecutionNodeExecutor(this.profiles, this.executionState)));
            }
        }
        return new ConstantResult(parentObjects);
    }
}
Also used : Maps(org.eclipse.collections.impl.factory.Maps) ExecutionNodeVisitor(org.finos.legend.engine.protocol.pure.v1.model.executionPlan.nodes.ExecutionNodeVisitor) Arrays(java.util.Arrays) DefaultExecutionNodeContext(org.finos.legend.engine.plan.execution.nodes.helpers.platform.DefaultExecutionNodeContext) Spliterators(java.util.Spliterators) GraphFetchCacheKey(org.finos.legend.engine.plan.execution.cache.graphFetch.GraphFetchCacheKey) ExecutionNodeSerializerHelper(org.finos.legend.engine.plan.execution.nodes.helpers.ExecutionNodeSerializerHelper) DoubleSummaryStatistics(java.util.DoubleSummaryStatistics) MutableList(org.eclipse.collections.api.list.MutableList) InMemoryCrossStoreGraphFetchExecutionNode(org.finos.legend.engine.protocol.pure.v1.model.executionPlan.nodes.graphFetch.store.inMemory.InMemoryCrossStoreGraphFetchExecutionNode) ErrorExecutionNode(org.finos.legend.engine.protocol.pure.v1.model.executionPlan.nodes.ErrorExecutionNode) IPlatformPureExpressionExecutionNodeSerializeSpecifics(org.finos.legend.engine.plan.dependencies.store.platform.IPlatformPureExpressionExecutionNodeSerializeSpecifics) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) StoreStreamReadingExecutionNode(org.finos.legend.engine.protocol.pure.v1.model.executionPlan.nodes.graphFetch.store.inMemory.StoreStreamReadingExecutionNode) Map(java.util.Map) ConstantResult(org.finos.legend.engine.plan.execution.result.ConstantResult) ExecutionNode(org.finos.legend.engine.protocol.pure.v1.model.executionPlan.nodes.ExecutionNode) FunctionParametersValidationNode(org.finos.legend.engine.protocol.pure.v1.model.executionPlan.nodes.FunctionParametersValidationNode) AppliedFunction(org.finos.legend.engine.protocol.pure.v1.model.valueSpecification.application.AppliedFunction) AllocationExecutionNode(org.finos.legend.engine.protocol.pure.v1.model.executionPlan.nodes.AllocationExecutionNode) ConstantExecutionNode(org.finos.legend.engine.protocol.pure.v1.model.executionPlan.nodes.ConstantExecutionNode) Collection(java.util.Collection) GraphExecutionState(org.finos.legend.engine.plan.execution.nodes.state.GraphExecutionState) FunctionParametersParametersValidation(org.finos.legend.engine.plan.execution.validation.FunctionParametersParametersValidation) SerializationConfig(org.finos.legend.engine.protocol.pure.v1.model.valueSpecification.raw.SerializationConfig) Collectors(java.util.stream.Collectors) Constrained(org.finos.legend.engine.plan.dependencies.domain.dataQuality.Constrained) IExecutionNodeContext(org.finos.legend.engine.plan.dependencies.store.shared.IExecutionNodeContext) Objects(java.util.Objects) InMemoryRootGraphFetchExecutionNode(org.finos.legend.engine.protocol.pure.v1.model.executionPlan.nodes.graphFetch.store.inMemory.InMemoryRootGraphFetchExecutionNode) List(java.util.List) Stream(java.util.stream.Stream) Lists(org.eclipse.collections.impl.factory.Lists) Span(io.opentracing.Span) Scope(io.opentracing.Scope) FreeMarkerConditionalExecutionNode(org.finos.legend.engine.protocol.pure.v1.model.executionPlan.nodes.FreeMarkerConditionalExecutionNode) Spliterator(java.util.Spliterator) FreeMarkerExecutor(org.finos.legend.engine.plan.execution.nodes.helpers.freemarker.FreeMarkerExecutor) IPlatformPureExpressionExecutionNodeGraphFetchUnionSpecifics(org.finos.legend.engine.plan.dependencies.store.platform.IPlatformPureExpressionExecutionNodeGraphFetchUnionSpecifics) StoreType(org.finos.legend.engine.plan.execution.stores.StoreType) MultiResultSequenceExecutionNode(org.finos.legend.engine.protocol.pure.v1.model.executionPlan.nodes.MultiResultSequenceExecutionNode) CommonProfile(org.pac4j.core.profile.CommonProfile) ExecutionState(org.finos.legend.engine.plan.execution.nodes.state.ExecutionState) GraphFetchCache(org.finos.legend.engine.plan.execution.cache.graphFetch.GraphFetchCache) AggregationAwareExecutionNode(org.finos.legend.engine.protocol.pure.v1.model.executionPlan.nodes.AggregationAwareExecutionNode) IPlatformPureExpressionExecutionNodeGraphFetchMergeSpecifics(org.finos.legend.engine.plan.dependencies.store.platform.IPlatformPureExpressionExecutionNodeGraphFetchMergeSpecifics) PartialClassBuilder(org.finos.legend.engine.plan.execution.result.builder._class.PartialClassBuilder) GraphFetchResult(org.finos.legend.engine.plan.execution.result.graphFetch.GraphFetchResult) GraphFetchM2MExecutionNode(org.finos.legend.engine.protocol.pure.v1.model.executionPlan.nodes.GraphFetchM2MExecutionNode) ExecutionNodeResultHelper(org.finos.legend.engine.plan.execution.nodes.helpers.ExecutionNodeResultHelper) GraphFetchCrossAssociationKeys(org.finos.legend.engine.plan.execution.cache.graphFetch.GraphFetchCrossAssociationKeys) ExecutionCache(org.finos.legend.engine.plan.execution.cache.ExecutionCache) PureExpressionPlatformExecutionNode(org.finos.legend.engine.protocol.pure.v1.model.executionPlan.nodes.PureExpressionPlatformExecutionNode) GraphFetchExecutionNode(org.finos.legend.engine.protocol.pure.v1.model.executionPlan.nodes.graphFetch.GraphFetchExecutionNode) StreamingObjectResult(org.finos.legend.engine.plan.execution.result.object.StreamingObjectResult) JavaHelper(org.finos.legend.engine.plan.execution.nodes.helpers.platform.JavaHelper) StreamSupport(java.util.stream.StreamSupport) IChecked(org.finos.legend.engine.plan.dependencies.domain.dataQuality.IChecked) JavaPlatformImplementation(org.finos.legend.engine.protocol.pure.v1.model.executionPlan.nodes.JavaPlatformImplementation) ErrorResult(org.finos.legend.engine.plan.execution.result.ErrorResult) SequenceExecutionNode(org.finos.legend.engine.protocol.pure.v1.model.executionPlan.nodes.SequenceExecutionNode) Result(org.finos.legend.engine.plan.execution.result.Result) ResultVisitor(org.finos.legend.engine.plan.execution.result.ResultVisitor) XStorePropertyFetchDetails(org.finos.legend.engine.protocol.pure.v1.model.executionPlan.nodes.graphFetch.XStorePropertyFetchDetails) GraphFetchCacheByTargetCrossKeys(org.finos.legend.engine.plan.execution.cache.graphFetch.GraphFetchCacheByTargetCrossKeys) ExecutionNodeJavaPlatformHelper(org.finos.legend.engine.plan.execution.nodes.helpers.platform.ExecutionNodeJavaPlatformHelper) GlobalTracer(io.opentracing.util.GlobalTracer) GraphObjectsBatch(org.finos.legend.engine.plan.execution.result.graphFetch.GraphObjectsBatch) InMemoryPropertyGraphFetchExecutionNode(org.finos.legend.engine.protocol.pure.v1.model.executionPlan.nodes.graphFetch.store.inMemory.InMemoryPropertyGraphFetchExecutionNode) ProfileManager(org.pac4j.core.profile.ProfileManager) Consumer(java.util.function.Consumer) AtomicLong(java.util.concurrent.atomic.AtomicLong) MultiResult(org.finos.legend.engine.plan.execution.result.MultiResult) GlobalGraphFetchExecutionNode(org.finos.legend.engine.protocol.pure.v1.model.executionPlan.nodes.graphFetch.GlobalGraphFetchExecutionNode) LocalGraphFetchExecutionNode(org.finos.legend.engine.protocol.pure.v1.model.executionPlan.nodes.graphFetch.LocalGraphFetchExecutionNode) GraphExecutionState(org.finos.legend.engine.plan.execution.nodes.state.GraphExecutionState) ExecutionState(org.finos.legend.engine.plan.execution.nodes.state.ExecutionState) PartialClassBuilder(org.finos.legend.engine.plan.execution.result.builder._class.PartialClassBuilder) GraphObjectsBatch(org.finos.legend.engine.plan.execution.result.graphFetch.GraphObjectsBatch) ConstantResult(org.finos.legend.engine.plan.execution.result.ConstantResult) StreamingObjectResult(org.finos.legend.engine.plan.execution.result.object.StreamingObjectResult) DoubleSummaryStatistics(java.util.DoubleSummaryStatistics) GraphFetchResult(org.finos.legend.engine.plan.execution.result.graphFetch.GraphFetchResult) Span(io.opentracing.Span) AtomicLong(java.util.concurrent.atomic.AtomicLong) IChecked(org.finos.legend.engine.plan.dependencies.domain.dataQuality.IChecked) Constrained(org.finos.legend.engine.plan.dependencies.domain.dataQuality.Constrained) Collection(java.util.Collection) MutableList(org.eclipse.collections.api.list.MutableList) List(java.util.List)

Example 2 with GraphObjectsBatch

use of org.finos.legend.engine.plan.execution.result.graphFetch.GraphObjectsBatch in project legend-engine by finos.

the class InMemoryExecutionNodeExecutor method visit.

@Override
public Result visit(InMemoryPropertyGraphFetchExecutionNode node) {
    boolean isLeaf = node.children == null || node.children.isEmpty();
    IInMemoryPropertyGraphFetchExecutionNodeSpecifics nodeSpecifics = ExecutionNodeJavaPlatformHelper.getNodeSpecificsInstance(node, this.executionState, this.pm);
    GraphObjectsBatch graphObjectsBatch = this.executionState.graphObjectsBatch;
    List<?> parentObjects = graphObjectsBatch.getObjectsForNodeIndex(node.parentIndex).stream().map(x -> x instanceof IChecked ? ((IChecked<?>) x).getValue() : x).collect(Collectors.toList());
    Stream<IGraphInstance> childGraphInstancesStream = nodeSpecifics.transformProperty(parentObjects);
    List<Object> childObjects = childGraphInstancesStream.filter(Objects::nonNull).map(graphInstance -> {
        graphObjectsBatch.addObjectMemoryUtilization(graphInstance.instanceSize());
        return graphInstance.getValue();
    }).collect(Collectors.toList());
    graphObjectsBatch.setObjectsForNodeIndex(node.nodeIndex, childObjects);
    if (!childObjects.isEmpty() && (!isLeaf)) {
        node.children.forEach(x -> x.accept(new ExecutionNodeExecutor(this.pm, executionState)));
    }
    return new ConstantResult(childObjects);
}
Also used : java.util(java.util) org.finos.legend.engine.plan.dependencies.store.inMemory.graphFetch(org.finos.legend.engine.plan.dependencies.store.inMemory.graphFetch) CommonProfile(org.pac4j.core.profile.CommonProfile) IGraphInstance(org.finos.legend.engine.plan.dependencies.domain.graphFetch.IGraphInstance) DoubleStrategyHashMap(org.finos.legend.engine.shared.core.collectionsExtensions.DoubleStrategyHashMap) ExecutionState(org.finos.legend.engine.plan.execution.nodes.state.ExecutionState) org.finos.legend.engine.protocol.pure.v1.model.executionPlan.nodes(org.finos.legend.engine.protocol.pure.v1.model.executionPlan.nodes) Lists(org.eclipse.collections.api.factory.Lists) BasicDefect(org.finos.legend.engine.plan.dependencies.domain.dataQuality.BasicDefect) GraphFetchResult(org.finos.legend.engine.plan.execution.result.graphFetch.GraphFetchResult) ClassResultType(org.finos.legend.engine.protocol.pure.v1.model.executionPlan.result.ClassResultType) MutableList(org.eclipse.collections.api.list.MutableList) InMemoryCrossStoreGraphFetchExecutionNode(org.finos.legend.engine.protocol.pure.v1.model.executionPlan.nodes.graphFetch.store.inMemory.InMemoryCrossStoreGraphFetchExecutionNode) StoreStreamReadingResult(org.finos.legend.engine.plan.execution.stores.inMemory.result.graphFetch.StoreStreamReadingResult) Maps(org.eclipse.collections.api.factory.Maps) GraphFetchExecutionNode(org.finos.legend.engine.protocol.pure.v1.model.executionPlan.nodes.graphFetch.GraphFetchExecutionNode) ExecutionNodeExecutor(org.finos.legend.engine.plan.execution.nodes.ExecutionNodeExecutor) StreamingObjectResult(org.finos.legend.engine.plan.execution.result.object.StreamingObjectResult) JavaHelper(org.finos.legend.engine.plan.execution.nodes.helpers.platform.JavaHelper) StoreStreamReadingExecutionNode(org.finos.legend.engine.protocol.pure.v1.model.executionPlan.nodes.graphFetch.store.inMemory.StoreStreamReadingExecutionNode) ConstantResult(org.finos.legend.engine.plan.execution.result.ConstantResult) StreamSupport(java.util.stream.StreamSupport) IChecked(org.finos.legend.engine.plan.dependencies.domain.dataQuality.IChecked) Result(org.finos.legend.engine.plan.execution.result.Result) ExecutionNodeJavaPlatformHelper(org.finos.legend.engine.plan.execution.nodes.helpers.platform.ExecutionNodeJavaPlatformHelper) GlobalTracer(io.opentracing.util.GlobalTracer) GraphObjectsBatch(org.finos.legend.engine.plan.execution.result.graphFetch.GraphObjectsBatch) InMemoryPropertyGraphFetchExecutionNode(org.finos.legend.engine.protocol.pure.v1.model.executionPlan.nodes.graphFetch.store.inMemory.InMemoryPropertyGraphFetchExecutionNode) Collectors(java.util.stream.Collectors) Consumer(java.util.function.Consumer) AtomicLong(java.util.concurrent.atomic.AtomicLong) IDefect(org.finos.legend.engine.plan.dependencies.domain.dataQuality.IDefect) InMemoryRootGraphFetchExecutionNode(org.finos.legend.engine.protocol.pure.v1.model.executionPlan.nodes.graphFetch.store.inMemory.InMemoryRootGraphFetchExecutionNode) Stream(java.util.stream.Stream) Span(io.opentracing.Span) GlobalGraphFetchExecutionNode(org.finos.legend.engine.protocol.pure.v1.model.executionPlan.nodes.graphFetch.GlobalGraphFetchExecutionNode) InMemoryGraphFetchUtils(org.finos.legend.engine.plan.execution.stores.inMemory.utils.InMemoryGraphFetchUtils) LocalGraphFetchExecutionNode(org.finos.legend.engine.protocol.pure.v1.model.executionPlan.nodes.graphFetch.LocalGraphFetchExecutionNode) IGraphInstance(org.finos.legend.engine.plan.dependencies.domain.graphFetch.IGraphInstance) GraphObjectsBatch(org.finos.legend.engine.plan.execution.result.graphFetch.GraphObjectsBatch) ConstantResult(org.finos.legend.engine.plan.execution.result.ConstantResult) ExecutionNodeExecutor(org.finos.legend.engine.plan.execution.nodes.ExecutionNodeExecutor) IChecked(org.finos.legend.engine.plan.dependencies.domain.dataQuality.IChecked)

Example 3 with GraphObjectsBatch

use of org.finos.legend.engine.plan.execution.result.graphFetch.GraphObjectsBatch in project legend-engine by finos.

the class InMemoryExecutionNodeExecutor method mergeInMemoryNode.

private Result mergeInMemoryNode(InMemoryRootGraphFetchExecutionNode node) {
    IInMemoryRootGraphFetchMergeExecutionNodeSpecifics nodeSpecifics = ExecutionNodeJavaPlatformHelper.getNodeSpecificsInstance(node, this.executionState, this.pm);
    List<GraphFetchResult> results = node.executionNodes.stream().map(n -> (GraphFetchResult) n.accept(new ExecutionNodeExecutor(this.pm, this.executionState))).collect(Collectors.toList());
    List<Object> subObjects = results.stream().map(g -> g.getGraphObjectsBatchStream().findFirst().get().getObjectsForNodeIndex(0).get(0)).collect(Collectors.toList());
    // merged object
    Object targetObject = nodeSpecifics.transform(subObjects);
    Spliterator<GraphObjectsBatch> graphObjectsBatchSpliterator = new Spliterators.AbstractSpliterator<GraphObjectsBatch>(Long.MAX_VALUE, Spliterator.ORDERED) {

        AtomicLong batchIndex = new AtomicLong(0L);

        @Override
        public boolean tryAdvance(Consumer<? super GraphObjectsBatch> action) {
            long currentBatch = batchIndex.incrementAndGet();
            if (// run only once
            currentBatch > 1) {
                return false;
            }
            List<Object> resultObjects = new ArrayList<>();
            GraphObjectsBatch inMemoryGraphObjectsBatch = new GraphObjectsBatch(currentBatch, executionState.getGraphFetchBatchMemoryLimit());
            IGraphInstance<?> target = (IGraphInstance<?>) targetObject;
            inMemoryGraphObjectsBatch.addObjectMemoryUtilization(target.instanceSize());
            resultObjects.add(target.getValue());
            inMemoryGraphObjectsBatch.setObjectsForNodeIndex(node.nodeIndex, resultObjects);
            action.accept(inMemoryGraphObjectsBatch);
            return false;
        }
    };
    Stream<GraphObjectsBatch> graphObjectsBatchStream = StreamSupport.stream(graphObjectsBatchSpliterator, false);
    return new GraphFetchResult(graphObjectsBatchStream, new ConstantResult(targetObject));
}
Also used : java.util(java.util) org.finos.legend.engine.plan.dependencies.store.inMemory.graphFetch(org.finos.legend.engine.plan.dependencies.store.inMemory.graphFetch) CommonProfile(org.pac4j.core.profile.CommonProfile) IGraphInstance(org.finos.legend.engine.plan.dependencies.domain.graphFetch.IGraphInstance) DoubleStrategyHashMap(org.finos.legend.engine.shared.core.collectionsExtensions.DoubleStrategyHashMap) ExecutionState(org.finos.legend.engine.plan.execution.nodes.state.ExecutionState) org.finos.legend.engine.protocol.pure.v1.model.executionPlan.nodes(org.finos.legend.engine.protocol.pure.v1.model.executionPlan.nodes) Lists(org.eclipse.collections.api.factory.Lists) BasicDefect(org.finos.legend.engine.plan.dependencies.domain.dataQuality.BasicDefect) GraphFetchResult(org.finos.legend.engine.plan.execution.result.graphFetch.GraphFetchResult) ClassResultType(org.finos.legend.engine.protocol.pure.v1.model.executionPlan.result.ClassResultType) MutableList(org.eclipse.collections.api.list.MutableList) InMemoryCrossStoreGraphFetchExecutionNode(org.finos.legend.engine.protocol.pure.v1.model.executionPlan.nodes.graphFetch.store.inMemory.InMemoryCrossStoreGraphFetchExecutionNode) StoreStreamReadingResult(org.finos.legend.engine.plan.execution.stores.inMemory.result.graphFetch.StoreStreamReadingResult) Maps(org.eclipse.collections.api.factory.Maps) GraphFetchExecutionNode(org.finos.legend.engine.protocol.pure.v1.model.executionPlan.nodes.graphFetch.GraphFetchExecutionNode) ExecutionNodeExecutor(org.finos.legend.engine.plan.execution.nodes.ExecutionNodeExecutor) StreamingObjectResult(org.finos.legend.engine.plan.execution.result.object.StreamingObjectResult) JavaHelper(org.finos.legend.engine.plan.execution.nodes.helpers.platform.JavaHelper) StoreStreamReadingExecutionNode(org.finos.legend.engine.protocol.pure.v1.model.executionPlan.nodes.graphFetch.store.inMemory.StoreStreamReadingExecutionNode) ConstantResult(org.finos.legend.engine.plan.execution.result.ConstantResult) StreamSupport(java.util.stream.StreamSupport) IChecked(org.finos.legend.engine.plan.dependencies.domain.dataQuality.IChecked) Result(org.finos.legend.engine.plan.execution.result.Result) ExecutionNodeJavaPlatformHelper(org.finos.legend.engine.plan.execution.nodes.helpers.platform.ExecutionNodeJavaPlatformHelper) GlobalTracer(io.opentracing.util.GlobalTracer) GraphObjectsBatch(org.finos.legend.engine.plan.execution.result.graphFetch.GraphObjectsBatch) InMemoryPropertyGraphFetchExecutionNode(org.finos.legend.engine.protocol.pure.v1.model.executionPlan.nodes.graphFetch.store.inMemory.InMemoryPropertyGraphFetchExecutionNode) Collectors(java.util.stream.Collectors) Consumer(java.util.function.Consumer) AtomicLong(java.util.concurrent.atomic.AtomicLong) IDefect(org.finos.legend.engine.plan.dependencies.domain.dataQuality.IDefect) InMemoryRootGraphFetchExecutionNode(org.finos.legend.engine.protocol.pure.v1.model.executionPlan.nodes.graphFetch.store.inMemory.InMemoryRootGraphFetchExecutionNode) Stream(java.util.stream.Stream) Span(io.opentracing.Span) GlobalGraphFetchExecutionNode(org.finos.legend.engine.protocol.pure.v1.model.executionPlan.nodes.graphFetch.GlobalGraphFetchExecutionNode) InMemoryGraphFetchUtils(org.finos.legend.engine.plan.execution.stores.inMemory.utils.InMemoryGraphFetchUtils) LocalGraphFetchExecutionNode(org.finos.legend.engine.protocol.pure.v1.model.executionPlan.nodes.graphFetch.LocalGraphFetchExecutionNode) IGraphInstance(org.finos.legend.engine.plan.dependencies.domain.graphFetch.IGraphInstance) GraphObjectsBatch(org.finos.legend.engine.plan.execution.result.graphFetch.GraphObjectsBatch) ConstantResult(org.finos.legend.engine.plan.execution.result.ConstantResult) ExecutionNodeExecutor(org.finos.legend.engine.plan.execution.nodes.ExecutionNodeExecutor) GraphFetchResult(org.finos.legend.engine.plan.execution.result.graphFetch.GraphFetchResult) AtomicLong(java.util.concurrent.atomic.AtomicLong) Consumer(java.util.function.Consumer)

Example 4 with GraphObjectsBatch

use of org.finos.legend.engine.plan.execution.result.graphFetch.GraphObjectsBatch in project legend-engine by finos.

the class InMemoryExecutionNodeExecutor method visit.

@Override
public Result visit(InMemoryRootGraphFetchExecutionNode node) {
    int batchSize = node.batchSize == null ? 1 : node.batchSize;
    boolean isLeaf = node.children == null || node.children.isEmpty();
    boolean checked = node.checked;
    ClassResultType classResultType = (ClassResultType) node.resultType;
    String _class = classResultType._class;
    Result childResult = null;
    JavaPlatformImplementation javaPlatformImpl = (JavaPlatformImplementation) node.implementation;
    String executionClassName = JavaHelper.getExecutionClassFullName(javaPlatformImpl);
    Class<?> clazz = ExecutionNodeJavaPlatformHelper.getClassToExecute(node, executionClassName, this.executionState, this.pm);
    Span graphFetchSpan = GlobalTracer.get().buildSpan("graph fetch").withTag("rootStoreType", "inMemory").withTag("batchSizeConfig", batchSize).start();
    GlobalTracer.get().activateSpan(graphFetchSpan);
    try {
        if ((Arrays.asList(clazz.getInterfaces()).contains(IInMemoryRootGraphFetchMergeExecutionNodeSpecifics.class))) {
            return mergeInMemoryNode(node);
        } else {
            IInMemoryRootGraphFetchExecutionNodeSpecifics nodeSpecifics = ExecutionNodeJavaPlatformHelper.getNodeSpecificsInstance(node, this.executionState, this.pm);
            childResult = node.executionNodes.get(0).accept(new ExecutionNodeExecutor(this.pm, this.executionState));
            Iterator<?> sourceObjectsIterator;
            if (childResult instanceof StoreStreamReadingResult) {
                StoreStreamReadingResult<?> storeStreamReadingResult = (StoreStreamReadingResult) childResult;
                sourceObjectsIterator = storeStreamReadingResult.getObjectsIterator();
            } else if (childResult instanceof StreamingObjectResult) {
                StreamingObjectResult<?> streamingObjectResult = (StreamingObjectResult) childResult;
                sourceObjectsIterator = streamingObjectResult.getObjectStream().iterator();
            } else {
                throw new IllegalStateException("Unsupported result type: " + childResult.getClass().getSimpleName());
            }
            AtomicLong batchIndex = new AtomicLong(0L);
            Spliterator<GraphObjectsBatch> graphObjectsBatchSpliterator = new Spliterators.AbstractSpliterator<GraphObjectsBatch>(Long.MAX_VALUE, Spliterator.ORDERED) {

                @Override
                public boolean tryAdvance(Consumer<? super GraphObjectsBatch> action) {
                    long currentBatch = batchIndex.incrementAndGet();
                    GraphObjectsBatch inMemoryGraphObjectsBatch = new GraphObjectsBatch(currentBatch, executionState.getGraphFetchBatchMemoryLimit());
                    List<Object> resultObjects = new ArrayList<>();
                    int objectCount = 0;
                    if (checked) {
                        while (sourceObjectsIterator.hasNext()) {
                            IChecked<?> checkedSource = (IChecked<?>) sourceObjectsIterator.next();
                            Object value = checkedSource.getValue();
                            if (value == null) {
                                resultObjects.add(newDynamicChecked(Collections.singletonList(BasicDefect.newNoInputDefect(_class)), checkedSource, null));
                            } else {
                                Object targetObject = nodeSpecifics.transform(value);
                                if (targetObject != null) {
                                    if (targetObject instanceof List) {
                                        ((List<?>) targetObject).forEach(x -> {
                                            IGraphInstance<?> target = (IGraphInstance<?>) x;
                                            inMemoryGraphObjectsBatch.addObjectMemoryUtilization(target.instanceSize());
                                            resultObjects.add(newDynamicChecked(Collections.emptyList(), checkedSource, target.getValue()));
                                        });
                                    } else {
                                        IGraphInstance<?> target = (IGraphInstance<?>) targetObject;
                                        inMemoryGraphObjectsBatch.addObjectMemoryUtilization(target.instanceSize());
                                        resultObjects.add(newDynamicChecked(Collections.emptyList(), checkedSource, target.getValue()));
                                    }
                                }
                            }
                            objectCount += 1;
                            if (objectCount >= batchSize)
                                break;
                        }
                    } else {
                        while (sourceObjectsIterator.hasNext()) {
                            Object targetObject = nodeSpecifics.transform(sourceObjectsIterator.next());
                            if (targetObject != null) {
                                if (targetObject instanceof List) {
                                    ((List<?>) targetObject).forEach(x -> {
                                        IGraphInstance<?> target = (IGraphInstance<?>) x;
                                        inMemoryGraphObjectsBatch.addObjectMemoryUtilization(target.instanceSize());
                                        resultObjects.add(target.getValue());
                                    });
                                } else {
                                    IGraphInstance<?> target = (IGraphInstance<?>) targetObject;
                                    inMemoryGraphObjectsBatch.addObjectMemoryUtilization(target.instanceSize());
                                    resultObjects.add(target.getValue());
                                }
                            }
                            objectCount += 1;
                            if (objectCount >= batchSize)
                                break;
                        }
                    }
                    inMemoryGraphObjectsBatch.setObjectsForNodeIndex(node.nodeIndex, resultObjects);
                    if (!resultObjects.isEmpty() && (!isLeaf)) {
                        ExecutionState newState = new ExecutionState(executionState);
                        newState.graphObjectsBatch = inMemoryGraphObjectsBatch;
                        node.children.forEach(x -> x.accept(new ExecutionNodeExecutor(InMemoryExecutionNodeExecutor.this.pm, newState)));
                    }
                    action.accept(inMemoryGraphObjectsBatch);
                    return objectCount != 0;
                }
            };
            Stream<GraphObjectsBatch> graphObjectsBatchStream = StreamSupport.stream(graphObjectsBatchSpliterator, false);
            return new GraphFetchResult(graphObjectsBatchStream, childResult).withGraphFetchSpan(graphFetchSpan);
        }
    } catch (Exception e) {
        if (childResult != null) {
            childResult.close();
        }
        if (graphFetchSpan != null) {
            graphFetchSpan.finish();
        }
        if (e instanceof RuntimeException) {
            throw e;
        }
        Throwable cause = e.getCause();
        if (cause instanceof RuntimeException)
            throw (RuntimeException) cause;
        if (cause instanceof Error)
            throw (Error) cause;
        throw new RuntimeException(cause);
    }
}
Also used : ExecutionState(org.finos.legend.engine.plan.execution.nodes.state.ExecutionState) IGraphInstance(org.finos.legend.engine.plan.dependencies.domain.graphFetch.IGraphInstance) ClassResultType(org.finos.legend.engine.protocol.pure.v1.model.executionPlan.result.ClassResultType) ExecutionNodeExecutor(org.finos.legend.engine.plan.execution.nodes.ExecutionNodeExecutor) Span(io.opentracing.Span) GraphFetchResult(org.finos.legend.engine.plan.execution.result.graphFetch.GraphFetchResult) StoreStreamReadingResult(org.finos.legend.engine.plan.execution.stores.inMemory.result.graphFetch.StoreStreamReadingResult) StreamingObjectResult(org.finos.legend.engine.plan.execution.result.object.StreamingObjectResult) ConstantResult(org.finos.legend.engine.plan.execution.result.ConstantResult) Result(org.finos.legend.engine.plan.execution.result.Result) Consumer(java.util.function.Consumer) MutableList(org.eclipse.collections.api.list.MutableList) GraphObjectsBatch(org.finos.legend.engine.plan.execution.result.graphFetch.GraphObjectsBatch) StreamingObjectResult(org.finos.legend.engine.plan.execution.result.object.StreamingObjectResult) GraphFetchResult(org.finos.legend.engine.plan.execution.result.graphFetch.GraphFetchResult) AtomicLong(java.util.concurrent.atomic.AtomicLong) IChecked(org.finos.legend.engine.plan.dependencies.domain.dataQuality.IChecked) StoreStreamReadingResult(org.finos.legend.engine.plan.execution.stores.inMemory.result.graphFetch.StoreStreamReadingResult)

Example 5 with GraphObjectsBatch

use of org.finos.legend.engine.plan.execution.result.graphFetch.GraphObjectsBatch in project legend-engine by finos.

the class InMemoryExecutionNodeExecutor method visit.

@Override
public Result visit(InMemoryCrossStoreGraphFetchExecutionNode node) {
    List<Object> childObjects = new ArrayList<>();
    Result childResult = null;
    try {
        IInMemoryCrossStoreGraphFetchExecutionNodeSpecifics nodeSpecifics = ExecutionNodeJavaPlatformHelper.getNodeSpecificsInstance(node, this.executionState, this.pm);
        GraphObjectsBatch graphObjectsBatch = new GraphObjectsBatch(this.executionState.graphObjectsBatch);
        List<?> parentObjects = graphObjectsBatch.getObjectsForNodeIndex(node.parentIndex);
        if ((parentObjects != null) && !parentObjects.isEmpty()) {
            DoubleStrategyHashMap<Object, List<Object>, Object> parentMap = new DoubleStrategyHashMap<>(InMemoryGraphFetchUtils.parentChildDoubleHashStrategy(nodeSpecifics));
            parentObjects.forEach(parentObject -> parentMap.getIfAbsentPut(parentObject, ArrayList::new).add(parentObject));
            if (node.supportsBatching) {
                Map<String, List<Object>> keyValuePairs = Maps.mutable.empty();
                nodeSpecifics.getCrossStoreKeysValueForChildren(parentObjects.get(0)).keySet().forEach(key -> keyValuePairs.put(key, Lists.mutable.empty()));
                parentMap.keySet().forEach(parentObject -> nodeSpecifics.getCrossStoreKeysValueForChildren(parentObject).forEach((key, value) -> keyValuePairs.get(key).add(value)));
                keyValuePairs.forEach((key, value) -> this.executionState.addResult(key, new ConstantResult(value)));
                childResult = this.visit((InMemoryRootGraphFetchExecutionNode) node);
                GraphFetchResult childGraphFetchResult = (GraphFetchResult) childResult;
                Stream<GraphObjectsBatch> graphObjectsBatchStream = childGraphFetchResult.getGraphObjectsBatchStream();
                graphObjectsBatchStream.forEach(batch -> {
                    batch.getObjectsForNodeIndex(node.nodeIndex).forEach(child -> {
                        IGraphInstance<?> childGraphInstance = nodeSpecifics.wrapChildInGraphInstance(child);
                        Object childObject = childGraphInstance.getValue();
                        List<Object> parentsInScope = parentMap.getWithSecondKey(childObject);
                        if (parentsInScope != null) {
                            for (Object parentObject : parentsInScope) {
                                boolean isChildAdded = nodeSpecifics.attemptAddingChildToParent(parentObject, childObject);
                                if (isChildAdded) {
                                    graphObjectsBatch.addObjectMemoryUtilization(childGraphInstance.instanceSize());
                                    childObjects.add(childObject);
                                }
                            }
                        }
                    });
                });
            } else {
                for (Map.Entry<Object, List<Object>> entry : parentMap.entrySet()) {
                    Map<String, Object> keyValuePairs = nodeSpecifics.getCrossStoreKeysValueForChildren(entry.getKey());
                    keyValuePairs.forEach((key, value) -> this.executionState.addResult(key, new ConstantResult(value)));
                    childResult = this.visit((InMemoryRootGraphFetchExecutionNode) node);
                    GraphFetchResult childGraphFetchResult = (GraphFetchResult) childResult;
                    Stream<GraphObjectsBatch> graphObjectsBatchStream = childGraphFetchResult.getGraphObjectsBatchStream();
                    graphObjectsBatchStream.forEach(batch -> {
                        batch.getObjectsForNodeIndex(node.nodeIndex).forEach(child -> {
                            IGraphInstance<?> childGraphInstance = nodeSpecifics.wrapChildInGraphInstance(child);
                            Object childObject = childGraphInstance.getValue();
                            List<Object> parentsInScope = entry.getValue();
                            if (parentsInScope != null) {
                                for (Object parentObject : parentsInScope) {
                                    boolean isChildAdded = nodeSpecifics.attemptAddingChildToParent(parentObject, childObject);
                                    if (isChildAdded) {
                                        graphObjectsBatch.addObjectMemoryUtilization(childGraphInstance.instanceSize());
                                        childObjects.add(childObject);
                                    }
                                }
                            }
                        });
                    });
                }
            }
            graphObjectsBatch.setObjectsForNodeIndex(node.nodeIndex, childObjects);
        }
        return new ConstantResult(childObjects);
    } catch (RuntimeException e) {
        throw e;
    } catch (Exception e) {
        throw new RuntimeException(e);
    } finally {
        if (childResult != null) {
            childResult.close();
        }
    }
}
Also used : java.util(java.util) org.finos.legend.engine.plan.dependencies.store.inMemory.graphFetch(org.finos.legend.engine.plan.dependencies.store.inMemory.graphFetch) CommonProfile(org.pac4j.core.profile.CommonProfile) IGraphInstance(org.finos.legend.engine.plan.dependencies.domain.graphFetch.IGraphInstance) DoubleStrategyHashMap(org.finos.legend.engine.shared.core.collectionsExtensions.DoubleStrategyHashMap) ExecutionState(org.finos.legend.engine.plan.execution.nodes.state.ExecutionState) org.finos.legend.engine.protocol.pure.v1.model.executionPlan.nodes(org.finos.legend.engine.protocol.pure.v1.model.executionPlan.nodes) Lists(org.eclipse.collections.api.factory.Lists) BasicDefect(org.finos.legend.engine.plan.dependencies.domain.dataQuality.BasicDefect) GraphFetchResult(org.finos.legend.engine.plan.execution.result.graphFetch.GraphFetchResult) ClassResultType(org.finos.legend.engine.protocol.pure.v1.model.executionPlan.result.ClassResultType) MutableList(org.eclipse.collections.api.list.MutableList) InMemoryCrossStoreGraphFetchExecutionNode(org.finos.legend.engine.protocol.pure.v1.model.executionPlan.nodes.graphFetch.store.inMemory.InMemoryCrossStoreGraphFetchExecutionNode) StoreStreamReadingResult(org.finos.legend.engine.plan.execution.stores.inMemory.result.graphFetch.StoreStreamReadingResult) Maps(org.eclipse.collections.api.factory.Maps) GraphFetchExecutionNode(org.finos.legend.engine.protocol.pure.v1.model.executionPlan.nodes.graphFetch.GraphFetchExecutionNode) ExecutionNodeExecutor(org.finos.legend.engine.plan.execution.nodes.ExecutionNodeExecutor) StreamingObjectResult(org.finos.legend.engine.plan.execution.result.object.StreamingObjectResult) JavaHelper(org.finos.legend.engine.plan.execution.nodes.helpers.platform.JavaHelper) StoreStreamReadingExecutionNode(org.finos.legend.engine.protocol.pure.v1.model.executionPlan.nodes.graphFetch.store.inMemory.StoreStreamReadingExecutionNode) ConstantResult(org.finos.legend.engine.plan.execution.result.ConstantResult) StreamSupport(java.util.stream.StreamSupport) IChecked(org.finos.legend.engine.plan.dependencies.domain.dataQuality.IChecked) Result(org.finos.legend.engine.plan.execution.result.Result) ExecutionNodeJavaPlatformHelper(org.finos.legend.engine.plan.execution.nodes.helpers.platform.ExecutionNodeJavaPlatformHelper) GlobalTracer(io.opentracing.util.GlobalTracer) GraphObjectsBatch(org.finos.legend.engine.plan.execution.result.graphFetch.GraphObjectsBatch) InMemoryPropertyGraphFetchExecutionNode(org.finos.legend.engine.protocol.pure.v1.model.executionPlan.nodes.graphFetch.store.inMemory.InMemoryPropertyGraphFetchExecutionNode) Collectors(java.util.stream.Collectors) Consumer(java.util.function.Consumer) AtomicLong(java.util.concurrent.atomic.AtomicLong) IDefect(org.finos.legend.engine.plan.dependencies.domain.dataQuality.IDefect) InMemoryRootGraphFetchExecutionNode(org.finos.legend.engine.protocol.pure.v1.model.executionPlan.nodes.graphFetch.store.inMemory.InMemoryRootGraphFetchExecutionNode) Stream(java.util.stream.Stream) Span(io.opentracing.Span) GlobalGraphFetchExecutionNode(org.finos.legend.engine.protocol.pure.v1.model.executionPlan.nodes.graphFetch.GlobalGraphFetchExecutionNode) InMemoryGraphFetchUtils(org.finos.legend.engine.plan.execution.stores.inMemory.utils.InMemoryGraphFetchUtils) LocalGraphFetchExecutionNode(org.finos.legend.engine.protocol.pure.v1.model.executionPlan.nodes.graphFetch.LocalGraphFetchExecutionNode) InMemoryRootGraphFetchExecutionNode(org.finos.legend.engine.protocol.pure.v1.model.executionPlan.nodes.graphFetch.store.inMemory.InMemoryRootGraphFetchExecutionNode) GraphObjectsBatch(org.finos.legend.engine.plan.execution.result.graphFetch.GraphObjectsBatch) ConstantResult(org.finos.legend.engine.plan.execution.result.ConstantResult) DoubleStrategyHashMap(org.finos.legend.engine.shared.core.collectionsExtensions.DoubleStrategyHashMap) GraphFetchResult(org.finos.legend.engine.plan.execution.result.graphFetch.GraphFetchResult) GraphFetchResult(org.finos.legend.engine.plan.execution.result.graphFetch.GraphFetchResult) StoreStreamReadingResult(org.finos.legend.engine.plan.execution.stores.inMemory.result.graphFetch.StoreStreamReadingResult) StreamingObjectResult(org.finos.legend.engine.plan.execution.result.object.StreamingObjectResult) ConstantResult(org.finos.legend.engine.plan.execution.result.ConstantResult) Result(org.finos.legend.engine.plan.execution.result.Result) MutableList(org.eclipse.collections.api.list.MutableList) DoubleStrategyHashMap(org.finos.legend.engine.shared.core.collectionsExtensions.DoubleStrategyHashMap)

Aggregations

Span (io.opentracing.Span)6 AtomicLong (java.util.concurrent.atomic.AtomicLong)6 Consumer (java.util.function.Consumer)6 MutableList (org.eclipse.collections.api.list.MutableList)6 ExecutionState (org.finos.legend.engine.plan.execution.nodes.state.ExecutionState)6 ConstantResult (org.finos.legend.engine.plan.execution.result.ConstantResult)6 Result (org.finos.legend.engine.plan.execution.result.Result)6 GraphFetchResult (org.finos.legend.engine.plan.execution.result.graphFetch.GraphFetchResult)6 GraphObjectsBatch (org.finos.legend.engine.plan.execution.result.graphFetch.GraphObjectsBatch)6 StreamingObjectResult (org.finos.legend.engine.plan.execution.result.object.StreamingObjectResult)6 GlobalTracer (io.opentracing.util.GlobalTracer)5 Collectors (java.util.stream.Collectors)5 Stream (java.util.stream.Stream)5 StreamSupport (java.util.stream.StreamSupport)5 IChecked (org.finos.legend.engine.plan.dependencies.domain.dataQuality.IChecked)5 ExecutionNodeJavaPlatformHelper (org.finos.legend.engine.plan.execution.nodes.helpers.platform.ExecutionNodeJavaPlatformHelper)5 JavaHelper (org.finos.legend.engine.plan.execution.nodes.helpers.platform.JavaHelper)5 InMemoryCrossStoreGraphFetchExecutionNode (org.finos.legend.engine.protocol.pure.v1.model.executionPlan.nodes.graphFetch.store.inMemory.InMemoryCrossStoreGraphFetchExecutionNode)5 InMemoryPropertyGraphFetchExecutionNode (org.finos.legend.engine.protocol.pure.v1.model.executionPlan.nodes.graphFetch.store.inMemory.InMemoryPropertyGraphFetchExecutionNode)5 InMemoryRootGraphFetchExecutionNode (org.finos.legend.engine.protocol.pure.v1.model.executionPlan.nodes.graphFetch.store.inMemory.InMemoryRootGraphFetchExecutionNode)5