/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you 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 * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.tinkerpop.gremlin.process.computer; import org.apache.tinkerpop.gremlin.process.traversal.Traversal; import org.apache.tinkerpop.gremlin.structure.Edge; import org.apache.tinkerpop.gremlin.structure.Vertex; import java.util.concurrent.Future; /** * The {@link GraphComputer} is responsible for the execution of a {@link VertexProgram} and then a set of {@link MapReduce} jobs * over the vertices in the {@link org.apache.tinkerpop.gremlin.structure.Graph}. It is up to the {@link GraphComputer} implementation to determine the * appropriate memory structures given the computing substrate. * * @author Marko A. Rodriguez (http://markorodriguez.com) * @author Matthias Broecheler (me@matthiasb.com) */ public interface GraphComputer { public enum ResultGraph { /** * When the computation is complete, the {@link org.apache.tinkerpop.gremlin.structure.Graph} in {@link ComputerResult} is the original graph that spawned the graph computer. */ ORIGINAL, /** * When the computation is complete, the {@link org.apache.tinkerpop.gremlin.structure.Graph} in {@link ComputerResult} is a new graph cloned from the original graph. */ NEW } public enum Persist { /** * Write nothing to the declared {@link ResultGraph}. */ NOTHING, /** * Write vertex and vertex properties to the {@link ResultGraph}. */ VERTEX_PROPERTIES, /** * Write vertex, vertex properties, and edges to the {@link ResultGraph}. */ EDGES } /** * Set the {@link ResultGraph} of the computation. * If this is not set explicitly by the user, then the {@link VertexProgram} can choose the most efficient result for its intended use. * If there is no declared vertex program, then the {@link GraphComputer} defaults to {@link ResultGraph#ORIGINAL}. * * @param resultGraph the type of graph to be returned by {@link ComputerResult#graph} * @return the updated GraphComputer with newly set result graph */ public GraphComputer result(final ResultGraph resultGraph); /** * Set the {@link Persist} level of the computation. * If this is not set explicitly by the user, then the {@link VertexProgram} can choose the most efficient persist for the its intended use. * If there is no declared vertex program, then the {@link GraphComputer} defaults to {@link Persist#NOTHING}. * * @param persist the persistence level of the resultant computation * @return the updated GraphComputer with newly set persist */ public GraphComputer persist(final Persist persist); /** * Set the {@link VertexProgram} to be executed by the {@link GraphComputer}. * There can only be one VertexProgram for the GraphComputer. * * @param vertexProgram the VertexProgram to be executed * @return the updated GraphComputer with newly set VertexProgram */ public GraphComputer program(final VertexProgram vertexProgram); /** * Add a {@link MapReduce} job to the set of MapReduce jobs to be executed by the {@link GraphComputer}. * There can be any number of MapReduce jobs. * * @param mapReduce the MapReduce job to add to the computation * @return the updated GraphComputer with newly added MapReduce job */ public GraphComputer mapReduce(final MapReduce mapReduce); /** * Set the desired number of workers to execute the {@link VertexProgram} and {@link MapReduce} jobs. * This is a recommendation to the underlying {@link GraphComputer} implementation and is allowed to deviate accordingly by the implementation. * * @param workers the number of workers to execute the submission * @return the updated GraphComputer with newly set worker count */ public GraphComputer workers(final int workers); /** * Add a filter that will limit which vertices are loaded from the graph source. * The provided {@link Traversal} can only check the vertex, its vertex properties, and the vertex property properties. * The loaded graph will only have those vertices that pass through the provided filter. * * @param vertexFilter the traversal to verify whether or not to load the current vertex * @return the updated GraphComputer with newly set vertex filter * @throws IllegalArgumentException if the provided traversal attempts to access vertex edges */ public GraphComputer vertices(final Traversal<Vertex, Vertex> vertexFilter) throws IllegalArgumentException; /** * Add a filter that will limit which edges of the vertices are loaded from the graph source. * The provided {@link Traversal} can only check the local star graph of the vertex and thus, * can not access properties/labels of the adjacent vertices. * The vertices of the loaded graph will only have those edges that pass through the provided filter. * * @param edgeFilter the traversal that determines which edges are loaded for each vertex * @return the updated GraphComputer with newly set edge filter * @throws IllegalArgumentException if the provided traversal attempts to access adjacent vertices */ public GraphComputer edges(final Traversal<Vertex, Edge> edgeFilter) throws IllegalArgumentException; /** * Set an arbitrary configuration key/value for the underlying {@link org.apache.commons.configuration.Configuration} in the {@link GraphComputer}. * Typically, the other fluent methods in {@link GraphComputer} should be used to configure the computation. * However, for some custom configuration in the underlying engine, this method should be used. * Different GraphComputer implementations will have different key/values and thus, parameters placed here are generally not universal to all GraphComputer implementations. * The default implementation simply does nothing and returns the {@link GraphComputer} unchanged. * * @param key the key of the configuration * @param value the value of the configuration * @return the updated GraphComputer with newly set key/value configuration */ public default GraphComputer configure(final String key, final Object value) { return this; } /** * Submit the {@link VertexProgram} and the set of {@link MapReduce} jobs for execution by the {@link GraphComputer}. * * @return a {@link Future} denoting a reference to the asynchronous computation and where to get the {@link org.apache.tinkerpop.gremlin.process.computer.util.DefaultComputerResult} when its is complete. */ public Future<ComputerResult> submit(); public default Features features() { return new Features() { }; } public interface Features { public default int getMaxWorkers() { return Integer.MAX_VALUE; } public default boolean supportsGlobalMessageScopes() { return true; } public default boolean supportsLocalMessageScopes() { return true; } public default boolean supportsVertexAddition() { return true; } public default boolean supportsVertexRemoval() { return true; } public default boolean supportsVertexPropertyAddition() { return true; } public default boolean supportsVertexPropertyRemoval() { return true; } public default boolean supportsEdgeAddition() { return true; } public default boolean supportsEdgeRemoval() { return true; } public default boolean supportsEdgePropertyAddition() { return true; } public default boolean supportsEdgePropertyRemoval() { return true; } public default boolean supportsResultGraphPersistCombination(final ResultGraph resultGraph, final Persist persist) { return true; } public default boolean supportsGraphFilter() { return true; } /** * Supports {@link VertexProgram} and {@link MapReduce} parameters to be direct referenced Java objects (no serialization required). * This is typically true for single machine graph computer engines. For cluster oriented graph computers, this is typically false. */ public default boolean supportsDirectObjects() { return true; } } public static class Exceptions { private Exceptions() { } public static UnsupportedOperationException adjacentVertexLabelsCanNotBeRead() { return new UnsupportedOperationException("The label of an adjacent vertex can not be read"); } public static UnsupportedOperationException adjacentVertexPropertiesCanNotBeReadOrUpdated() { return new UnsupportedOperationException("The properties of an adjacent vertex can not be read or updated"); } public static UnsupportedOperationException adjacentVertexEdgesAndVerticesCanNotBeReadOrUpdated() { return new UnsupportedOperationException("The edges and vertices of an adjacent vertex can not be read or updated"); } public static UnsupportedOperationException graphFilterNotSupported() { return new UnsupportedOperationException("The computer does not support graph filter"); } public static IllegalArgumentException providedKeyIsNotAnElementComputeKey(final String key) { return new IllegalArgumentException("The provided key is not an element compute key: " + key); } public static IllegalArgumentException providedKeyIsNotAMemoryComputeKey(final String key) { return new IllegalArgumentException("The provided key is not a memory compute key: " + key); } public static IllegalArgumentException resultGraphPersistCombinationNotSupported(final ResultGraph resultGraph, final Persist persist) { return new IllegalArgumentException("The computer does not support the following result graph and persist combination: " + resultGraph + ":" + persist); } public static IllegalStateException computerHasAlreadyBeenSubmittedAVertexProgram() { return new IllegalStateException("This computer has already had a vertex program submitted to it"); } public static IllegalStateException computerHasNoVertexProgramNorMapReducers() { return new IllegalStateException("The computer has no vertex program or map reducers to execute"); } public static UnsupportedOperationException incidentAndAdjacentElementsCanNotBeAccessedInMapReduce() { return new UnsupportedOperationException("The computer is in MapReduce mode and a vertex's incident and adjacent elements can not be accessed"); } public static UnsupportedOperationException vertexPropertiesCanNotBeUpdatedInMapReduce() { return new UnsupportedOperationException("The computer is in MapReduce mode and a vertex's properties can not be updated"); } public static IllegalArgumentException computerRequiresMoreWorkersThanSupported(final int workers, final int maxWorkers) { return new IllegalArgumentException("The computer requires more workers than supported: " + workers + " [max:" + maxWorkers + "]"); } public static IllegalArgumentException vertexFilterAccessesIncidentEdges(final Traversal<Vertex, Vertex> vertexFilter) { return new IllegalArgumentException("The provided vertex filter traversal accesses incident edges: " + vertexFilter); } public static IllegalArgumentException edgeFilterAccessesAdjacentVertices(final Traversal<Vertex, Edge> edgeFilter) { return new IllegalArgumentException("The provided edge filter traversal accesses data on adjacent vertices: " + edgeFilter); } } }