You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tinkerpop.apache.org by sp...@apache.org on 2015/02/12 14:02:05 UTC
[39/77] [partial] incubator-tinkerpop git commit: moved com/tinkerpop
directories to org/apache/tinkerpop
http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/1545201f/gremlin-core/src/main/java/com/tinkerpop/gremlin/process/graph/traversal/step/map/SelectStep.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/com/tinkerpop/gremlin/process/graph/traversal/step/map/SelectStep.java b/gremlin-core/src/main/java/com/tinkerpop/gremlin/process/graph/traversal/step/map/SelectStep.java
deleted file mode 100644
index 086ab9b..0000000
--- a/gremlin-core/src/main/java/com/tinkerpop/gremlin/process/graph/traversal/step/map/SelectStep.java
+++ /dev/null
@@ -1,132 +0,0 @@
-/*
- * 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 com.tinkerpop.gremlin.process.graph.traversal.step.map;
-
-import com.tinkerpop.gremlin.process.Path;
-import com.tinkerpop.gremlin.process.Traversal;
-import com.tinkerpop.gremlin.process.TraversalEngine;
-import com.tinkerpop.gremlin.process.Traverser;
-import com.tinkerpop.gremlin.process.graph.traversal.step.util.CollectingBarrierStep;
-import com.tinkerpop.gremlin.process.traversal.step.EngineDependent;
-import com.tinkerpop.gremlin.process.traversal.step.TraversalParent;
-import com.tinkerpop.gremlin.process.traversal.util.TraversalHelper;
-import com.tinkerpop.gremlin.process.traversal.util.TraversalRing;
-import com.tinkerpop.gremlin.process.traversal.util.TraversalUtil;
-import com.tinkerpop.gremlin.process.traverser.TraverserRequirement;
-
-import java.util.Arrays;
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.function.Function;
-
-/**
- * @author Marko A. Rodriguez (http://markorodriguez.com)
- */
-public final class SelectStep<S, E> extends MapStep<S, Map<String, E>> implements TraversalParent, EngineDependent {
-
- protected TraversalRing<Object, Object> traversalRing = new TraversalRing<>();
- private final List<String> selectLabels;
- private final boolean wasEmpty;
- private boolean requiresPaths = false;
-
- public SelectStep(final Traversal.Admin traversal, final String... selectLabels) {
- super(traversal);
- this.wasEmpty = selectLabels.length == 0;
- this.selectLabels = this.wasEmpty ? TraversalHelper.getLabelsUpTo(this, this.traversal) : Arrays.asList(selectLabels);
- }
-
- @Override
- protected Map<String, E> map(final Traverser.Admin<S> traverser) {
- final S start = traverser.get();
- final Map<String, E> bindings = new LinkedHashMap<>();
-
- ////// PROCESS STEP BINDINGS
- final Path path = traverser.path();
- this.selectLabels.forEach(label -> {
- if (path.hasLabel(label))
- bindings.put(label, (E) TraversalUtil.apply(path.<Object>get(label), this.traversalRing.next()));
- });
-
- ////// PROCESS MAP BINDINGS
- if (start instanceof Map) {
- if (this.wasEmpty)
- ((Map<String, Object>) start).forEach((k, v) -> bindings.put(k, (E) TraversalUtil.apply(v, this.traversalRing.next())));
- else
- this.selectLabels.forEach(label -> {
- if (((Map) start).containsKey(label)) {
- bindings.put(label, (E) TraversalUtil.apply(((Map) start).get(label), this.traversalRing.next()));
- }
- });
- }
-
- this.traversalRing.reset();
- return bindings;
- }
-
- @Override
- public void reset() {
- super.reset();
- this.traversalRing.reset();
- }
-
- @Override
- public void onEngine(final TraversalEngine traversalEngine) {
- this.requiresPaths = traversalEngine.equals(TraversalEngine.COMPUTER) ?
- TraversalHelper.getLabelsUpTo(this, this.traversal.asAdmin()).stream().filter(this.selectLabels::contains).findAny().isPresent() :
- TraversalHelper.getStepsUpTo(this, this.traversal.asAdmin()).stream()
- .filter(step -> step instanceof CollectingBarrierStep)
- .filter(step -> TraversalHelper.getLabelsUpTo(step, this.traversal.asAdmin()).stream().filter(this.selectLabels::contains).findAny().isPresent()
- || (step.getLabel().isPresent() && this.selectLabels.contains(step.getLabel().get()))) // TODO: get rid of this (there is a test case to check it)
- .findAny().isPresent();
- }
-
- @Override
- public String toString() {
- return TraversalHelper.makeStepString(this, this.selectLabels, this.traversalRing);
- }
-
- @Override
- public SelectStep<S, E> clone() throws CloneNotSupportedException {
- final SelectStep<S, E> clone = (SelectStep<S, E>) super.clone();
- clone.traversalRing = new TraversalRing<>();
- for (final Traversal.Admin<Object, Object> traversal : this.traversalRing.getTraversals()) {
- clone.traversalRing.addTraversal(clone.integrateChild(traversal.clone(), TYPICAL_LOCAL_OPERATIONS));
- }
- return clone;
- }
-
- @Override
- public List<Traversal.Admin<Object, Object>> getLocalChildren() {
- return this.traversalRing.getTraversals();
- }
-
- @Override
- public void addLocalChild(final Traversal.Admin<?, ?> selectTraversal) {
- this.traversalRing.addTraversal(this.integrateChild(selectTraversal, TYPICAL_LOCAL_OPERATIONS));
- }
-
- @Override
- public Set<TraverserRequirement> getRequirements() {
- final Set<TraverserRequirement> requirements = this.getSelfAndChildRequirements(TraverserRequirement.OBJECT, TraverserRequirement.PATH_ACCESS);
- if (this.requiresPaths) requirements.add(TraverserRequirement.PATH);
- return requirements;
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/1545201f/gremlin-core/src/main/java/com/tinkerpop/gremlin/process/graph/traversal/step/map/SumStep.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/com/tinkerpop/gremlin/process/graph/traversal/step/map/SumStep.java b/gremlin-core/src/main/java/com/tinkerpop/gremlin/process/graph/traversal/step/map/SumStep.java
deleted file mode 100644
index 0278b15..0000000
--- a/gremlin-core/src/main/java/com/tinkerpop/gremlin/process/graph/traversal/step/map/SumStep.java
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * 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 com.tinkerpop.gremlin.process.graph.traversal.step.map;
-
-import com.tinkerpop.gremlin.process.Traversal;
-import com.tinkerpop.gremlin.process.Traverser;
-import com.tinkerpop.gremlin.process.graph.traversal.step.util.ReducingBarrierStep;
-import com.tinkerpop.gremlin.process.traversal.step.Reducing;
-import com.tinkerpop.gremlin.process.traverser.TraverserRequirement;
-import com.tinkerpop.gremlin.util.function.ConstantSupplier;
-
-import java.io.Serializable;
-import java.util.EnumSet;
-import java.util.Set;
-import java.util.function.BiFunction;
-
-/**
- * @author Marko A. Rodriguez (http://markorodriguez.com)
- */
-public final class SumStep extends ReducingBarrierStep<Number, Double> implements Reducing<Double, Traverser<Number>> {
-
- private static final Set<TraverserRequirement> REQUIREMENTS = EnumSet.of(
- TraverserRequirement.BULK,
- TraverserRequirement.OBJECT
- );
-
- public SumStep(final Traversal.Admin traversal) {
- super(traversal);
- this.setSeedSupplier(new ConstantSupplier<>(0.0d));
- this.setBiFunction(SumBiFunction.instance());
- }
-
-
- @Override
- public Set<TraverserRequirement> getRequirements() {
- return REQUIREMENTS;
- }
-
- @Override
- public Reducer<Double, Traverser<Number>> getReducer() {
- return new Reducer<>(this.getSeedSupplier(), this.getBiFunction(), true);
- }
-
- /////
-
- private static class SumBiFunction<S extends Number> implements BiFunction<Double, Traverser<S>, Double>, Serializable {
-
- private static final SumBiFunction INSTANCE = new SumBiFunction();
-
- private SumBiFunction() {
-
- }
-
- @Override
- public Double apply(final Double mutatingSeed, final Traverser<S> traverser) {
- return mutatingSeed + (traverser.get().doubleValue() * traverser.bulk());
- }
-
- public final static <S extends Number> SumBiFunction<S> instance() {
- return INSTANCE;
- }
- }
-}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/1545201f/gremlin-core/src/main/java/com/tinkerpop/gremlin/process/graph/traversal/step/map/UnfoldStep.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/com/tinkerpop/gremlin/process/graph/traversal/step/map/UnfoldStep.java b/gremlin-core/src/main/java/com/tinkerpop/gremlin/process/graph/traversal/step/map/UnfoldStep.java
deleted file mode 100644
index 90b35ca..0000000
--- a/gremlin-core/src/main/java/com/tinkerpop/gremlin/process/graph/traversal/step/map/UnfoldStep.java
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * 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 com.tinkerpop.gremlin.process.graph.traversal.step.map;
-
-import com.tinkerpop.gremlin.process.Traversal;
-import com.tinkerpop.gremlin.process.Traverser;
-import com.tinkerpop.gremlin.process.traverser.TraverserRequirement;
-import com.tinkerpop.gremlin.util.iterator.IteratorUtils;
-
-import java.util.Collections;
-import java.util.Iterator;
-import java.util.Map;
-import java.util.Set;
-
-/**
- * @author Marko A. Rodriguez (http://markorodriguez.com)
- */
-public final class UnfoldStep<S, E> extends FlatMapStep<S, E> {
-
- public UnfoldStep(final Traversal.Admin traversal) {
- super(traversal);
- }
-
- @Override
- protected Iterator<E> flatMap(final Traverser.Admin<S> traverser) {
- final S s = traverser.get();
- if (s instanceof Iterator)
- return (Iterator) s;
- else if (s instanceof Iterable)
- return ((Iterable) s).iterator();
- else if (s instanceof Map)
- return ((Map) s).entrySet().iterator();
- else
- return IteratorUtils.of((E) s);
- }
-
- @Override
- public Set<TraverserRequirement> getRequirements() {
- return Collections.singleton(TraverserRequirement.OBJECT);
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/1545201f/gremlin-core/src/main/java/com/tinkerpop/gremlin/process/graph/traversal/step/map/VertexStep.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/com/tinkerpop/gremlin/process/graph/traversal/step/map/VertexStep.java b/gremlin-core/src/main/java/com/tinkerpop/gremlin/process/graph/traversal/step/map/VertexStep.java
deleted file mode 100644
index 111f7f4..0000000
--- a/gremlin-core/src/main/java/com/tinkerpop/gremlin/process/graph/traversal/step/map/VertexStep.java
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
- * 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 com.tinkerpop.gremlin.process.graph.traversal.step.map;
-
-import com.tinkerpop.gremlin.process.Traversal;
-import com.tinkerpop.gremlin.process.Traverser;
-import com.tinkerpop.gremlin.process.traversal.step.Reversible;
-import com.tinkerpop.gremlin.process.traversal.util.TraversalHelper;
-import com.tinkerpop.gremlin.process.traverser.TraverserRequirement;
-import com.tinkerpop.gremlin.structure.Direction;
-import com.tinkerpop.gremlin.structure.Element;
-import com.tinkerpop.gremlin.structure.Vertex;
-
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.Iterator;
-import java.util.Set;
-
-/**
- * @author Marko A. Rodriguez (http://markorodriguez.com)
- */
-public class VertexStep<E extends Element> extends FlatMapStep<Vertex, E> implements Reversible {
-
- private final String[] edgeLabels;
- private Direction direction;
- private final Class<E> returnClass;
-
- public VertexStep(final Traversal.Admin traversal, final Class<E> returnClass, final Direction direction, final String... edgeLabels) {
- super(traversal);
- this.direction = direction;
- this.edgeLabels = edgeLabels;
- this.returnClass = returnClass;
- }
-
- @Override
- protected Iterator<E> flatMap(final Traverser.Admin<Vertex> traverser) {
- return Vertex.class.isAssignableFrom(this.returnClass) ?
- (Iterator<E>) traverser.get().iterators().vertexIterator(this.direction, this.edgeLabels) :
- (Iterator<E>) traverser.get().iterators().edgeIterator(this.direction, this.edgeLabels);
- }
-
- @Override
- public void reverse() {
- this.direction = this.direction.opposite();
- }
-
- public Direction getDirection() {
- return this.direction;
- }
-
- public String[] getEdgeLabels() {
- return this.edgeLabels;
- }
-
- public Class<E> getReturnClass() {
- return this.returnClass;
- }
-
- @Override
- public String toString() {
- return TraversalHelper.makeStepString(this, this.direction, Arrays.asList(this.edgeLabels), this.returnClass.getSimpleName().toLowerCase());
- }
-
- @Override
- public Set<TraverserRequirement> getRequirements() {
- return Collections.singleton(TraverserRequirement.OBJECT);
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/1545201f/gremlin-core/src/main/java/com/tinkerpop/gremlin/process/graph/traversal/step/map/match/Bindings.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/com/tinkerpop/gremlin/process/graph/traversal/step/map/match/Bindings.java b/gremlin-core/src/main/java/com/tinkerpop/gremlin/process/graph/traversal/step/map/match/Bindings.java
deleted file mode 100644
index 89a9f20..0000000
--- a/gremlin-core/src/main/java/com/tinkerpop/gremlin/process/graph/traversal/step/map/match/Bindings.java
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * 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 com.tinkerpop.gremlin.process.graph.traversal.step.map.match;
-
-import java.util.Comparator;
-import java.util.Iterator;
-import java.util.Map;
-import java.util.SortedMap;
-import java.util.TreeMap;
-import java.util.function.Function;
-
-/**
- * @author Joshua Shinavier (http://fortytwo.net)
- */
-public class Bindings<T> {
- private final SortedMap<String, T> map = new TreeMap<>();
-
- public Bindings() {
- }
-
- public Bindings(final Map<String, T> map) {
- this.map.putAll(map);
- }
-
- public Bindings<T> put(final String name, final T value) {
- map.put(name, value);
- return this;
- }
-
- @Override
- public String toString() {
- StringBuilder sb = new StringBuilder("{");
- boolean first = true;
- for (Map.Entry<String, T> entry : map.entrySet()) {
- if (first) first = false;
- else sb.append(", ");
- sb.append(entry.getKey()).append(':').append(entry.getValue());
- }
- sb.append('}');
- return sb.toString();
- }
-
- public static class BindingsComparator<T> implements Comparator<Bindings<T>> {
- private final Function<T, String> toStringFunction;
-
- public BindingsComparator(Function<T, String> toStringFunction) {
- this.toStringFunction = toStringFunction;
- }
-
- @Override
- public int compare(Bindings<T> left, Bindings<T> right) {
- int cmp = ((Integer) left.map.size()).compareTo(right.map.size());
- if (0 != cmp) return cmp;
-
- Iterator<Map.Entry<String, T>> i1 = left.map.entrySet().iterator();
- Iterator<Map.Entry<String, T>> i2 = right.map.entrySet().iterator();
- while (i1.hasNext()) {
- Map.Entry<String, T> e1 = i1.next();
- Map.Entry<String, T> e2 = i2.next();
-
- cmp = e1.getKey().compareTo(e1.getKey());
- if (0 != cmp) return cmp;
-
- cmp = e1.getValue().toString().compareTo(e2.getValue().toString());
- if (0 != cmp) return cmp;
- }
-
- return 0;
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/1545201f/gremlin-core/src/main/java/com/tinkerpop/gremlin/process/graph/traversal/step/map/match/CrossJoinEnumerator.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/com/tinkerpop/gremlin/process/graph/traversal/step/map/match/CrossJoinEnumerator.java b/gremlin-core/src/main/java/com/tinkerpop/gremlin/process/graph/traversal/step/map/match/CrossJoinEnumerator.java
deleted file mode 100644
index 782f7d6..0000000
--- a/gremlin-core/src/main/java/com/tinkerpop/gremlin/process/graph/traversal/step/map/match/CrossJoinEnumerator.java
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
- * 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 com.tinkerpop.gremlin.process.graph.traversal.step.map.match;
-
-import java.util.function.BiConsumer;
-
-/**
- * An Enumerator which finds the Cartesian product of two other Enumerators,
- * expanding at the same rate in either dimension.
- * This maximizes the size of the product with respect to the number of expansions of the base Enumerators.
- */
-public class CrossJoinEnumerator<T> implements Enumerator<T> {
-
- private final Enumerator<T> xEnum, yEnum;
-
- public CrossJoinEnumerator(final Enumerator<T> xEnum,
- final Enumerator<T> yEnum) {
- this.xEnum = xEnum;
- this.yEnum = yEnum;
- }
-
- public int size() {
- return xEnum.size() * yEnum.size();
- }
-
- // note: permits random access
- public boolean visitSolution(final int index,
- final BiConsumer<String, T> visitor) {
- int sq = (int) Math.sqrt(index);
-
- // choose x and y such that the solution represented by index
- // remains constant as this Enumerator expands
- int x, y;
-
- if (0 == index) {
- x = y = 0;
- } else {
- int r = index - sq * sq;
- if (r < sq) {
- x = sq;
- y = r;
- } else {
- x = r - sq;
- y = sq;
- }
- }
-
- // expand x if necessary
- if (!hasIndex(xEnum, sq)) {
- if (0 == xEnum.size()) {
- return false;
- }
-
- x = index % xEnum.size();
- y = index / xEnum.size();
- }
-
- // expand y if necessary
- if (!hasIndex(yEnum, y)) {
- int height = yEnum.size();
- if (0 == height) {
- return false;
- }
-
- x = index / height;
- if (!hasIndex(xEnum, x)) {
- return false;
- }
- y = index % height;
- }
-
- // solutions are visited completely (if we have reached this point), else not at all
- return xEnum.visitSolution(x, visitor) && yEnum.visitSolution(y, visitor);
- }
-
- private boolean hasIndex(final Enumerator<T> e,
- final int index) {
- return index < e.size() || e.visitSolution(index, (BiConsumer<String, T>) MatchStep.TRIVIAL_CONSUMER);
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/1545201f/gremlin-core/src/main/java/com/tinkerpop/gremlin/process/graph/traversal/step/map/match/Enumerator.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/com/tinkerpop/gremlin/process/graph/traversal/step/map/match/Enumerator.java b/gremlin-core/src/main/java/com/tinkerpop/gremlin/process/graph/traversal/step/map/match/Enumerator.java
deleted file mode 100644
index d374d01..0000000
--- a/gremlin-core/src/main/java/com/tinkerpop/gremlin/process/graph/traversal/step/map/match/Enumerator.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * 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 com.tinkerpop.gremlin.process.graph.traversal.step.map.match;
-
-import java.util.function.BiConsumer;
-
-/**
- * An array of key/value maps accessible by index.
- * The total size of the enumerator may be unknown when it is created;
- * it grows when successive solutions are requested, computing as many as necessary.
- *
- * @author Joshua Shinavier (http://fortytwo.net)
- */
-public interface Enumerator<T> {
-
- /**
- * @return the number of solutions so far known; the enumerator has at least this many.
- * This should be a relatively cheap operation.
- */
- int size();
-
- /**
- * Provides access to a solution, allowing it to be printed, put into a map, etc.
- *
- * @param index the index of the solution
- * @param visitor a consumer for each key/value pair in the solution
- * @return whether a solution exists at the given index and was visited
- */
- boolean visitSolution(int index, BiConsumer<String, T> visitor);
-}
http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/1545201f/gremlin-core/src/main/java/com/tinkerpop/gremlin/process/graph/traversal/step/map/match/InnerJoinEnumerator.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/com/tinkerpop/gremlin/process/graph/traversal/step/map/match/InnerJoinEnumerator.java b/gremlin-core/src/main/java/com/tinkerpop/gremlin/process/graph/traversal/step/map/match/InnerJoinEnumerator.java
deleted file mode 100644
index 03200f8..0000000
--- a/gremlin-core/src/main/java/com/tinkerpop/gremlin/process/graph/traversal/step/map/match/InnerJoinEnumerator.java
+++ /dev/null
@@ -1,129 +0,0 @@
-/*
- * 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 com.tinkerpop.gremlin.process.graph.traversal.step.map.match;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.function.BiConsumer;
-
-/**
- * An Enumerator which joins the solutions of a base Enumerator according to repeated variables
- * <p/>
- * Note: this Enumerator requires random access to its base Enumerator,
- * as it maintains a list of indices at which valid solutions are found, and visits only those indices.
- *
- * @author Joshua Shinavier (http://fortytwo.net)
- */
-public class InnerJoinEnumerator<T> implements Enumerator<T> {
- private final Enumerator<T> baseEnumerator;
- private Iterator<Integer> iterator;
- private final List<Integer> joinIndices;
-
- private final Map<String, T> map;
- private final BiConsumer<String, T> joinVisitor;
-
- private int joinCount;
-
- public InnerJoinEnumerator(final Enumerator<T> baseEnumerator,
- final Set<String> joinVariables) {
-
- this.baseEnumerator = baseEnumerator;
- this.joinIndices = new ArrayList<>();
-
- map = new HashMap<>();
- // TODO: allow for more than two instances of a variable
- joinVisitor = (name, newValue) -> {
- if (joinVariables.contains(name)) {
- T value = map.get(name);
- if (null == value) {
- map.put(name, newValue);
- } else if (value.equals(newValue)) {
- joinCount++;
- }
- } else {
- map.put(name, newValue);
- }
- };
-
- iterator = new Iterator<Integer>() {
- private int currentIndex = -1;
-
- {
- advanceToNext();
- }
-
- public boolean hasNext() {
- // there are no calls to this method
- return false;
- }
-
- public Integer next() {
- int tmp = currentIndex;
- advanceToNext();
- return tmp;
- }
-
- private void advanceToNext() {
- while (true) {
- map.clear();
- joinCount = 0;
-
- if (!baseEnumerator.visitSolution(++currentIndex, joinVisitor)) {
- iterator = null;
- return;
- }
-
- if (joinVariables.size() == joinCount) {
- joinIndices.add(currentIndex);
- return;
- }
- }
- }
- };
- }
-
- public int size() {
- return joinIndices.size();
- }
-
- public boolean visitSolution(int i, BiConsumer<String, T> visitor) {
- while (i >= joinIndices.size()) {
- if (null == iterator) {
- return false;
- }
-
- iterator.next();
- }
-
- map.clear();
- if (!baseEnumerator.visitSolution(joinIndices.get(i), joinVisitor)) {
- throw new IllegalStateException();
- }
-
- for (Map.Entry<String, T> entry : map.entrySet()) {
- visitor.accept(entry.getKey(), entry.getValue());
- }
-
- return true;
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/1545201f/gremlin-core/src/main/java/com/tinkerpop/gremlin/process/graph/traversal/step/map/match/IteratorEnumerator.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/com/tinkerpop/gremlin/process/graph/traversal/step/map/match/IteratorEnumerator.java b/gremlin-core/src/main/java/com/tinkerpop/gremlin/process/graph/traversal/step/map/match/IteratorEnumerator.java
deleted file mode 100644
index 8687928..0000000
--- a/gremlin-core/src/main/java/com/tinkerpop/gremlin/process/graph/traversal/step/map/match/IteratorEnumerator.java
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * 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 com.tinkerpop.gremlin.process.graph.traversal.step.map.match;
-
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
-import java.util.function.BiConsumer;
-
-/**
- * @author Joshua Shinavier (http://fortytwo.net)
- */
-public class IteratorEnumerator<T> implements Enumerator<T> {
- private final String name;
- private Iterator<T> iterator;
- private final List<T> memory = new ArrayList<>();
-
- public IteratorEnumerator(final String name,
- final Iterator<T> iterator) {
- this.name = name;
- this.iterator = iterator;
- }
-
- public int size() {
- return memory.size();
- }
-
- public boolean visitSolution(final int index,
- final BiConsumer<String, T> visitor) {
- T value;
-
- if (index < memory.size()) {
- value = memory.get(index);
- } else do {
- if (null == iterator) {
- return false;
- } else if (!iterator.hasNext()) {
- // free up memory as soon as possible
- iterator = null;
- return false;
- }
-
- value = iterator.next();
- memory.add(value);
- } while (index >= memory.size());
-
- MatchStep.visit(name, value, visitor);
-
- return true;
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/1545201f/gremlin-core/src/main/java/com/tinkerpop/gremlin/process/graph/traversal/step/map/match/MatchStep.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/com/tinkerpop/gremlin/process/graph/traversal/step/map/match/MatchStep.java b/gremlin-core/src/main/java/com/tinkerpop/gremlin/process/graph/traversal/step/map/match/MatchStep.java
deleted file mode 100644
index 7928345..0000000
--- a/gremlin-core/src/main/java/com/tinkerpop/gremlin/process/graph/traversal/step/map/match/MatchStep.java
+++ /dev/null
@@ -1,559 +0,0 @@
-/*
- * 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 com.tinkerpop.gremlin.process.graph.traversal.step.map.match;
-
-import com.tinkerpop.gremlin.process.FastNoSuchElementException;
-import com.tinkerpop.gremlin.process.Traversal;
-import com.tinkerpop.gremlin.process.Traverser;
-import com.tinkerpop.gremlin.process.traversal.step.AbstractStep;
-import com.tinkerpop.gremlin.process.traversal.step.TraversalParent;
-import com.tinkerpop.gremlin.process.traversal.util.TraversalHelper;
-import com.tinkerpop.gremlin.process.traverser.B_O_PA_S_SE_SL_Traverser;
-import com.tinkerpop.gremlin.process.traverser.TraverserRequirement;
-import com.tinkerpop.gremlin.util.iterator.IteratorUtils;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
-import java.util.NoSuchElementException;
-import java.util.Set;
-import java.util.Stack;
-import java.util.function.BiConsumer;
-import java.util.function.Consumer;
-import java.util.function.Function;
-
-/**
- * @author Joshua Shinavier (http://fortytwo.net)
- */
-public final class MatchStep<S, E> extends AbstractStep<S, Map<String, E>> implements TraversalParent {
-
- static final BiConsumer<String, Object> TRIVIAL_CONSUMER = (s, t) -> {
- };
-
- private static final String ANON_LABEL_PREFIX = "_";
-
- // optimize before processing each start object, by default
- private static final int DEFAULT_STARTS_PER_OPTIMIZE = 1;
-
- private final String startLabel;
- private final Map<String, List<TraversalWrapper<S, S>>> traversalsByStartAs;
- private final List<Traversal> traversals = new ArrayList<>();
-
- private int startsPerOptimize = DEFAULT_STARTS_PER_OPTIMIZE;
- private int optimizeCounter = -1;
- private int anonLabelCounter = 0;
-
- private Enumerator<S> currentSolution;
- private int currentIndex;
-
- // initial value allows MatchStep to be used as a stand-alone query engine
- private Traverser.Admin<S> currentStart;
-
- public MatchStep(final Traversal.Admin traversal, final String startLabel, final Traversal... traversals) {
- super(traversal);
- this.startLabel = startLabel;
- this.traversalsByStartAs = new HashMap<>();
- this.currentStart = new B_O_PA_S_SE_SL_Traverser<>(null, this);
- for (final Traversal tl : traversals) {
- addTraversalPrivate(tl);
- this.integrateChild(tl.asAdmin(), TYPICAL_LOCAL_OPERATIONS);
- this.traversals.add(tl);
- }
- checkSolvability();
- }
-
- @Override
- public Set<TraverserRequirement> getRequirements() {
- return this.getSelfAndChildRequirements();
- }
-
- @Override
- public String toString() {
- return TraversalHelper.makeStepString(this, this.traversalsByStartAs);
- }
-
- /**
- * Adds an individual traversal to an already-constructed MatchStep.
- * The query must be solvable after addition (i.e. should not require the addition of
- * further traversals in order to be solvable)
- * This method should be called before the query is first executed.
- *
- * @param traversal the traversal to add
- */
- public void addTraversal(final Traversal<S, S> traversal) {
- addTraversalPrivate(traversal);
- this.traversals.add(traversal);
- this.integrateChild(traversal.asAdmin(), TYPICAL_LOCAL_OPERATIONS);
- checkSolvability();
- }
-
- public void setStartsPerOptimize(final int startsPerOptimize) {
- if (startsPerOptimize < 1) {
- throw new IllegalArgumentException();
- }
- this.startsPerOptimize = startsPerOptimize;
- }
-
- @Override
- protected Traverser<Map<String, E>> processNextStart() throws NoSuchElementException {
- final Map<String, E> map = new HashMap<>();
- final Traverser<Map<String, E>> result = this.currentStart.split(map, this);
- final BiConsumer<String, S> resultSetter = (name, value) -> map.put(name, (E) value);
-
- while (true) { // break out when the current solution is exhausted and there are no more starts
- if (null == this.currentSolution) {
- if (this.starts.hasNext()) {
- this.optimizeCounter = (this.optimizeCounter + 1) % this.startsPerOptimize;
- if (0 == this.optimizeCounter) {
- optimize();
- }
-
- this.currentStart = this.starts.next();
- this.currentSolution = solveFor(IteratorUtils.of(this.currentStart.get()));
- this.currentIndex = 0;
- } else {
- throw FastNoSuchElementException.instance();
- }
- }
-
- map.clear();
- if (this.currentSolution.visitSolution(this.currentIndex++, resultSetter)) {
- return result;
- } else {
- this.currentSolution = null;
- }
- }
- }
-
- /**
- * @return a description of the current state of this step, including the query plan and gathered statistics
- */
- public String summarize() {
- final StringBuilder sb = new StringBuilder("match \"")
- .append(this.startLabel)
- .append("\":\t")
- .append(findCost(this.startLabel))
- .append('\n');
- summarize(this.startLabel, sb, new HashSet<>(), 1);
- return sb.toString();
- }
-
- private void summarize(final String outLabel,
- final StringBuilder sb,
- final Set<String> visited,
- final int indent) {
- if (!visited.contains(outLabel)) {
- visited.add(outLabel);
- final List<TraversalWrapper<S, S>> outs = traversalsByStartAs.get(outLabel);
- if (null != outs) {
- for (final TraversalWrapper<S, S> w : outs) {
- for (int i = 0; i < indent; i++) sb.append('\t');
- sb.append(outLabel).append("->").append(w.endLabel).append(":\t");
- sb.append(findCost(w));
- sb.append('\t').append(w);
- sb.append('\n');
- summarize(w.endLabel, sb, visited, indent + 1);
- }
- }
- }
- }
-
- private void addTraversalPrivate(final Traversal<S, S> traversal) {
-
- String startAs = traversal.asAdmin().getStartStep().getLabel().orElseThrow(()
- -> new IllegalArgumentException("All match traversals must have their start step labeled with as()"));
- String endAs = traversal.asAdmin().getEndStep().getLabel().orElse(null);
- checkAs(startAs);
- if (null == endAs) {
- endAs = createAnonymousAs();
- } else {
- checkAs(endAs);
- }
-
- final TraversalWrapper<S, S> wrapper = new TraversalWrapper<>(traversal, startAs, endAs);
- // index all wrapped traversals by their startLabel
- List<TraversalWrapper<S, S>> l2 = this.traversalsByStartAs.get(startAs);
- if (null == l2) {
- l2 = new LinkedList<>();
- this.traversalsByStartAs.put(startAs, l2);
- }
- l2.add(wrapper);
- }
-
- // given all the wrapped traversals, determine bad patterns in the set and throw exceptions if not solvable
- private void checkSolvability() {
- final Set<String> pathSet = new HashSet<>();
- final Stack<String> stack = new Stack<>();
- stack.push(this.startLabel);
- int countTraversals = 0;
- while (!stack.isEmpty()) {
- final String outAs = stack.peek();
- if (pathSet.contains(outAs)) {
- stack.pop();
- pathSet.remove(outAs);
- } else {
- pathSet.add(outAs);
- final List<TraversalWrapper<S, S>> l = traversalsByStartAs.get(outAs);
- if (null != l) {
- for (final TraversalWrapper<S, S> tw : l) {
- countTraversals++;
- if (pathSet.contains(tw.endLabel)) {
- throw new IllegalArgumentException("The provided traversal set contains a cycle due to '"
- + tw.endLabel + '\'');
- }
- stack.push(tw.endLabel);
- }
- }
- }
- }
-
- int totalTraversals = 0;
- for (List<TraversalWrapper<S, S>> l : this.traversalsByStartAs.values()) {
- totalTraversals += l.size();
- }
-
- if (countTraversals < totalTraversals) {
- throw new IllegalArgumentException("The provided traversal set contains unreachable as-label(s)");
- }
- }
-
- private static void checkAs(final String as) {
- // note: this won't happen so long as the anon prefix is the same as Traversal.UNDERSCORE
- if (isAnonymousAs(as)) {
- throw new IllegalArgumentException("The step named '" + as + "' uses reserved prefix '"
- + ANON_LABEL_PREFIX + '\'');
- }
- }
-
- private static boolean isAnonymousAs(final String as) {
- return as.startsWith(ANON_LABEL_PREFIX);
- }
-
- private String createAnonymousAs() {
- return ANON_LABEL_PREFIX + ++this.anonLabelCounter;
- }
-
- /**
- * Directly applies this match query to a sequence of inputs
- *
- * @param inputs a sequence of inputs
- * @return an enumerator over all solutions
- */
- public Enumerator<S> solveFor(final Iterator<S> inputs) {
- return solveFor(startLabel, inputs);
- }
-
- private Enumerator<S> solveFor(final String localStartAs,
- final Iterator<S> inputs) {
- List<TraversalWrapper<S, S>> outs = traversalsByStartAs.get(localStartAs);
- if (null == outs) {
- // no out-traversals from here; just enumerate the values bound to localStartAs
- return isAnonymousAs(localStartAs)
- ? new SimpleEnumerator<>(localStartAs, inputs)
- : new IteratorEnumerator<>(localStartAs, inputs);
- } else {
- // for each value bound to localStartAs, feed it into all out-traversals in parallel and join the results
- return new SerialEnumerator<>(localStartAs, inputs, o -> {
- Enumerator<S> result = null;
- Set<String> leftLabels = new HashSet<>();
-
- for (TraversalWrapper<S, S> w : outs) {
- TraversalUpdater<S, S> updater
- = new TraversalUpdater<>(w, IteratorUtils.of(o), currentStart, this.getId());
-
- Set<String> rightLabels = new HashSet<>();
- addVariables(w.endLabel, rightLabels);
- Enumerator<S> ie = solveFor(w.endLabel, updater);
- result = null == result ? ie : crossJoin(result, ie, leftLabels, rightLabels);
- leftLabels.addAll(rightLabels);
- }
-
- return result;
- });
- }
- }
-
- private static <T> Enumerator<T> crossJoin(final Enumerator<T> left,
- final Enumerator<T> right,
- final Set<String> leftLabels,
- final Set<String> rightLabels) {
- Set<String> shared = new HashSet<>();
- for (String s : rightLabels) {
- if (leftLabels.contains(s)) {
- shared.add(s);
- }
- }
-
- Enumerator<T> cj = new CrossJoinEnumerator<>(left, right);
- return shared.size() > 0 ? new InnerJoinEnumerator<>(cj, shared) : cj;
- }
-
- // recursively add all non-anonymous variables from a starting point in the query
- private void addVariables(final String localStartAs,
- final Set<String> variables) {
- if (!isAnonymousAs(localStartAs)) {
- variables.add(localStartAs);
- }
-
- List<TraversalWrapper<S, S>> outs = traversalsByStartAs.get(localStartAs);
- if (null != outs) {
- for (TraversalWrapper<S, S> w : outs) {
- String endAs = w.endLabel;
- if (!variables.contains(endAs)) {
- addVariables(endAs, variables);
- }
- }
- }
- }
-
- // applies a visitor, skipping anonymous variables
- static <T> void visit(final String name,
- final T value,
- final BiConsumer<String, T> visitor) {
- if (!isAnonymousAs(name)) {
- visitor.accept(name, value);
- }
- }
-
- /**
- * Computes and applies a new query plan based on gathered statistics about traversal inputs and outputs.
- */
- // note: optimize() is never called from within a solution iterator, as it changes the query plan
- public void optimize() {
- optimizeAt(startLabel);
- }
-
- private void optimizeAt(final String outAs) {
- List<TraversalWrapper<S, S>> outs = traversalsByStartAs.get(outAs);
- if (null != outs) {
- for (TraversalWrapper<S, S> t : outs) {
- optimizeAt(t.endLabel);
- updateOrderingFactor(t);
- }
- Collections.sort(outs);
- }
- }
-
- private double findCost(final TraversalWrapper<S, S> root) {
- double bf = root.findBranchFactor();
- return bf + findCost(root.endLabel, root.findBranchFactor());
- }
-
- private double findCost(final String outAs,
- final double branchFactor) {
- double bf = branchFactor;
-
- double cost = 0;
-
- List<TraversalWrapper<S, S>> outs = traversalsByStartAs.get(outAs);
- if (null != outs) {
- for (TraversalWrapper<S, S> child : outs) {
- cost += bf * findCost(child);
- bf *= child.findBranchFactor();
- }
- }
-
- return cost;
- }
-
- /**
- * @param outLabel the out-label of one or more traversals in the query
- * @return the expected cost, in the current query plan, of applying the branch of the query plan at
- * the given out-label to one start value
- */
- public double findCost(final String outLabel) {
- return findCost(outLabel, 1.0);
- }
-
- private void updateOrderingFactor(final TraversalWrapper<S, S> w) {
- w.orderingFactor = ((w.findBranchFactor() - 1) / findCost(w));
- }
-
- @Override
- public List<Traversal> getLocalChildren() {
- return this.traversals;
- }
-
- /**
- * A wrapper for a traversal in a query which maintains statistics about the traversal as
- * it consumes inputs and produces outputs.
- * The "branch factor" of the traversal is an important factor in determining its place in the query plan.
- */
- // note: input and output counts are never "refreshed".
- // The position of a traversal in a query never changes, although its priority / likelihood of being executed does.
- // Priority in turn affects branch factor.
- // However, with sufficient inputs and optimizations,the branch factor is expected to converge on a stable value.
- public static class TraversalWrapper<A, B> implements Comparable<TraversalWrapper<A, B>> {
- private final Traversal<A, B> traversal;
- private final String startLabel, endLabel;
- private int totalInputs = 0;
- private int totalOutputs = 0;
- private double orderingFactor;
-
- public TraversalWrapper(final Traversal<A, B> traversal,
- final String startLabel,
- final String endLabel) {
- this.traversal = traversal;
- this.startLabel = startLabel;
- this.endLabel = endLabel;
- }
-
- public void incrementInputs() {
- this.totalInputs++;
- }
-
- public void incrementOutputs(int outputs) {
- this.totalOutputs += outputs;
- }
-
- // TODO: take variance into account, to avoid penalizing traversals for early encounters with super-inputs,
- // or simply for never having been tried
- public double findBranchFactor() {
- return 0 == this.totalInputs ? 1 : this.totalOutputs / ((double) this.totalInputs);
- }
-
- @Override
- public int compareTo(final TraversalWrapper<A, B> other) {
- return ((Double) this.orderingFactor).compareTo(other.orderingFactor);
- }
-
- public Traversal<A, B> getTraversal() {
- return this.traversal;
- }
-
- public void reset() {
- this.traversal.asAdmin().reset();
- }
-
- @Override
- public String toString() {
- return this.traversal.toString();
- //return "[" + this.startLabel + "->" + this.endLabel + "," + findBranchFactor() + ","
- // + this.totalInputs + "," + this.totalOutputs + "," + this.traversal + "]";
- }
- }
-
- /**
- * A helper object which wraps a traversal, submitting starts and counting results per start
- */
- public static class TraversalUpdater<A, B> implements Iterator<B> {
- private final TraversalWrapper<A, B> w;
- private int outputs = -1;
-
- public TraversalUpdater(final TraversalWrapper<A, B> w,
- final Iterator<A> inputs,
- final Traverser<A> start,
- final String as) {
- this.w = w;
-
- Iterator<A> seIter = new SideEffectIterator<>(inputs, ignored -> {
- // only increment traversal input and output counts once an input
- // has been completely processed by the traversal
- if (-1 != outputs) {
- w.incrementInputs();
- w.incrementOutputs(outputs);
- }
- outputs = 0;
- });
- Iterator<Traverser<A>> starts = new MapIterator<>(seIter,
- o -> {
- final Traverser.Admin<A> traverser = ((Traverser.Admin<A>) start).split();
- traverser.set((A) o);
- return traverser;
- });
-
- w.reset();
-
- // with the traversal "empty" and ready for re-use, add new starts
- w.traversal.asAdmin().addStarts(starts);
- }
-
- // note: may return true after first returning false (inheriting this behavior from e.g. DefaultTraversal)
- @Override
- public boolean hasNext() {
- return w.traversal.hasNext();
- }
-
- @Override
- public B next() {
- outputs++;
- B b = w.traversal.next();
-
- // immediately check hasNext(), possibly updating the traverser's statistics
- // even if we otherwise abandon the iterator
- w.traversal.hasNext();
-
- return b;
- }
- }
-
- // an iterator which executes a side-effect the first time hasNext() is called before a next()
- private static class SideEffectIterator<T> implements Iterator<T> {
- private final Consumer onHasNext;
- private final Iterator<T> baseIterator;
- private boolean ready = true;
-
- private SideEffectIterator(final Iterator<T> baseIterator,
- final Consumer onHasNext) {
- this.onHasNext = onHasNext;
- this.baseIterator = baseIterator;
- }
-
- @Override
- public boolean hasNext() {
- if (this.ready) {
- this.onHasNext.accept(null);
- this.ready = false;
- }
- return this.baseIterator.hasNext();
- }
-
- @Override
- public T next() {
- T value = this.baseIterator.next();
- this.ready = true;
- return value;
- }
- }
-
- private static class MapIterator<A, B> implements Iterator<B> {
- private final Function<A, B> map;
- private final Iterator<A> baseIterator;
-
- public MapIterator(final Iterator<A> baseIterator, final Function<A, B> map) {
- this.map = map;
- this.baseIterator = baseIterator;
- }
-
- @Override
- public boolean hasNext() {
- return this.baseIterator.hasNext();
- }
-
- @Override
- public B next() {
- return this.map.apply(this.baseIterator.next());
- }
- }
-}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/1545201f/gremlin-core/src/main/java/com/tinkerpop/gremlin/process/graph/traversal/step/map/match/SerialEnumerator.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/com/tinkerpop/gremlin/process/graph/traversal/step/map/match/SerialEnumerator.java b/gremlin-core/src/main/java/com/tinkerpop/gremlin/process/graph/traversal/step/map/match/SerialEnumerator.java
deleted file mode 100644
index 42570a3..0000000
--- a/gremlin-core/src/main/java/com/tinkerpop/gremlin/process/graph/traversal/step/map/match/SerialEnumerator.java
+++ /dev/null
@@ -1,119 +0,0 @@
-/*
- * 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 com.tinkerpop.gremlin.process.graph.traversal.step.map.match;
-
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
-import java.util.function.BiConsumer;
-import java.util.function.Function;
-
-/**
- * An enumerator which consumes values from an iterator and maps each value to a secondary enumerator
- * (for example, a join)
- * Enumerated indices cover all solutions in the secondary enumerators,
- * in ascending order according to the value iterator and the enumerators' own indices.
- *
- * @author Joshua Shinavier (http://fortytwo.net)
- */
-public class SerialEnumerator<T> implements Enumerator<T> {
- private final String name;
- private Iterator<T> iterator;
- private final Function<T, Enumerator<T>> constructor;
- private final List<Enumerator<T>> memory = new ArrayList<>();
- private final List<T> values = new ArrayList<>();
-
- // TODO: this only assigned, not accessed until the efficient implementation of size() is restored
- private int completedEnumsSize = 0;
-
- public SerialEnumerator(final String name,
- final Iterator<T> iterator,
- final Function<T, Enumerator<T>> constructor) {
- this.name = name;
- this.iterator = iterator;
- this.constructor = constructor;
- }
-
- public int size() {
- // TODO: restore the more efficient implementation of size() while taking into account that
- // traversal iterators such as DefaultTraversal may return hasNext=true after first returning hasNext=false
- /*
- int size = completedEnumsSize;
- if (!sideEffects.isEmpty()) {
- size += sideEffects.get(sideEffects.size() - 1).size();
- }
- return size;
- */
-
- //*
- int size = 0;
- for (Enumerator<T> e : memory) size += e.size();
- return size;
- //*/
- }
-
- // note: *not* intended for random access; use binary search if this is ever needed
- public boolean visitSolution(final int index,
- final BiConsumer<String, T> visitor) {
- int totalSize = 0;
- int memIndex = 0;
- while (true) {
- if (memIndex < memory.size()) {
- Enumerator<T> e = memory.get(memIndex);
-
- if (e.visitSolution(index - totalSize, visitor)) {
- // additionally, bind the value stored in this enumerator
- MatchStep.visit(name, values.get(memIndex), visitor);
-
- return true;
- } else {
- totalSize += e.size();
- memIndex++;
- }
- } else {
- if (null == iterator) {
- return false;
- } else if (!iterator.hasNext()) {
- // free up memory as soon as possible
- iterator = null;
- return false;
- }
-
- if (!memory.isEmpty()) {
- int lastSize = memory.get(memIndex - 1).size();
-
- // first remove the head enumeration if it exists and is empty
- // (only the head will ever be empty, avoiding wasted space)
- if (0 == lastSize) {
- memIndex--;
- memory.remove(memIndex);
- values.remove(memIndex);
- } else {
- completedEnumsSize += lastSize;
- }
- }
-
- T value = iterator.next();
- values.add(value);
- Enumerator<T> e = constructor.apply(value);
- memory.add(memory.size(), e);
- }
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/1545201f/gremlin-core/src/main/java/com/tinkerpop/gremlin/process/graph/traversal/step/map/match/SimpleEnumerator.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/com/tinkerpop/gremlin/process/graph/traversal/step/map/match/SimpleEnumerator.java b/gremlin-core/src/main/java/com/tinkerpop/gremlin/process/graph/traversal/step/map/match/SimpleEnumerator.java
deleted file mode 100644
index 4f1dd8e..0000000
--- a/gremlin-core/src/main/java/com/tinkerpop/gremlin/process/graph/traversal/step/map/match/SimpleEnumerator.java
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * 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 com.tinkerpop.gremlin.process.graph.traversal.step.map.match;
-
-import java.util.Iterator;
-import java.util.function.BiConsumer;
-
-/**
- * An enumerator of at most one element
- *
- * @author Joshua Shinavier (http://fortytwo.net)
- */
-public class SimpleEnumerator<T> implements Enumerator<T> {
-
- private final String name;
- private Iterator<T> iterator;
- private T element;
-
- public SimpleEnumerator(final String name,
- final Iterator<T> iterator) {
- this.name = name;
- this.iterator = iterator;
- }
-
- @Override
- public int size() {
- return null == element ? 0 : 1;
- }
-
- @Override
- public boolean visitSolution(int index, BiConsumer<String, T> visitor) {
- if (0 != index) {
- return false;
- }
-
- if (null != iterator) {
- if (iterator.hasNext()) {
- element = iterator.next();
- }
- iterator = null;
- }
-
- if (null != element) {
- MatchStep.visit(name, element, visitor);
- return true;
- }
-
- return false;
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/1545201f/gremlin-core/src/main/java/com/tinkerpop/gremlin/process/graph/traversal/step/sideEffect/AddEdgeStep.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/com/tinkerpop/gremlin/process/graph/traversal/step/sideEffect/AddEdgeStep.java b/gremlin-core/src/main/java/com/tinkerpop/gremlin/process/graph/traversal/step/sideEffect/AddEdgeStep.java
deleted file mode 100644
index 68f7049..0000000
--- a/gremlin-core/src/main/java/com/tinkerpop/gremlin/process/graph/traversal/step/sideEffect/AddEdgeStep.java
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * 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 com.tinkerpop.gremlin.process.graph.traversal.step.sideEffect;
-
-import com.tinkerpop.gremlin.process.Traversal;
-import com.tinkerpop.gremlin.process.Traverser;
-import com.tinkerpop.gremlin.process.traversal.step.Reversible;
-import com.tinkerpop.gremlin.process.traversal.util.TraversalHelper;
-import com.tinkerpop.gremlin.process.traverser.TraverserRequirement;
-import com.tinkerpop.gremlin.structure.Direction;
-import com.tinkerpop.gremlin.structure.Vertex;
-
-import java.util.EnumSet;
-import java.util.Set;
-
-/**
- * @author Marko A. Rodriguez (http://markorodriguez.com)
- */
-public final class AddEdgeStep extends SideEffectStep<Vertex> implements Reversible {
-
- private static final Set<TraverserRequirement> REQUIREMENTS = EnumSet.of(
- TraverserRequirement.PATH,
- TraverserRequirement.OBJECT
- );
-
- // TODO: Weight key based on Traverser.getCount() ?
-
- private final Direction direction;
- private final String edgeLabel;
- private final String stepLabel;
- private final Object[] propertyKeyValues;
-
- public AddEdgeStep(final Traversal.Admin traversal, final Direction direction, final String edgeLabel, final String stepLabel, final Object... propertyKeyValues) {
- super(traversal);
- this.direction = direction;
- this.edgeLabel = edgeLabel;
- this.stepLabel = stepLabel;
- this.propertyKeyValues = propertyKeyValues;
- }
-
- @Override
- protected void sideEffect(final Traverser.Admin<Vertex> traverser) {
- final Vertex currentVertex = traverser.get();
- final Vertex otherVertex = traverser.path().get(stepLabel);
- if (direction.equals(Direction.IN) || direction.equals(Direction.BOTH)) {
- otherVertex.addEdge(edgeLabel, currentVertex, this.propertyKeyValues);
- }
- if (direction.equals(Direction.OUT) || direction.equals(Direction.BOTH)) {
- currentVertex.addEdge(edgeLabel, otherVertex, this.propertyKeyValues);
- }
- }
-
- @Override
- public String toString() {
- return TraversalHelper.makeStepString(this, this.direction.name(), this.edgeLabel, this.stepLabel);
- }
-
- @Override
- public Set<TraverserRequirement> getRequirements() {
- return REQUIREMENTS;
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/1545201f/gremlin-core/src/main/java/com/tinkerpop/gremlin/process/graph/traversal/step/sideEffect/AggregateStep.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/com/tinkerpop/gremlin/process/graph/traversal/step/sideEffect/AggregateStep.java b/gremlin-core/src/main/java/com/tinkerpop/gremlin/process/graph/traversal/step/sideEffect/AggregateStep.java
deleted file mode 100644
index 7b289f9..0000000
--- a/gremlin-core/src/main/java/com/tinkerpop/gremlin/process/graph/traversal/step/sideEffect/AggregateStep.java
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
- * 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 com.tinkerpop.gremlin.process.graph.traversal.step.sideEffect;
-
-import com.tinkerpop.gremlin.process.Traversal;
-import com.tinkerpop.gremlin.process.computer.MapReduce;
-import com.tinkerpop.gremlin.process.graph.traversal.step.SideEffectCapable;
-import com.tinkerpop.gremlin.process.graph.traversal.step.sideEffect.mapreduce.AggregateMapReduce;
-import com.tinkerpop.gremlin.process.graph.traversal.step.util.CollectingBarrierStep;
-import com.tinkerpop.gremlin.process.traversal.lambda.IdentityTraversal;
-import com.tinkerpop.gremlin.process.traversal.step.MapReducer;
-import com.tinkerpop.gremlin.process.traversal.step.Reversible;
-import com.tinkerpop.gremlin.process.traversal.step.SideEffectRegistrar;
-import com.tinkerpop.gremlin.process.traversal.step.TraversalParent;
-import com.tinkerpop.gremlin.process.traversal.util.TraversalHelper;
-import com.tinkerpop.gremlin.process.traversal.util.TraversalUtil;
-import com.tinkerpop.gremlin.process.traverser.TraverserRequirement;
-import com.tinkerpop.gremlin.process.util.TraverserSet;
-import com.tinkerpop.gremlin.util.function.BulkSetSupplier;
-
-import java.util.Collection;
-import java.util.Collections;
-import java.util.List;
-import java.util.Set;
-
-/**
- * @author Marko A. Rodriguez (http://markorodriguez.com)
- */
-public final class AggregateStep<S> extends CollectingBarrierStep<S> implements SideEffectRegistrar, SideEffectCapable, Reversible, TraversalParent, MapReducer<MapReduce.NullObject, Object, MapReduce.NullObject, Object, Collection> {
-
- private Traversal.Admin<S, Object> aggregateTraversal = new IdentityTraversal<>();
- private String sideEffectKey;
-
- public AggregateStep(final Traversal.Admin traversal, final String sideEffectKey) {
- super(traversal);
- this.sideEffectKey = sideEffectKey;
- }
-
- @Override
- public void registerSideEffects() {
- if (null == this.sideEffectKey) this.sideEffectKey = this.getId();
- this.getTraversal().asAdmin().getSideEffects().registerSupplierIfAbsent(this.sideEffectKey, BulkSetSupplier.instance());
- }
-
- @Override
- public String getSideEffectKey() {
- return this.sideEffectKey;
- }
-
- @Override
- public String toString() {
- return TraversalHelper.makeStepString(this, this.sideEffectKey, this.aggregateTraversal);
- }
-
- @Override
- public MapReduce<MapReduce.NullObject, Object, MapReduce.NullObject, Object, Collection> getMapReduce() {
- return new AggregateMapReduce(this);
- }
-
- @Override
- public void addLocalChild(final Traversal.Admin<?, ?> traversal) {
- this.aggregateTraversal = this.integrateChild(traversal, TYPICAL_LOCAL_OPERATIONS);
- }
-
- @Override
- public List<Traversal.Admin<S, Object>> getLocalChildren() {
- return Collections.singletonList(this.aggregateTraversal);
- }
-
- @Override
- public void barrierConsumer(final TraverserSet<S> traverserSet) {
- traverserSet.forEach(traverser ->
- TraversalHelper.addToCollection(
- traverser.getSideEffects().get(this.sideEffectKey),
- TraversalUtil.apply(traverser, this.aggregateTraversal),
- traverser.bulk()));
- }
-
- @Override
- public Set<TraverserRequirement> getRequirements() {
- return this.getSelfAndChildRequirements(TraverserRequirement.BULK, TraverserRequirement.SIDE_EFFECTS);
- }
-
- @Override
- public AggregateStep<S> clone() throws CloneNotSupportedException {
- final AggregateStep<S> clone = (AggregateStep<S>) super.clone();
- clone.aggregateTraversal = this.integrateChild(this.aggregateTraversal.clone(), TYPICAL_LOCAL_OPERATIONS);
- return clone;
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/1545201f/gremlin-core/src/main/java/com/tinkerpop/gremlin/process/graph/traversal/step/sideEffect/GraphStep.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/com/tinkerpop/gremlin/process/graph/traversal/step/sideEffect/GraphStep.java b/gremlin-core/src/main/java/com/tinkerpop/gremlin/process/graph/traversal/step/sideEffect/GraphStep.java
deleted file mode 100644
index f698f3e..0000000
--- a/gremlin-core/src/main/java/com/tinkerpop/gremlin/process/graph/traversal/step/sideEffect/GraphStep.java
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- * 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 com.tinkerpop.gremlin.process.graph.traversal.step.sideEffect;
-
-import com.tinkerpop.gremlin.process.Traversal;
-import com.tinkerpop.gremlin.process.TraversalEngine;
-import com.tinkerpop.gremlin.process.Traverser;
-import com.tinkerpop.gremlin.process.traversal.step.EngineDependent;
-import com.tinkerpop.gremlin.process.traversal.util.TraversalHelper;
-import com.tinkerpop.gremlin.structure.Edge;
-import com.tinkerpop.gremlin.structure.Element;
-import com.tinkerpop.gremlin.structure.Graph;
-import com.tinkerpop.gremlin.structure.Vertex;
-import com.tinkerpop.gremlin.util.iterator.EmptyIterator;
-
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.Iterator;
-import java.util.function.Supplier;
-
-/**
- * @author Marko A. Rodriguez (http://markorodriguez.com)
- */
-public class GraphStep<S extends Element> extends StartStep<S> implements EngineDependent {
-
- protected final Class<S> returnClass;
- protected final Object[] ids;
- protected transient Graph graph;
- protected transient Supplier<Iterator<S>> iteratorSupplier;
-
- public GraphStep(final Traversal.Admin traversal, final Graph graph, final Class<S> returnClass, final Object... ids) {
- super(traversal);
- this.graph = graph;
- this.returnClass = returnClass;
- this.ids = ids;
- this.iteratorSupplier = () -> (Iterator<S>) (Vertex.class.isAssignableFrom(this.returnClass) ?
- this.graph.iterators().<S>vertexIterator(this.ids) :
- this.graph.iterators().edgeIterator(this.ids));
- }
-
- public String toString() {
- return TraversalHelper.makeStepString(this, Arrays.asList(this.ids), this.returnClass.getSimpleName().toLowerCase());
- }
-
- public boolean returnsVertices() {
- return Vertex.class.isAssignableFrom(this.returnClass);
- }
-
- public boolean returnsEdges() {
- return Edge.class.isAssignableFrom(this.returnClass);
- }
-
- public Class<S> getReturnClass() {
- return this.returnClass;
- }
-
- public void setIteratorSupplier(final Supplier<Iterator<S>> iteratorSupplier) {
- this.iteratorSupplier = iteratorSupplier;
- }
-
- public <G extends Graph> G getGraph(final Class<G> graphClass) {
- return (G) this.graph;
- }
-
- public Object[] getIds() {
- return this.ids;
- }
-
- @Override
- public void onEngine(final TraversalEngine traversalEngine) {
- if (traversalEngine.equals(TraversalEngine.COMPUTER)) {
- this.iteratorSupplier = Collections::emptyIterator;
- }
- }
-
- @Override
- protected Traverser<S> processNextStart() {
- if (this.first)
- this.start = null == this.iteratorSupplier ? EmptyIterator.instance() : this.iteratorSupplier.get();
- return super.processNextStart();
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/1545201f/gremlin-core/src/main/java/com/tinkerpop/gremlin/process/graph/traversal/step/sideEffect/GroupCountStep.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/com/tinkerpop/gremlin/process/graph/traversal/step/sideEffect/GroupCountStep.java b/gremlin-core/src/main/java/com/tinkerpop/gremlin/process/graph/traversal/step/sideEffect/GroupCountStep.java
deleted file mode 100644
index 288f7c8..0000000
--- a/gremlin-core/src/main/java/com/tinkerpop/gremlin/process/graph/traversal/step/sideEffect/GroupCountStep.java
+++ /dev/null
@@ -1,104 +0,0 @@
-/*
- * 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 com.tinkerpop.gremlin.process.graph.traversal.step.sideEffect;
-
-import com.tinkerpop.gremlin.process.Traversal;
-import com.tinkerpop.gremlin.process.Traverser;
-import com.tinkerpop.gremlin.process.computer.MapReduce;
-import com.tinkerpop.gremlin.process.graph.traversal.step.SideEffectCapable;
-import com.tinkerpop.gremlin.process.graph.traversal.step.sideEffect.mapreduce.GroupCountMapReduce;
-import com.tinkerpop.gremlin.process.traversal.lambda.IdentityTraversal;
-import com.tinkerpop.gremlin.process.traversal.step.MapReducer;
-import com.tinkerpop.gremlin.process.traversal.step.Reversible;
-import com.tinkerpop.gremlin.process.traversal.step.SideEffectRegistrar;
-import com.tinkerpop.gremlin.process.traversal.step.TraversalParent;
-import com.tinkerpop.gremlin.process.traversal.util.TraversalHelper;
-import com.tinkerpop.gremlin.process.traversal.util.TraversalUtil;
-import com.tinkerpop.gremlin.process.traverser.TraverserRequirement;
-import com.tinkerpop.gremlin.process.util.MapHelper;
-import com.tinkerpop.gremlin.util.function.HashMapSupplier;
-
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-/**
- * @author Marko A. Rodriguez (http://markorodriguez.com)
- */
-public final class GroupCountStep<S> extends SideEffectStep<S> implements SideEffectRegistrar, SideEffectCapable, Reversible, TraversalParent, MapReducer<Object, Long, Object, Long, Map<Object, Long>> {
-
- private Traversal.Admin<S, Object> groupTraversal = new IdentityTraversal<>();
- private String sideEffectKey;
- // TODO: onFirst like subgraph so we don't keep getting the map
-
- public GroupCountStep(final Traversal.Admin traversal, final String sideEffectKey) {
- super(traversal);
- this.sideEffectKey = sideEffectKey;
- }
-
- @Override
- protected void sideEffect(final Traverser.Admin<S> traverser) {
- final Map<Object, Long> groupCountMap = traverser.sideEffects(this.sideEffectKey);
- MapHelper.incr(groupCountMap, TraversalUtil.apply(traverser.asAdmin(), this.groupTraversal), traverser.bulk());
- }
-
- @Override
- public void registerSideEffects() {
- if (this.sideEffectKey == null) this.sideEffectKey = this.getId();
- this.traversal.asAdmin().getSideEffects().registerSupplierIfAbsent(this.sideEffectKey, HashMapSupplier.instance());
- }
-
- @Override
- public String getSideEffectKey() {
- return this.sideEffectKey;
- }
-
- @Override
- public MapReduce<Object, Long, Object, Long, Map<Object, Long>> getMapReduce() {
- return new GroupCountMapReduce(this);
- }
-
- @Override
- public String toString() {
- return TraversalHelper.makeStepString(this, this.sideEffectKey, this.groupTraversal);
- }
-
- @Override
- public void addLocalChild(final Traversal.Admin<?, ?> traversal) {
- this.groupTraversal = this.integrateChild(traversal, TYPICAL_LOCAL_OPERATIONS);
- }
-
- @Override
- public List<Traversal.Admin<S, Object>> getLocalChildren() {
- return Collections.singletonList(this.groupTraversal);
- }
-
- @Override
- public Set<TraverserRequirement> getRequirements() {
- return this.getSelfAndChildRequirements(TraverserRequirement.BULK, TraverserRequirement.SIDE_EFFECTS);
- }
-
- @Override
- public GroupCountStep<S> clone() throws CloneNotSupportedException {
- final GroupCountStep<S> clone = (GroupCountStep<S>) super.clone();
- clone.groupTraversal = this.integrateChild(this.groupTraversal.clone(), TYPICAL_LOCAL_OPERATIONS);
- return clone;
- }
-}