You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tinkerpop.apache.org by ok...@apache.org on 2016/03/01 15:26:32 UTC
[21/50] incubator-tinkerpop git commit: out of my 24 hole. @dkuppitz
-- I was wrong,
you can't have XXXStep and XXXSideEffectStep as one in the same. I learned
exactly what I learned about a year ago by trying. However,
note that all GroupCountXXXStep an
out of my 24 hole. @dkuppitz -- I was wrong, you can't have XXXStep and XXXSideEffectStep as one in the same. I learned exactly what I learned about a year ago by trying. However, note that all GroupCountXXXStep and GroupXXXStep are no longer MapReduce-based, but GraphComputer.Memory-based and because of their alignment they share lots of the same code. All that is left is TreeStep, ProfileStep, and AggregateStep to convert to the GraphComputer.Memory model.
Project: http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/commit/2f3b2ac9
Tree: http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/tree/2f3b2ac9
Diff: http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/diff/2f3b2ac9
Branch: refs/heads/master
Commit: 2f3b2ac971ade400b4f2bfb794b451a612ed0f69
Parents: 980525c
Author: Marko A. Rodriguez <ok...@gmail.com>
Authored: Thu Feb 25 08:29:23 2016 -0700
Committer: Marko A. Rodriguez <ok...@gmail.com>
Committed: Thu Feb 25 08:29:23 2016 -0700
----------------------------------------------------------------------
.../traversal/dsl/graph/GraphTraversal.java | 25 +-
.../traversal/step/map/GroupCountStep.java | 123 +++++++++
.../process/traversal/step/map/GroupStep.java | 259 +++++++++++++++++++
.../traversal/step/map/GroupStepV3d0.java | 170 ++++++++++++
.../traversal/step/map/MaxGlobalStep.java | 3 +-
.../sideEffect/GroupCountSideEffectStep.java | 121 +++++++++
.../step/sideEffect/GroupCountStep.java | 134 ----------
.../step/sideEffect/GroupSideEffectStep.java | 147 +++++++++++
.../sideEffect/GroupSideEffectStepV3d0.java | 158 +++++++++++
.../traversal/step/sideEffect/GroupStep.java | 240 -----------------
.../step/sideEffect/GroupStepV3d0.java | 182 -------------
.../step/util/ReducingBarrierStep.java | 2 +-
.../gremlin/structure/io/gryo/GryoMapper.java | 6 +-
.../traversal/step/map/GroupCountStepTest.java | 42 +++
.../traversal/step/map/GroupStepTest.java | 43 +++
.../GroupCountSideEffectStepTest.java | 44 ++++
.../step/sideEffect/GroupCountStepTest.java | 47 ----
.../sideEffect/GroupSideEffectStepTest.java | 45 ++++
.../sideEffect/GroupSideEffectStepV3D0Test.java | 47 ++++
.../step/sideEffect/GroupStepTest.java | 48 ----
.../step/sideEffect/GroupStepV3D0Test.java | 47 ----
.../io/PersistedInputOutputRDDTest.java | 10 +-
22 files changed, 1220 insertions(+), 723 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/2f3b2ac9/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversal.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversal.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversal.java
index f1f6b94..69c84ad 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversal.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversal.java
@@ -72,6 +72,9 @@ import org.apache.tinkerpop.gremlin.process.traversal.step.map.EdgeOtherVertexSt
import org.apache.tinkerpop.gremlin.process.traversal.step.map.EdgeVertexStep;
import org.apache.tinkerpop.gremlin.process.traversal.step.map.FoldStep;
import org.apache.tinkerpop.gremlin.process.traversal.step.map.GraphStep;
+import org.apache.tinkerpop.gremlin.process.traversal.step.map.GroupCountStep;
+import org.apache.tinkerpop.gremlin.process.traversal.step.map.GroupStep;
+import org.apache.tinkerpop.gremlin.process.traversal.step.map.GroupStepV3d0;
import org.apache.tinkerpop.gremlin.process.traversal.step.map.IdStep;
import org.apache.tinkerpop.gremlin.process.traversal.step.map.LabelStep;
import org.apache.tinkerpop.gremlin.process.traversal.step.map.LambdaCollectingBarrierStep;
@@ -107,9 +110,9 @@ import org.apache.tinkerpop.gremlin.process.traversal.step.map.UnfoldStep;
import org.apache.tinkerpop.gremlin.process.traversal.step.map.VertexStep;
import org.apache.tinkerpop.gremlin.process.traversal.step.sideEffect.AddPropertyStep;
import org.apache.tinkerpop.gremlin.process.traversal.step.sideEffect.AggregateStep;
-import org.apache.tinkerpop.gremlin.process.traversal.step.sideEffect.GroupCountStep;
-import org.apache.tinkerpop.gremlin.process.traversal.step.sideEffect.GroupStepV3d0;
-import org.apache.tinkerpop.gremlin.process.traversal.step.sideEffect.GroupStep;
+import org.apache.tinkerpop.gremlin.process.traversal.step.sideEffect.GroupCountSideEffectStep;
+import org.apache.tinkerpop.gremlin.process.traversal.step.sideEffect.GroupSideEffectStep;
+import org.apache.tinkerpop.gremlin.process.traversal.step.sideEffect.GroupSideEffectStepV3d0;
import org.apache.tinkerpop.gremlin.process.traversal.step.sideEffect.IdentityStep;
import org.apache.tinkerpop.gremlin.process.traversal.step.sideEffect.InjectStep;
import org.apache.tinkerpop.gremlin.process.traversal.step.sideEffect.LambdaSideEffectStep;
@@ -144,7 +147,6 @@ import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Optional;
-import java.util.UUID;
import java.util.function.BiFunction;
import java.util.function.Consumer;
import java.util.function.Function;
@@ -638,8 +640,7 @@ public interface GraphTraversal<S, E> extends Traversal<S, E> {
}
public default <K, V> GraphTraversal<S, Map<K, V>> group() {
- final String id = UUID.randomUUID().toString();
- return this.asAdmin().addStep(new GroupStep<>(this.asAdmin(), id)).cap(id);
+ return this.asAdmin().addStep(new GroupStep<>(this.asAdmin()));
}
/**
@@ -647,13 +648,11 @@ public interface GraphTraversal<S, E> extends Traversal<S, E> {
*/
@Deprecated
public default <K, V> GraphTraversal<S, Map<K, V>> groupV3d0() {
- final String id = UUID.randomUUID().toString();
- return this.asAdmin().addStep(new GroupStepV3d0<>(this.asAdmin(), id)).cap(id);
+ return this.asAdmin().addStep(new GroupStepV3d0<>(this.asAdmin()));
}
public default <K> GraphTraversal<S, Map<K, Long>> groupCount() {
- final String id = UUID.randomUUID().toString() + "destroy";
- return this.asAdmin().addStep(new GroupCountStep<>(this.asAdmin(), id)).cap(id);
+ return this.asAdmin().addStep(new GroupCountStep<>(this.asAdmin()));
}
public default GraphTraversal<S, Tree> tree() {
@@ -989,18 +988,18 @@ public interface GraphTraversal<S, E> extends Traversal<S, E> {
}
public default GraphTraversal<S, E> group(final String sideEffectKey) {
- return this.asAdmin().addStep(new GroupStep<>(this.asAdmin(), sideEffectKey));
+ return this.asAdmin().addStep(new GroupSideEffectStep<>(this.asAdmin(), sideEffectKey));
}
/**
* @deprecated As of release 3.1.0, replaced by {@link #group(String)}.
*/
public default GraphTraversal<S, E> groupV3d0(final String sideEffectKey) {
- return this.asAdmin().addStep(new GroupStepV3d0<>(this.asAdmin(), sideEffectKey));
+ return this.asAdmin().addStep(new GroupSideEffectStepV3d0<>(this.asAdmin(), sideEffectKey));
}
public default GraphTraversal<S, E> groupCount(final String sideEffectKey) {
- return this.asAdmin().addStep(new GroupCountStep<>(this.asAdmin(), sideEffectKey));
+ return this.asAdmin().addStep(new GroupCountSideEffectStep<>(this.asAdmin(), sideEffectKey));
}
public default GraphTraversal<S, E> tree(final String sideEffectKey) {
http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/2f3b2ac9/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/GroupCountStep.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/GroupCountStep.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/GroupCountStep.java
new file mode 100644
index 0000000..433ad50
--- /dev/null
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/GroupCountStep.java
@@ -0,0 +1,123 @@
+/*
+ * 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.traversal.step.map;
+
+import org.apache.tinkerpop.gremlin.process.computer.MemoryComputeKey;
+import org.apache.tinkerpop.gremlin.process.traversal.Traversal;
+import org.apache.tinkerpop.gremlin.process.traversal.Traverser;
+import org.apache.tinkerpop.gremlin.process.traversal.step.ByModulating;
+import org.apache.tinkerpop.gremlin.process.traversal.step.TraversalParent;
+import org.apache.tinkerpop.gremlin.process.traversal.step.util.MapHelper;
+import org.apache.tinkerpop.gremlin.process.traversal.step.util.ReducingBarrierStep;
+import org.apache.tinkerpop.gremlin.process.traversal.traverser.TraverserRequirement;
+import org.apache.tinkerpop.gremlin.process.traversal.util.TraversalUtil;
+import org.apache.tinkerpop.gremlin.structure.util.StringFactory;
+import org.apache.tinkerpop.gremlin.util.function.HashMapSupplier;
+
+import java.io.Serializable;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import java.util.Set;
+import java.util.function.BinaryOperator;
+
+/**
+ * @author Marko A. Rodriguez (http://markorodriguez.com)
+ */
+public final class GroupCountStep<S, E> extends ReducingBarrierStep<S, Map<E, Long>> implements TraversalParent, ByModulating {
+
+ private Traversal.Admin<S, E> keyTraversal = null;
+
+ public GroupCountStep(final Traversal.Admin traversal) {
+ super(traversal);
+ this.setSeedSupplier(HashMapSupplier.instance());
+ this.setReducingBiOperator(GroupCountBiOperator.instance());
+ }
+
+ @Override
+ public Map<E, Long> projectTraverser(final Traverser.Admin<S> traverser) {
+ return Collections.singletonMap(TraversalUtil.applyNullable(traverser, this.keyTraversal), traverser.bulk());
+ }
+
+ @Override
+ public void addLocalChild(final Traversal.Admin<?, ?> groupTraversal) {
+ this.keyTraversal = this.integrateChild(groupTraversal);
+ }
+
+ @Override
+ public List<Traversal.Admin<S, E>> getLocalChildren() {
+ return null == this.keyTraversal ? Collections.emptyList() : Collections.singletonList(this.keyTraversal);
+ }
+
+ @Override
+ public Set<TraverserRequirement> getRequirements() {
+ return this.getSelfAndChildRequirements(TraverserRequirement.BULK);
+ }
+
+ @Override
+ public Optional<MemoryComputeKey> getMemoryComputeKey() {
+ return Optional.of(MemoryComputeKey.of(REDUCING, GroupCountBiOperator.instance(), false, false));
+ }
+
+ @Override
+ public void modulateBy(final Traversal.Admin<?, ?> keyTraversal) throws UnsupportedOperationException {
+ this.keyTraversal = this.integrateChild(keyTraversal);
+ }
+
+ @Override
+ public GroupCountStep<S, E> clone() {
+ final GroupCountStep<S, E> clone = (GroupCountStep<S, E>) super.clone();
+ if (null != this.keyTraversal)
+ clone.keyTraversal = clone.integrateChild(this.keyTraversal.clone());
+ return clone;
+ }
+
+ @Override
+ public int hashCode() {
+ int result = super.hashCode();
+ if (this.keyTraversal != null) result ^= this.keyTraversal.hashCode();
+ return result;
+ }
+
+ @Override
+ public String toString() {
+ return StringFactory.stepString(this, this.keyTraversal);
+ }
+
+ ///////////////////////////
+
+ public static final class GroupCountBiOperator<E> implements BinaryOperator<Map<E, Long>>, Serializable {
+
+ private static final GroupCountBiOperator INSTANCE = new GroupCountBiOperator();
+
+ @Override
+ public Map<E, Long> apply(final Map<E, Long> mutatingSeed, final Map<E, Long> map) {
+ for (final Map.Entry<E, Long> entry : map.entrySet()) {
+ MapHelper.incr(mutatingSeed, entry.getKey(), entry.getValue());
+ }
+ return mutatingSeed;
+ }
+
+ public static final <E> GroupCountBiOperator<E> instance() {
+ return INSTANCE;
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/2f3b2ac9/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/GroupStep.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/GroupStep.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/GroupStep.java
new file mode 100644
index 0000000..d86132b
--- /dev/null
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/GroupStep.java
@@ -0,0 +1,259 @@
+/*
+ * 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.traversal.step.map;
+
+import org.apache.tinkerpop.gremlin.process.computer.MemoryComputeKey;
+import org.apache.tinkerpop.gremlin.process.traversal.Step;
+import org.apache.tinkerpop.gremlin.process.traversal.Traversal;
+import org.apache.tinkerpop.gremlin.process.traversal.Traverser;
+import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__;
+import org.apache.tinkerpop.gremlin.process.traversal.lambda.ElementValueTraversal;
+import org.apache.tinkerpop.gremlin.process.traversal.lambda.FunctionTraverser;
+import org.apache.tinkerpop.gremlin.process.traversal.lambda.IdentityTraversal;
+import org.apache.tinkerpop.gremlin.process.traversal.lambda.TokenTraversal;
+import org.apache.tinkerpop.gremlin.process.traversal.step.Barrier;
+import org.apache.tinkerpop.gremlin.process.traversal.step.ByModulating;
+import org.apache.tinkerpop.gremlin.process.traversal.step.TraversalParent;
+import org.apache.tinkerpop.gremlin.process.traversal.step.util.ReducingBarrierStep;
+import org.apache.tinkerpop.gremlin.process.traversal.traverser.TraverserRequirement;
+import org.apache.tinkerpop.gremlin.process.traversal.traverser.util.TraverserSet;
+import org.apache.tinkerpop.gremlin.process.traversal.util.TraversalHelper;
+import org.apache.tinkerpop.gremlin.process.traversal.util.TraversalUtil;
+import org.apache.tinkerpop.gremlin.structure.util.StringFactory;
+import org.apache.tinkerpop.gremlin.util.function.HashMapSupplier;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import java.util.Set;
+import java.util.function.BinaryOperator;
+
+/**
+ * @author Marko A. Rodriguez (http://markorodriguez.com)
+ */
+public final class GroupStep<S, K, V> extends ReducingBarrierStep<S, Map<K, V>> implements ByModulating, TraversalParent {
+
+ private char state = 'k';
+ private Traversal.Admin<S, K> keyTraversal = null;
+ private Traversal.Admin<S, ?> valueTraversal = this.integrateChild(__.identity().asAdmin()); // used in OLAP
+ private Traversal.Admin<?, V> reduceTraversal = this.integrateChild(__.fold().asAdmin()); // used in OLAP
+ public Traversal.Admin<S, V> valueReduceTraversal = this.integrateChild(__.fold().asAdmin()); // used in OLTP
+
+
+ public GroupStep(final Traversal.Admin traversal) {
+ super(traversal);
+ this.setReducingBiOperator(new GroupBiOperator<>(this.valueReduceTraversal));
+ this.setSeedSupplier(HashMapSupplier.instance());
+ }
+
+ @Override
+ public void onGraphComputer() {
+ super.onGraphComputer();
+ this.setReducingBiOperator(GroupBiOperator.computerInstance());
+ }
+
+ @Override
+ public void modulateBy(final Traversal.Admin<?, ?> kvTraversal) {
+ if ('k' == this.state) {
+ this.keyTraversal = this.integrateChild(kvTraversal);
+ this.state = 'v';
+ } else if ('v' == this.state) {
+ this.valueReduceTraversal = this.integrateChild(convertValueTraversal(kvTraversal));
+ final List<Traversal.Admin<?, ?>> splitTraversal = splitOnBarrierStep(this.valueReduceTraversal);
+ this.valueTraversal = this.integrateChild(splitTraversal.get(0));
+ this.reduceTraversal = this.integrateChild(splitTraversal.get(1));
+ this.state = 'x';
+ this.setReducingBiOperator(new GroupBiOperator<>(this.valueReduceTraversal));
+ } else {
+ throw new IllegalStateException("The key and value traversals for group()-step have already been set: " + this);
+ }
+ }
+
+ @Override
+ public Optional<MemoryComputeKey> getMemoryComputeKey() {
+ return Optional.of(MemoryComputeKey.of(REDUCING, GroupBiOperator.computerInstance(), false, false));
+ }
+
+ @Override
+ public Map<K, V> projectTraverser(final Traverser.Admin<S> traverser) {
+ return GroupStep.doInitialProjection(traverser, (Traversal.Admin) this.keyTraversal, this.onGraphComputer ? this.valueTraversal : null);
+ }
+
+ @Override
+ public String toString() {
+ return StringFactory.stepString(this, this.keyTraversal, this.valueReduceTraversal);
+ }
+
+ @Override
+ public List<Traversal.Admin<?, ?>> getLocalChildren() {
+ final List<Traversal.Admin<?, ?>> children = new ArrayList<>(4);
+ if (null != this.keyTraversal)
+ children.add((Traversal.Admin) this.keyTraversal);
+ children.add(this.valueReduceTraversal);
+ children.add(this.valueTraversal);
+ children.add(this.reduceTraversal);
+ return children;
+ }
+
+ @Override
+ public Set<TraverserRequirement> getRequirements() {
+ return this.getSelfAndChildRequirements(TraverserRequirement.OBJECT, TraverserRequirement.BULK, TraverserRequirement.SIDE_EFFECTS);
+ }
+
+ @Override
+ public GroupStep<S, K, V> clone() {
+ final GroupStep<S, K, V> clone = (GroupStep<S, K, V>) super.clone();
+ if (null != this.keyTraversal)
+ clone.keyTraversal = clone.integrateChild(this.keyTraversal.clone());
+ clone.valueReduceTraversal = clone.integrateChild(this.valueReduceTraversal.clone());
+ clone.valueTraversal = clone.integrateChild(this.valueTraversal.clone());
+ clone.reduceTraversal = clone.integrateChild(this.reduceTraversal.clone());
+ return clone;
+ }
+
+ @Override
+ public int hashCode() {
+ int result = super.hashCode();
+ if (this.keyTraversal != null) result ^= this.keyTraversal.hashCode();
+ result ^= this.valueReduceTraversal.hashCode();
+ return result;
+ }
+
+ @Override
+ public Object generateFinalResult(final Object object) {
+ return GroupStep.doFinalReduction((Map<K, Object>) object, this.onGraphComputer ? this.reduceTraversal : null);
+ }
+
+ ///////////////////////
+
+ public static final class GroupBiOperator<K, V> implements BinaryOperator<Map<K, V>>, Serializable {
+
+ private static final GroupBiOperator COMPUTER_INSTANCE = new GroupBiOperator();
+
+ private transient Traversal.Admin<?, V> valueReduceTraversal;
+ private transient Map<K, Integer> counters;
+ private final boolean onGraphComputer;
+
+ public GroupBiOperator(final Traversal.Admin<?, V> valueReduceTraversal) {
+ this.valueReduceTraversal = valueReduceTraversal;
+ this.counters = new HashMap<>();
+ this.onGraphComputer = false;
+ }
+
+ public GroupBiOperator() {
+ this.onGraphComputer = true;
+ }
+
+ @Override
+ public Map<K, V> apply(final Map<K, V> mutatingSeed, final Map<K, V> map) {
+ for (final K key : map.keySet()) {
+ if (this.onGraphComputer) {
+ TraverserSet<?> traverserSet = (TraverserSet) mutatingSeed.get(key);
+ if (null == traverserSet) {
+ traverserSet = new TraverserSet<>();
+ mutatingSeed.put(key, (V) traverserSet);
+ }
+ traverserSet.addAll((TraverserSet) map.get(key));
+ } else {
+ final Traverser.Admin traverser = (Traverser.Admin) map.get(key);
+ Traversal.Admin valueReduceTraversal = (Traversal.Admin) mutatingSeed.get(key);
+ if (null == valueReduceTraversal) {
+ this.counters.put(key, 0);
+ valueReduceTraversal = this.valueReduceTraversal.clone();
+ mutatingSeed.put(key, (V) valueReduceTraversal);
+ }
+ valueReduceTraversal.addStart(traverser);
+ final int count = this.counters.compute(key, (k, i) -> ++i);
+ if (count > 10000) {
+ this.counters.put(key, 0);
+ TraversalHelper.getFirstStepOfAssignableClass(Barrier.class, valueReduceTraversal).ifPresent(Barrier::processAllStarts);
+ }
+ }
+ }
+ return mutatingSeed;
+ }
+
+ public static final <K, V> GroupBiOperator<K, V> computerInstance() {
+ return COMPUTER_INSTANCE;
+ }
+ }
+
+ ///////////////////////
+
+ public static <S, E> Traversal.Admin<S, E> convertValueTraversal(final Traversal.Admin<S, E> valueReduceTraversal) {
+ if (valueReduceTraversal instanceof ElementValueTraversal ||
+ valueReduceTraversal instanceof TokenTraversal ||
+ valueReduceTraversal instanceof IdentityTraversal ||
+ valueReduceTraversal.getStartStep() instanceof LambdaMapStep && ((LambdaMapStep) valueReduceTraversal.getStartStep()).getMapFunction() instanceof FunctionTraverser) {
+ return (Traversal.Admin<S, E>) __.map(valueReduceTraversal).fold();
+ } else {
+ return valueReduceTraversal;
+ }
+ }
+
+ public static List<Traversal.Admin<?, ?>> splitOnBarrierStep(final Traversal.Admin<?, ?> valueReduceTraversal) {
+ if (TraversalHelper.getFirstStepOfAssignableClass(Barrier.class, valueReduceTraversal).isPresent()) {
+ final Traversal.Admin<?, ?> first = __.identity().asAdmin();
+ final Traversal.Admin<?, ?> second = __.identity().asAdmin();
+ boolean onSecond = false;
+ for (final Step step : valueReduceTraversal.getSteps()) {
+ if (step instanceof Barrier)
+ onSecond = true;
+ if (onSecond)
+ second.addStep(step.clone());
+ else
+ first.addStep(step.clone());
+ }
+ return Arrays.asList(first, second);
+ } else {
+ return Arrays.asList(valueReduceTraversal.clone(), __.identity().asAdmin());
+ }
+ }
+
+ public static <K, V> Map<K, V> doFinalReduction(final Map<K, Object> map, final Traversal.Admin<?, V> reduceTraversal) {
+ final Map<K, V> reducedMap = new HashMap<>();
+ if (null != reduceTraversal) {
+ for (final K key : map.keySet()) {
+ final Traversal.Admin<?, V> reduceClone = reduceTraversal.clone();
+ reduceClone.addStarts(((TraverserSet) map.get(key)).iterator());
+ reducedMap.put(key, reduceClone.next());
+ }
+ } else
+ map.forEach((key, traversal) -> reducedMap.put(key, ((Traversal.Admin<?, V>) traversal).next()));
+ return reducedMap;
+ }
+
+ public static <S, K> Map<K, Object> doInitialProjection(final Traverser.Admin<S> traverser, final Traversal.Admin<S, K> keyTraversal, final Traversal.Admin<S, ?> valueTraversal) {
+ final K key = TraversalUtil.applyNullable(traverser, keyTraversal);
+ if (null != valueTraversal) {
+ final TraverserSet traverserSet = new TraverserSet();
+ valueTraversal.reset();
+ valueTraversal.addStart(traverser);
+ valueTraversal.getEndStep().forEachRemaining(t -> traverserSet.add(t.asAdmin()));
+ return Collections.singletonMap(key, traverserSet);
+ } else
+ return Collections.singletonMap(key,traverser);
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/2f3b2ac9/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/GroupStepV3d0.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/GroupStepV3d0.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/GroupStepV3d0.java
new file mode 100644
index 0000000..ade485b
--- /dev/null
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/GroupStepV3d0.java
@@ -0,0 +1,170 @@
+/*
+ * 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.traversal.step.map;
+
+import org.apache.tinkerpop.gremlin.process.computer.MemoryComputeKey;
+import org.apache.tinkerpop.gremlin.process.traversal.Traversal;
+import org.apache.tinkerpop.gremlin.process.traversal.Traverser;
+import org.apache.tinkerpop.gremlin.process.traversal.step.ByModulating;
+import org.apache.tinkerpop.gremlin.process.traversal.step.TraversalParent;
+import org.apache.tinkerpop.gremlin.process.traversal.step.util.BulkSet;
+import org.apache.tinkerpop.gremlin.process.traversal.step.util.ReducingBarrierStep;
+import org.apache.tinkerpop.gremlin.process.traversal.traverser.TraverserRequirement;
+import org.apache.tinkerpop.gremlin.process.traversal.util.TraversalHelper;
+import org.apache.tinkerpop.gremlin.process.traversal.util.TraversalUtil;
+import org.apache.tinkerpop.gremlin.structure.util.StringFactory;
+import org.apache.tinkerpop.gremlin.util.function.HashMapSupplier;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import java.util.Set;
+import java.util.function.BinaryOperator;
+
+/**
+ * @author Marko A. Rodriguez (http://markorodriguez.com)
+ */
+public final class GroupStepV3d0<S, K, V, R> extends ReducingBarrierStep<S, Map<K, R>> implements TraversalParent, ByModulating {
+
+ private char state = 'k';
+ private Traversal.Admin<S, K> keyTraversal = null;
+ private Traversal.Admin<S, V> valueTraversal = null;
+ private Traversal.Admin<Collection<V>, R> reduceTraversal = null;
+
+ public GroupStepV3d0(final Traversal.Admin traversal) {
+ super(traversal);
+ this.setSeedSupplier(HashMapSupplier.instance());
+ this.setReducingBiOperator(GroupBiOperatorV3d0.instance());
+ }
+
+ @Override
+ public Optional<MemoryComputeKey> getMemoryComputeKey() {
+ return Optional.of(MemoryComputeKey.of(REDUCING, GroupBiOperatorV3d0.INSTANCE, false, false));
+ }
+
+ @Override
+ public Map<K, R> projectTraverser(final Traverser.Admin<S> traverser) {
+ final K key = TraversalUtil.applyNullable(traverser, this.keyTraversal);
+ final BulkSet<V> values = new BulkSet<>();
+ final V value = TraversalUtil.applyNullable(traverser, this.valueTraversal);
+ TraversalHelper.addToCollectionUnrollIterator(values, value, traverser.bulk());
+ return Collections.singletonMap(key, (R) values);
+ }
+
+ @Override
+ public String toString() {
+ return StringFactory.stepString(this, this.keyTraversal, this.valueTraversal, this.reduceTraversal);
+ }
+
+ @Override
+ public Map<K, R> generateFinalResult(final Object valueMap) {
+ final Map<K, R> reducedMap = new HashMap<>();
+ for (final K key : ((Map<K, Collection<V>>) valueMap).keySet()) {
+ final R r = TraversalUtil.applyNullable(((Map<K, Collection<V>>) valueMap).get(key), this.reduceTraversal);
+ reducedMap.put(key, r);
+ }
+ return reducedMap;
+ }
+
+ @Override
+ public <A, B> List<Traversal.Admin<A, B>> getLocalChildren() {
+ final List<Traversal.Admin<A, B>> children = new ArrayList<>(3);
+ if (null != this.keyTraversal)
+ children.add((Traversal.Admin) this.keyTraversal);
+ if (null != this.valueTraversal)
+ children.add((Traversal.Admin) this.valueTraversal);
+ if (null != this.reduceTraversal)
+ children.add((Traversal.Admin) this.reduceTraversal);
+ return children;
+ }
+
+ @Override
+ public void modulateBy(final Traversal.Admin<?, ?> kvrTraversal) {
+ if ('k' == this.state) {
+ this.keyTraversal = this.integrateChild(kvrTraversal);
+ this.state = 'v';
+ } else if ('v' == this.state) {
+ this.valueTraversal = this.integrateChild(kvrTraversal);
+ this.state = 'r';
+ } else if ('r' == this.state) {
+ this.reduceTraversal = this.integrateChild(kvrTraversal);
+ this.state = 'x';
+ } else {
+ throw new IllegalStateException("The key, value, and reduce functions for group()-step have already been set");
+ }
+ }
+
+ @Override
+ public Set<TraverserRequirement> getRequirements() {
+ return this.getSelfAndChildRequirements(TraverserRequirement.SIDE_EFFECTS, TraverserRequirement.BULK);
+ }
+
+ @Override
+ public GroupStepV3d0<S, K, V, R> clone() {
+ final GroupStepV3d0<S, K, V, R> clone = (GroupStepV3d0<S, K, V, R>) super.clone();
+ if (null != this.keyTraversal)
+ clone.keyTraversal = clone.integrateChild(this.keyTraversal.clone());
+ if (null != this.valueTraversal)
+ clone.valueTraversal = clone.integrateChild(this.valueTraversal.clone());
+ if (null != this.reduceTraversal)
+ clone.reduceTraversal = clone.integrateChild(this.reduceTraversal.clone());
+ return clone;
+ }
+
+ @Override
+ public int hashCode() {
+ int result = super.hashCode();
+ if (this.keyTraversal != null) result ^= this.keyTraversal.hashCode();
+ if (this.valueTraversal != null) result ^= this.valueTraversal.hashCode();
+ if (this.reduceTraversal != null) result ^= this.reduceTraversal.hashCode();
+ return result;
+ }
+
+ //////////
+
+ @Deprecated
+ public static class GroupBiOperatorV3d0<K, V> implements BinaryOperator<Map<K, V>>, Serializable {
+
+ private final static GroupBiOperatorV3d0 INSTANCE = new GroupBiOperatorV3d0();
+
+ @Override
+ public Map<K, V> apply(final Map<K, V> mutatingSeed, final Map<K, V> map) {
+ for (final K key : map.keySet()) {
+ final BulkSet<V> values = (BulkSet<V>) map.get(key);
+ BulkSet<V> seedValues = (BulkSet<V>) mutatingSeed.get(key);
+ if (null == seedValues) {
+ seedValues = new BulkSet<>();
+ mutatingSeed.put(key, (V) seedValues);
+ }
+ seedValues.addAll(values);
+ }
+ return mutatingSeed;
+ }
+
+ public static final <K, V> GroupBiOperatorV3d0<K, V> instance() {
+ return INSTANCE;
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/2f3b2ac9/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/MaxGlobalStep.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/MaxGlobalStep.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/MaxGlobalStep.java
index c409ae4..70788ed 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/MaxGlobalStep.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/MaxGlobalStep.java
@@ -38,13 +38,12 @@ import static org.apache.tinkerpop.gremlin.process.traversal.NumberHelper.max;
*/
public final class MaxGlobalStep<S extends Number> extends ReducingBarrierStep<S, S> {
-
private static final Double NAN = Double.valueOf(Double.NaN);
public MaxGlobalStep(final Traversal.Admin traversal) {
super(traversal);
this.setSeedSupplier(new ConstantSupplier<>((S) NAN));
- this.setReducingBiOperator(new MaxGlobalBiOperator<>());
+ this.setReducingBiOperator(MaxGlobalBiOperator.INSTANCE);
}
@Override
http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/2f3b2ac9/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/sideEffect/GroupCountSideEffectStep.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/sideEffect/GroupCountSideEffectStep.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/sideEffect/GroupCountSideEffectStep.java
new file mode 100644
index 0000000..d2de613
--- /dev/null
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/sideEffect/GroupCountSideEffectStep.java
@@ -0,0 +1,121 @@
+/*
+ * 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.traversal.step.sideEffect;
+
+import org.apache.tinkerpop.gremlin.process.computer.MemoryComputeKey;
+import org.apache.tinkerpop.gremlin.process.traversal.Traversal;
+import org.apache.tinkerpop.gremlin.process.traversal.Traverser;
+import org.apache.tinkerpop.gremlin.process.traversal.step.ByModulating;
+import org.apache.tinkerpop.gremlin.process.traversal.step.GraphComputing;
+import org.apache.tinkerpop.gremlin.process.traversal.step.SideEffectCapable;
+import org.apache.tinkerpop.gremlin.process.traversal.step.TraversalParent;
+import org.apache.tinkerpop.gremlin.process.traversal.step.map.GroupCountStep;
+import org.apache.tinkerpop.gremlin.process.traversal.step.util.MapHelper;
+import org.apache.tinkerpop.gremlin.process.traversal.traverser.TraverserRequirement;
+import org.apache.tinkerpop.gremlin.process.traversal.util.TraversalUtil;
+import org.apache.tinkerpop.gremlin.structure.util.StringFactory;
+import org.apache.tinkerpop.gremlin.util.function.HashMapSupplier;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import java.util.Set;
+
+/**
+ * @author Marko A. Rodriguez (http://markorodriguez.com)
+ */
+public final class GroupCountSideEffectStep<S, E> extends SideEffectStep<S> implements SideEffectCapable, GraphComputing, TraversalParent, ByModulating {
+
+ private Traversal.Admin<S, E> keyTraversal = null;
+ private String sideEffectKey;
+
+ public GroupCountSideEffectStep(final Traversal.Admin traversal, final String sideEffectKey) {
+ super(traversal);
+ this.sideEffectKey = sideEffectKey;
+ this.traversal.asAdmin().getSideEffects().registerSupplierIfAbsent(this.sideEffectKey, HashMapSupplier.instance());
+ }
+
+ @Override
+ protected void sideEffect(final Traverser.Admin<S> traverser) {
+ final Map<Object, Long> groupCountMap = traverser.sideEffects(this.sideEffectKey);
+ MapHelper.incr(groupCountMap, TraversalUtil.applyNullable(traverser.asAdmin(), this.keyTraversal), traverser.bulk());
+ }
+
+ @Override
+ public String getSideEffectKey() {
+ return this.sideEffectKey;
+ }
+
+ @Override
+ public String toString() {
+ return StringFactory.stepString(this, this.sideEffectKey, this.keyTraversal);
+ }
+
+ @Override
+ public void addLocalChild(final Traversal.Admin<?, ?> groupTraversal) {
+ this.keyTraversal = this.integrateChild(groupTraversal);
+ }
+
+ @Override
+ public List<Traversal.Admin<S, E>> getLocalChildren() {
+ return null == this.keyTraversal ? Collections.emptyList() : Collections.singletonList(this.keyTraversal);
+ }
+
+ @Override
+ public Set<TraverserRequirement> getRequirements() {
+ return this.getSelfAndChildRequirements(TraverserRequirement.BULK, TraverserRequirement.SIDE_EFFECTS);
+ }
+
+ @Override
+ public GroupCountSideEffectStep<S, E> clone() {
+ final GroupCountSideEffectStep<S, E> clone = (GroupCountSideEffectStep<S, E>) super.clone();
+ if (null != this.keyTraversal)
+ clone.keyTraversal = clone.integrateChild(this.keyTraversal.clone());
+ return clone;
+ }
+
+ @Override
+ public int hashCode() {
+ int result = super.hashCode() ^ this.sideEffectKey.hashCode();
+ if (this.keyTraversal != null) result ^= this.keyTraversal.hashCode();
+ return result;
+ }
+
+ @Override
+ public void modulateBy(final Traversal.Admin<?, ?> keyTraversal) throws UnsupportedOperationException {
+ this.keyTraversal = this.integrateChild(keyTraversal);
+ }
+
+ @Override
+ public void onGraphComputer() {
+
+ }
+
+ @Override
+ public Object generateFinalResult(final Object map) {
+ return map;
+ }
+
+ @Override
+ public Optional<MemoryComputeKey> getMemoryComputeKey() {
+ return Optional.of(MemoryComputeKey.of(this.getSideEffectKey(), GroupCountStep.GroupCountBiOperator.instance(), false, false));
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/2f3b2ac9/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/sideEffect/GroupCountStep.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/sideEffect/GroupCountStep.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/sideEffect/GroupCountStep.java
deleted file mode 100644
index 1a655ea..0000000
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/sideEffect/GroupCountStep.java
+++ /dev/null
@@ -1,134 +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 org.apache.tinkerpop.gremlin.process.traversal.step.sideEffect;
-
-import org.apache.tinkerpop.gremlin.process.computer.MemoryComputeKey;
-import org.apache.tinkerpop.gremlin.process.traversal.Traversal;
-import org.apache.tinkerpop.gremlin.process.traversal.Traverser;
-import org.apache.tinkerpop.gremlin.process.traversal.step.ByModulating;
-import org.apache.tinkerpop.gremlin.process.traversal.step.GraphComputing;
-import org.apache.tinkerpop.gremlin.process.traversal.step.SideEffectCapable;
-import org.apache.tinkerpop.gremlin.process.traversal.step.TraversalParent;
-import org.apache.tinkerpop.gremlin.process.traversal.step.util.MapHelper;
-import org.apache.tinkerpop.gremlin.process.traversal.traverser.TraverserRequirement;
-import org.apache.tinkerpop.gremlin.process.traversal.util.TraversalUtil;
-import org.apache.tinkerpop.gremlin.structure.util.StringFactory;
-import org.apache.tinkerpop.gremlin.util.function.HashMapSupplier;
-
-import java.io.Serializable;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-import java.util.Optional;
-import java.util.Set;
-import java.util.function.BinaryOperator;
-
-/**
- * @author Marko A. Rodriguez (http://markorodriguez.com)
- */
-public final class GroupCountStep<S, E> extends SideEffectStep<S> implements SideEffectCapable, GraphComputing, TraversalParent, ByModulating {
-
- private Traversal.Admin<S, E> keyTraversal = null;
- private String sideEffectKey;
-
- public GroupCountStep(final Traversal.Admin traversal, final String sideEffectKey) {
- super(traversal);
- this.sideEffectKey = sideEffectKey;
- this.traversal.asAdmin().getSideEffects().registerSupplierIfAbsent(this.sideEffectKey, HashMapSupplier.instance());
- }
-
- @Override
- protected void sideEffect(final Traverser.Admin<S> traverser) {
- final Map<Object, Long> groupCountMap = traverser.sideEffects(this.sideEffectKey);
- MapHelper.incr(groupCountMap, TraversalUtil.applyNullable(traverser.asAdmin(), this.keyTraversal), traverser.bulk());
- }
-
- @Override
- public String getSideEffectKey() {
- return this.sideEffectKey;
- }
-
- @Override
- public String toString() {
- return StringFactory.stepString(this, this.sideEffectKey, this.keyTraversal);
- }
-
- @Override
- public void addLocalChild(final Traversal.Admin<?, ?> groupTraversal) {
- this.keyTraversal = this.integrateChild(groupTraversal);
- }
-
- @Override
- public List<Traversal.Admin<S, E>> getLocalChildren() {
- return null == this.keyTraversal ? Collections.emptyList() : Collections.singletonList(this.keyTraversal);
- }
-
- @Override
- public Set<TraverserRequirement> getRequirements() {
- return this.getSelfAndChildRequirements(TraverserRequirement.BULK, TraverserRequirement.SIDE_EFFECTS);
- }
-
- @Override
- public GroupCountStep<S, E> clone() {
- final GroupCountStep<S, E> clone = (GroupCountStep<S, E>) super.clone();
- if (null != this.keyTraversal)
- clone.keyTraversal = clone.integrateChild(this.keyTraversal.clone());
- return clone;
- }
-
- @Override
- public int hashCode() {
- int result = super.hashCode() ^ this.sideEffectKey.hashCode();
- if (this.keyTraversal != null) result ^= this.keyTraversal.hashCode();
- return result;
- }
-
- @Override
- public void modulateBy(final Traversal.Admin<?, ?> keyTraversal) throws UnsupportedOperationException {
- this.keyTraversal = this.integrateChild(keyTraversal);
- }
-
- @Override
- public void onGraphComputer() {
-
- }
-
- @Override
- public Object generateFinalResult(final Object map) {
- return map;
- }
-
- @Override
- public Optional<MemoryComputeKey> getMemoryComputeKey() {
- return Optional.of(MemoryComputeKey.of(this.getSideEffectKey(), GroupCountBiOperator.INSTANCE, false, false));
- }
-
- ///////
-
- public static final class GroupCountBiOperator<E> implements BinaryOperator<Map<E, Long>>, Serializable {
-
- private static GroupCountBiOperator INSTANCE = new GroupCountBiOperator();
-
- @Override
- public Map<E, Long> apply(final Map<E, Long> mutatingSeed, final Map<E, Long> map) {
- map.forEach((k, v) -> MapHelper.incr(mutatingSeed, k, v));
- return mutatingSeed;
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/2f3b2ac9/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/sideEffect/GroupSideEffectStep.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/sideEffect/GroupSideEffectStep.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/sideEffect/GroupSideEffectStep.java
new file mode 100644
index 0000000..307f211
--- /dev/null
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/sideEffect/GroupSideEffectStep.java
@@ -0,0 +1,147 @@
+/*
+ * 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.traversal.step.sideEffect;
+
+import org.apache.tinkerpop.gremlin.process.computer.MemoryComputeKey;
+import org.apache.tinkerpop.gremlin.process.traversal.Traversal;
+import org.apache.tinkerpop.gremlin.process.traversal.Traverser;
+import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__;
+import org.apache.tinkerpop.gremlin.process.traversal.step.ByModulating;
+import org.apache.tinkerpop.gremlin.process.traversal.step.GraphComputing;
+import org.apache.tinkerpop.gremlin.process.traversal.step.SideEffectCapable;
+import org.apache.tinkerpop.gremlin.process.traversal.step.TraversalParent;
+import org.apache.tinkerpop.gremlin.process.traversal.step.map.GroupStep;
+import org.apache.tinkerpop.gremlin.process.traversal.traverser.TraverserRequirement;
+import org.apache.tinkerpop.gremlin.structure.util.StringFactory;
+import org.apache.tinkerpop.gremlin.util.function.HashMapSupplier;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import java.util.Set;
+
+/**
+ * @author Marko A. Rodriguez (http://markorodriguez.com)
+ */
+public final class GroupSideEffectStep<S, K, V> extends SideEffectStep<S> implements SideEffectCapable, TraversalParent, ByModulating, GraphComputing {
+
+ private char state = 'k';
+ private Traversal.Admin<S, K> keyTraversal = null;
+ private Traversal.Admin<S, ?> valueTraversal = this.integrateChild(__.identity().asAdmin()); // used in OLAP
+ private Traversal.Admin<?, V> reduceTraversal = this.integrateChild(__.fold().asAdmin()); // used in OLAP
+ private Traversal.Admin<S, V> valueReduceTraversal = this.integrateChild(__.fold().asAdmin()); // used in OLTP
+ ///
+ private String sideEffectKey;
+ private boolean onGraphComputer = false;
+ private GroupStep.GroupBiOperator<K, V> standardOperator = new GroupStep.GroupBiOperator<>(this.valueReduceTraversal);
+
+ public GroupSideEffectStep(final Traversal.Admin traversal, final String sideEffectKey) {
+ super(traversal);
+ this.sideEffectKey = sideEffectKey;
+ this.traversal.asAdmin().getSideEffects().registerSupplierIfAbsent(this.sideEffectKey, HashMapSupplier.instance());
+ }
+
+ @Override
+ public void modulateBy(final Traversal.Admin<?, ?> kvTraversal) {
+ if ('k' == this.state) {
+ this.keyTraversal = this.integrateChild(kvTraversal);
+ this.state = 'v';
+ } else if ('v' == this.state) {
+ this.valueReduceTraversal = this.integrateChild(GroupStep.convertValueTraversal(kvTraversal));
+ final List<Traversal.Admin<?, ?>> splitTraversal = GroupStep.splitOnBarrierStep(this.valueReduceTraversal);
+ this.valueTraversal = this.integrateChild(splitTraversal.get(0));
+ this.reduceTraversal = this.integrateChild(splitTraversal.get(1));
+ this.state = 'x';
+ this.standardOperator = new GroupStep.GroupBiOperator<>(this.valueReduceTraversal);
+ } else {
+ throw new IllegalStateException("The key and value traversals for group()-step have already been set: " + this);
+ }
+ }
+
+ @Override
+ public Optional<MemoryComputeKey> getMemoryComputeKey() {
+ return Optional.of(MemoryComputeKey.of(this.getSideEffectKey(), new GroupStep.GroupBiOperator<>(), false, false));
+ }
+
+ @Override
+ protected void sideEffect(final Traverser.Admin<S> traverser) {
+ final Map<K, Object> groupMap = traverser.sideEffects(this.sideEffectKey);
+ final Map<K, Object> map = GroupStep.doInitialProjection(traverser.split(), this.keyTraversal, this.onGraphComputer ? this.valueTraversal : null);
+ if (this.onGraphComputer)
+ GroupStep.GroupBiOperator.computerInstance().apply((Map) groupMap, (Map) map);
+ else
+ this.standardOperator.apply((Map) groupMap, (Map) map);
+ }
+
+ @Override
+ public String getSideEffectKey() {
+ return this.sideEffectKey;
+ }
+
+ @Override
+ public void onGraphComputer() {
+ this.onGraphComputer = true;
+ }
+
+ @Override
+ public String toString() {
+ return StringFactory.stepString(this, this.sideEffectKey, this.keyTraversal, this.valueReduceTraversal);
+ }
+
+ @Override
+ public List<Traversal.Admin<?, ?>> getLocalChildren() {
+ final List<Traversal.Admin<?, ?>> children = new ArrayList<>(4);
+ if (null != this.keyTraversal)
+ children.add((Traversal.Admin) this.keyTraversal);
+ children.add(this.valueReduceTraversal);
+ children.add(this.valueTraversal);
+ children.add(this.reduceTraversal);
+ return children;
+ }
+
+ @Override
+ public Set<TraverserRequirement> getRequirements() {
+ return this.getSelfAndChildRequirements(TraverserRequirement.OBJECT, TraverserRequirement.BULK, TraverserRequirement.SIDE_EFFECTS);
+ }
+
+ @Override
+ public GroupSideEffectStep<S, K, V> clone() {
+ final GroupSideEffectStep<S, K, V> clone = (GroupSideEffectStep<S, K, V>) super.clone();
+ if (null != this.keyTraversal)
+ clone.keyTraversal = clone.integrateChild(this.keyTraversal.clone());
+ clone.valueReduceTraversal = clone.integrateChild(this.valueReduceTraversal.clone());
+ clone.valueTraversal = clone.integrateChild(this.valueTraversal.clone());
+ clone.reduceTraversal = clone.integrateChild(this.reduceTraversal.clone());
+ return clone;
+ }
+
+ @Override
+ public int hashCode() {
+ int result = super.hashCode() ^ this.sideEffectKey.hashCode();
+ if (this.keyTraversal != null) result ^= this.keyTraversal.hashCode();
+ result ^= this.valueReduceTraversal.hashCode();
+ return result;
+ }
+
+ @Override
+ public Object generateFinalResult(final Object object) {
+ return GroupStep.doFinalReduction((Map<K, Object>) object, this.onGraphComputer ? this.reduceTraversal : null);
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/2f3b2ac9/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/sideEffect/GroupSideEffectStepV3d0.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/sideEffect/GroupSideEffectStepV3d0.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/sideEffect/GroupSideEffectStepV3d0.java
new file mode 100644
index 0000000..a4555bc
--- /dev/null
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/sideEffect/GroupSideEffectStepV3d0.java
@@ -0,0 +1,158 @@
+/*
+ * 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.traversal.step.sideEffect;
+
+import org.apache.tinkerpop.gremlin.process.computer.MemoryComputeKey;
+import org.apache.tinkerpop.gremlin.process.traversal.Traversal;
+import org.apache.tinkerpop.gremlin.process.traversal.Traverser;
+import org.apache.tinkerpop.gremlin.process.traversal.step.ByModulating;
+import org.apache.tinkerpop.gremlin.process.traversal.step.GraphComputing;
+import org.apache.tinkerpop.gremlin.process.traversal.step.SideEffectCapable;
+import org.apache.tinkerpop.gremlin.process.traversal.step.TraversalParent;
+import org.apache.tinkerpop.gremlin.process.traversal.step.map.GroupStepV3d0;
+import org.apache.tinkerpop.gremlin.process.traversal.step.util.BulkSet;
+import org.apache.tinkerpop.gremlin.process.traversal.traverser.TraverserRequirement;
+import org.apache.tinkerpop.gremlin.process.traversal.util.TraversalHelper;
+import org.apache.tinkerpop.gremlin.process.traversal.util.TraversalUtil;
+import org.apache.tinkerpop.gremlin.structure.util.StringFactory;
+import org.apache.tinkerpop.gremlin.util.function.HashMapSupplier;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import java.util.Set;
+
+/**
+ * @author Marko A. Rodriguez (http://markorodriguez.com)
+ */
+@Deprecated
+public final class GroupSideEffectStepV3d0<S, K, V, R> extends SideEffectStep<S> implements SideEffectCapable, TraversalParent, ByModulating, GraphComputing {
+
+ private char state = 'k';
+ private Traversal.Admin<S, K> keyTraversal = null;
+ private Traversal.Admin<S, V> valueTraversal = null;
+ private Traversal.Admin<Collection<V>, R> reduceTraversal = null;
+ private String sideEffectKey;
+
+ public GroupSideEffectStepV3d0(final Traversal.Admin traversal, final String sideEffectKey) {
+ super(traversal);
+ this.sideEffectKey = sideEffectKey;
+ this.traversal.asAdmin().getSideEffects().registerSupplierIfAbsent(this.sideEffectKey, HashMapSupplier.instance());
+ }
+
+ @Override
+ public Optional<MemoryComputeKey> getMemoryComputeKey() {
+ return Optional.of(MemoryComputeKey.of(this.getSideEffectKey(), GroupStepV3d0.GroupBiOperatorV3d0.instance(), false, false));
+ }
+
+ @Override
+ protected void sideEffect(final Traverser.Admin<S> traverser) {
+ final Map<K, Collection<V>> groupMap = traverser.sideEffects(this.sideEffectKey);
+ final K key = TraversalUtil.applyNullable(traverser, keyTraversal);
+ final V value = TraversalUtil.applyNullable(traverser, valueTraversal);
+ Collection<V> values = groupMap.get(key);
+ if (null == values) {
+ values = new BulkSet<>();
+ groupMap.put(key, values);
+ }
+ TraversalHelper.addToCollectionUnrollIterator(values, value, traverser.bulk());
+ }
+
+ @Override
+ public String getSideEffectKey() {
+ return this.sideEffectKey;
+ }
+
+ @Override
+ public void onGraphComputer() {
+ }
+
+ @Override
+ public String toString() {
+ return StringFactory.stepString(this, this.sideEffectKey, this.keyTraversal, this.valueTraversal, this.reduceTraversal);
+ }
+
+ @Override
+ public Map<K, R> generateFinalResult(final Object valueMap) {
+ final Map<K, R> reducedMap = new HashMap<>();
+ for (final K key : ((Map<K, Collection<V>>) valueMap).keySet()) {
+ final R r = TraversalUtil.applyNullable(((Map<K, Collection<V>>) valueMap).get(key), this.reduceTraversal);
+ reducedMap.put(key, r);
+ }
+ return reducedMap;
+ }
+
+ @Override
+ public <A, B> List<Traversal.Admin<A, B>> getLocalChildren() {
+ final List<Traversal.Admin<A, B>> children = new ArrayList<>(3);
+ if (null != this.keyTraversal)
+ children.add((Traversal.Admin) this.keyTraversal);
+ if (null != this.valueTraversal)
+ children.add((Traversal.Admin) this.valueTraversal);
+ if (null != this.reduceTraversal)
+ children.add((Traversal.Admin) this.reduceTraversal);
+ return children;
+ }
+
+ @Override
+ public void modulateBy(final Traversal.Admin<?, ?> kvrTraversal) {
+ if ('k' == this.state) {
+ this.keyTraversal = this.integrateChild(kvrTraversal);
+ this.state = 'v';
+ } else if ('v' == this.state) {
+ this.valueTraversal = this.integrateChild(kvrTraversal);
+ this.state = 'r';
+ } else if ('r' == this.state) {
+ this.reduceTraversal = this.integrateChild(kvrTraversal);
+ this.state = 'x';
+ } else {
+ throw new IllegalStateException("The key, value, and reduce functions for group()-step have already been set");
+ }
+ }
+
+ @Override
+ public Set<TraverserRequirement> getRequirements() {
+ return this.getSelfAndChildRequirements(TraverserRequirement.SIDE_EFFECTS, TraverserRequirement.BULK);
+ }
+
+ @Override
+ public GroupSideEffectStepV3d0<S, K, V, R> clone() {
+ final GroupSideEffectStepV3d0<S, K, V, R> clone = (GroupSideEffectStepV3d0<S, K, V, R>) super.clone();
+ if (null != this.keyTraversal)
+ clone.keyTraversal = clone.integrateChild(this.keyTraversal.clone());
+ if (null != this.valueTraversal)
+ clone.valueTraversal = clone.integrateChild(this.valueTraversal.clone());
+ if (null != this.reduceTraversal)
+ clone.reduceTraversal = clone.integrateChild(this.reduceTraversal.clone());
+ return clone;
+ }
+
+ @Override
+ public int hashCode() {
+ int result = super.hashCode() ^ this.sideEffectKey.hashCode();
+ if (this.keyTraversal != null) result ^= this.keyTraversal.hashCode();
+ if (this.valueTraversal != null) result ^= this.valueTraversal.hashCode();
+ if (this.reduceTraversal != null) result ^= this.reduceTraversal.hashCode();
+ return result;
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/2f3b2ac9/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/sideEffect/GroupStep.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/sideEffect/GroupStep.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/sideEffect/GroupStep.java
deleted file mode 100644
index 845591a..0000000
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/sideEffect/GroupStep.java
+++ /dev/null
@@ -1,240 +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 org.apache.tinkerpop.gremlin.process.traversal.step.sideEffect;
-
-import org.apache.tinkerpop.gremlin.process.computer.MemoryComputeKey;
-import org.apache.tinkerpop.gremlin.process.traversal.Step;
-import org.apache.tinkerpop.gremlin.process.traversal.Traversal;
-import org.apache.tinkerpop.gremlin.process.traversal.Traverser;
-import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__;
-import org.apache.tinkerpop.gremlin.process.traversal.lambda.ElementValueTraversal;
-import org.apache.tinkerpop.gremlin.process.traversal.lambda.FunctionTraverser;
-import org.apache.tinkerpop.gremlin.process.traversal.lambda.IdentityTraversal;
-import org.apache.tinkerpop.gremlin.process.traversal.lambda.TokenTraversal;
-import org.apache.tinkerpop.gremlin.process.traversal.step.Barrier;
-import org.apache.tinkerpop.gremlin.process.traversal.step.ByModulating;
-import org.apache.tinkerpop.gremlin.process.traversal.step.GraphComputing;
-import org.apache.tinkerpop.gremlin.process.traversal.step.SideEffectCapable;
-import org.apache.tinkerpop.gremlin.process.traversal.step.TraversalParent;
-import org.apache.tinkerpop.gremlin.process.traversal.step.map.LambdaMapStep;
-import org.apache.tinkerpop.gremlin.process.traversal.traverser.TraverserRequirement;
-import org.apache.tinkerpop.gremlin.process.traversal.traverser.util.TraverserSet;
-import org.apache.tinkerpop.gremlin.process.traversal.util.TraversalHelper;
-import org.apache.tinkerpop.gremlin.process.traversal.util.TraversalUtil;
-import org.apache.tinkerpop.gremlin.structure.util.StringFactory;
-import org.apache.tinkerpop.gremlin.util.function.HashMapSupplier;
-
-import java.io.Serializable;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Optional;
-import java.util.Set;
-import java.util.function.BinaryOperator;
-
-/**
- * @author Marko A. Rodriguez (http://markorodriguez.com)
- */
-public final class GroupStep<S, K, V> extends SideEffectStep<S> implements SideEffectCapable, TraversalParent, ByModulating, GraphComputing {
-
- private char state = 'k';
- private Traversal.Admin<S, K> keyTraversal = null;
- private Traversal.Admin<S, ?> valueTraversal = this.integrateChild(__.identity().asAdmin()); // used in OLAP
- private Traversal.Admin<?, V> reduceTraversal = this.integrateChild(__.fold().asAdmin()); // used in OLAP
- private Traversal.Admin<S, V> valueReduceTraversal = this.integrateChild(__.fold().asAdmin()); // used in OLTP
- ///
- private String sideEffectKey;
- private boolean onGraphComputer = false;
-
- public GroupStep(final Traversal.Admin traversal, final String sideEffectKey) {
- super(traversal);
- this.sideEffectKey = sideEffectKey;
- this.traversal.asAdmin().getSideEffects().registerSupplierIfAbsent(this.sideEffectKey, HashMapSupplier.instance());
- }
-
- @Override
- public void modulateBy(final Traversal.Admin<?, ?> kvTraversal) {
- if ('k' == this.state) {
- this.keyTraversal = this.integrateChild(kvTraversal);
- this.state = 'v';
- } else if ('v' == this.state) {
- this.valueReduceTraversal = this.integrateChild(GroupStep.convertValueTraversal(kvTraversal));
- final List<Traversal.Admin<?, ?>> splitTraversal = GroupStep.splitOnBarrierStep(this.valueReduceTraversal);
- this.valueTraversal = this.integrateChild(splitTraversal.get(0));
- this.reduceTraversal = this.integrateChild(splitTraversal.get(1));
- this.state = 'x';
- } else {
- throw new IllegalStateException("The key and value traversals for group()-step have already been set: " + this);
- }
- }
-
- @Override
- public Optional<MemoryComputeKey> getMemoryComputeKey() {
- return Optional.of(MemoryComputeKey.of(this.getSideEffectKey(), GroupBiOperator.INSTANCE, false, false));
- }
-
- @Override
- protected void sideEffect(final Traverser.Admin<S> traverser) {
- Map<K, Object> map = traverser.sideEffects(this.sideEffectKey);
- final K key = TraversalUtil.applyNullable(traverser, this.keyTraversal);
- final TraverserSet<Object> traverserSet = new TraverserSet<>();
- if (this.onGraphComputer) {
- this.valueTraversal.reset();
- this.valueTraversal.addStart(traverser);
- this.valueTraversal.getEndStep().forEachRemaining(t -> traverserSet.add((Traverser.Admin) t.asAdmin()));
- final TraverserSet<Object> set = (TraverserSet) map.get(key);
- if (null == set)
- map.put(key, traverserSet);
- else
- set.addAll(traverserSet);
- } else {
- traverserSet.add((Traverser.Admin) traverser.split());
- Traversal.Admin valueReduceTraversal = (Traversal.Admin) map.get(key);
- if (null == valueReduceTraversal) {
- valueReduceTraversal = this.valueReduceTraversal.clone();
- map.put(key, valueReduceTraversal);
- }
- traverserSet.forEach(valueReduceTraversal::addStart);
- // TODO: TraversalHelper.getFirstStepOfAssignableClass(Barrier.class, valueReduceTraversal).ifPresent(Barrier::processAllStarts);
- }
- }
-
- @Override
- public String getSideEffectKey() {
- return this.sideEffectKey;
- }
-
- @Override
- public void onGraphComputer() {
- this.onGraphComputer = true;
- }
-
- @Override
- public String toString() {
- return StringFactory.stepString(this, this.sideEffectKey, this.keyTraversal, this.valueReduceTraversal);
- }
-
- @Override
- public List<Traversal.Admin<?, ?>> getLocalChildren() {
- final List<Traversal.Admin<?, ?>> children = new ArrayList<>(4);
- if (null != this.keyTraversal)
- children.add((Traversal.Admin) this.keyTraversal);
- children.add(this.valueReduceTraversal);
- children.add(this.valueTraversal);
- children.add(this.reduceTraversal);
- return children;
- }
-
- @Override
- public Set<TraverserRequirement> getRequirements() {
- return this.getSelfAndChildRequirements(TraverserRequirement.OBJECT, TraverserRequirement.BULK, TraverserRequirement.SIDE_EFFECTS);
- }
-
- @Override
- public GroupStep<S, K, V> clone() {
- final GroupStep<S, K, V> clone = (GroupStep<S, K, V>) super.clone();
- if (null != this.keyTraversal)
- clone.keyTraversal = clone.integrateChild(this.keyTraversal.clone());
- clone.valueReduceTraversal = clone.integrateChild(this.valueReduceTraversal.clone());
- clone.valueTraversal = clone.integrateChild(this.valueTraversal.clone());
- clone.reduceTraversal = clone.integrateChild(this.reduceTraversal.clone());
- return clone;
- }
-
- @Override
- public int hashCode() {
- int result = super.hashCode() ^ this.sideEffectKey.hashCode();
- if (this.keyTraversal != null) result ^= this.keyTraversal.hashCode();
- result ^= this.valueReduceTraversal.hashCode();
- return result;
- }
-
- @Override
- public Object generateFinalResult(final Object object) {
- final Map<K, Object> map = (Map<K, Object>) object;
- final Map<K, Object> reducedMap = new HashMap<>();
- if (this.onGraphComputer) {
- for (final K key : map.keySet()) {
- final Traversal.Admin<?, V> reduceClone = this.reduceTraversal.clone();
- reduceClone.addStarts(((TraverserSet) map.get(key)).iterator());
- reducedMap.put(key, reduceClone.next());
- }
- } else
- map.forEach((key, traversal) -> reducedMap.put(key, ((Traversal.Admin) traversal).next()));
- return reducedMap;
- }
-
- /////////////////////////////
-
- private static <S, E> Traversal.Admin<S, E> convertValueTraversal(final Traversal.Admin<S, E> valueReduceTraversal) {
- if (valueReduceTraversal instanceof ElementValueTraversal ||
- valueReduceTraversal instanceof TokenTraversal ||
- valueReduceTraversal instanceof IdentityTraversal ||
- valueReduceTraversal.getStartStep() instanceof LambdaMapStep && ((LambdaMapStep) valueReduceTraversal.getStartStep()).getMapFunction() instanceof FunctionTraverser) {
- return (Traversal.Admin<S, E>) __.map(valueReduceTraversal).fold();
- } else {
- return valueReduceTraversal;
- }
- }
-
- private static List<Traversal.Admin<?, ?>> splitOnBarrierStep(final Traversal.Admin<?, ?> valueReduceTraversal) {
- if (TraversalHelper.getFirstStepOfAssignableClass(Barrier.class, valueReduceTraversal).isPresent()) {
- final Traversal.Admin<?, ?> first = __.identity().asAdmin();
- final Traversal.Admin<?, ?> second = __.identity().asAdmin();
- boolean onSecond = false;
- for (final Step step : valueReduceTraversal.getSteps()) {
- if (step instanceof Barrier)
- onSecond = true;
- if (onSecond)
- second.addStep(step.clone());
- else
- first.addStep(step.clone());
- }
- return Arrays.asList(first, second);
- } else {
- return Arrays.asList(valueReduceTraversal.clone(), __.identity().asAdmin());
- }
- }
-
- /////////////////////////////
-
- public static final class GroupBiOperator<K, V> implements BinaryOperator<Map<K, V>>, Serializable {
-
- private static final GroupBiOperator INSTANCE = new GroupBiOperator();
-
- private GroupBiOperator() {
-
- }
-
- @Override
- public Map<K, V> apply(final Map<K, V> mutatingSeed, final Map<K, V> map) {
- for (final K key : map.keySet()) {
- TraverserSet traverserSet = (TraverserSet) mutatingSeed.get(key);
- if (null == traverserSet) {
- traverserSet = new TraverserSet<>();
- mutatingSeed.put(key, (V) traverserSet);
- }
- traverserSet.addAll((TraverserSet) map.get(key));
- }
- return mutatingSeed;
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/2f3b2ac9/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/sideEffect/GroupStepV3d0.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/sideEffect/GroupStepV3d0.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/sideEffect/GroupStepV3d0.java
deleted file mode 100644
index edc571b..0000000
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/sideEffect/GroupStepV3d0.java
+++ /dev/null
@@ -1,182 +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 org.apache.tinkerpop.gremlin.process.traversal.step.sideEffect;
-
-import org.apache.tinkerpop.gremlin.process.computer.MemoryComputeKey;
-import org.apache.tinkerpop.gremlin.process.traversal.Traversal;
-import org.apache.tinkerpop.gremlin.process.traversal.Traverser;
-import org.apache.tinkerpop.gremlin.process.traversal.step.ByModulating;
-import org.apache.tinkerpop.gremlin.process.traversal.step.GraphComputing;
-import org.apache.tinkerpop.gremlin.process.traversal.step.SideEffectCapable;
-import org.apache.tinkerpop.gremlin.process.traversal.step.TraversalParent;
-import org.apache.tinkerpop.gremlin.process.traversal.step.util.BulkSet;
-import org.apache.tinkerpop.gremlin.process.traversal.traverser.TraverserRequirement;
-import org.apache.tinkerpop.gremlin.process.traversal.util.TraversalHelper;
-import org.apache.tinkerpop.gremlin.process.traversal.util.TraversalUtil;
-import org.apache.tinkerpop.gremlin.structure.util.StringFactory;
-import org.apache.tinkerpop.gremlin.util.function.HashMapSupplier;
-
-import java.io.Serializable;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Optional;
-import java.util.Set;
-import java.util.function.BinaryOperator;
-
-/**
- * @author Marko A. Rodriguez (http://markorodriguez.com)
- */
-@Deprecated
-public final class GroupStepV3d0<S, K, V, R> extends SideEffectStep<S> implements SideEffectCapable, TraversalParent, ByModulating, GraphComputing {
-
- private char state = 'k';
- private Traversal.Admin<S, K> keyTraversal = null;
- private Traversal.Admin<S, V> valueTraversal = null;
- private Traversal.Admin<Collection<V>, R> reduceTraversal = null;
- private String sideEffectKey;
-
- public GroupStepV3d0(final Traversal.Admin traversal, final String sideEffectKey) {
- super(traversal);
- this.sideEffectKey = sideEffectKey;
- this.traversal.asAdmin().getSideEffects().registerSupplierIfAbsent(this.sideEffectKey, HashMapSupplier.instance());
- }
-
- @Override
- public Optional<MemoryComputeKey> getMemoryComputeKey() {
- return Optional.of(MemoryComputeKey.of(this.getSideEffectKey(), GroupBiOperatorV3d0.INSTANCE, false, false));
- }
-
- @Override
- protected void sideEffect(final Traverser.Admin<S> traverser) {
- final Map<K, Collection<V>> groupMap = traverser.sideEffects(this.sideEffectKey);
- final K key = TraversalUtil.applyNullable(traverser, keyTraversal);
- final V value = TraversalUtil.applyNullable(traverser, valueTraversal);
- Collection<V> values = groupMap.get(key);
- if (null == values) {
- values = new BulkSet<>();
- groupMap.put(key, values);
- }
- TraversalHelper.addToCollectionUnrollIterator(values, value, traverser.bulk());
- }
-
- @Override
- public String getSideEffectKey() {
- return this.sideEffectKey;
- }
-
- @Override
- public void onGraphComputer() {
- }
-
- @Override
- public String toString() {
- return StringFactory.stepString(this, this.sideEffectKey, this.keyTraversal, this.valueTraversal, this.reduceTraversal);
- }
-
- @Override
- public Map<K, R> generateFinalResult(final Object valueMap) {
- final Map<K, R> reducedMap = new HashMap<>();
- for (final K key : ((Map<K, Collection<V>>) valueMap).keySet()) {
- final R r = TraversalUtil.applyNullable(((Map<K, Collection<V>>) valueMap).get(key), this.reduceTraversal);
- reducedMap.put(key, r);
- }
- return reducedMap;
- }
-
- @Override
- public <A, B> List<Traversal.Admin<A, B>> getLocalChildren() {
- final List<Traversal.Admin<A, B>> children = new ArrayList<>(3);
- if (null != this.keyTraversal)
- children.add((Traversal.Admin) this.keyTraversal);
- if (null != this.valueTraversal)
- children.add((Traversal.Admin) this.valueTraversal);
- if (null != this.reduceTraversal)
- children.add((Traversal.Admin) this.reduceTraversal);
- return children;
- }
-
- @Override
- public void modulateBy(final Traversal.Admin<?, ?> kvrTraversal) {
- if ('k' == this.state) {
- this.keyTraversal = this.integrateChild(kvrTraversal);
- this.state = 'v';
- } else if ('v' == this.state) {
- this.valueTraversal = this.integrateChild(kvrTraversal);
- this.state = 'r';
- } else if ('r' == this.state) {
- this.reduceTraversal = this.integrateChild(kvrTraversal);
- this.state = 'x';
- } else {
- throw new IllegalStateException("The key, value, and reduce functions for group()-step have already been set");
- }
- }
-
- @Override
- public Set<TraverserRequirement> getRequirements() {
- return this.getSelfAndChildRequirements(TraverserRequirement.SIDE_EFFECTS, TraverserRequirement.BULK);
- }
-
- @Override
- public GroupStepV3d0<S, K, V, R> clone() {
- final GroupStepV3d0<S, K, V, R> clone = (GroupStepV3d0<S, K, V, R>) super.clone();
- if (null != this.keyTraversal)
- clone.keyTraversal = clone.integrateChild(this.keyTraversal.clone());
- if (null != this.valueTraversal)
- clone.valueTraversal = clone.integrateChild(this.valueTraversal.clone());
- if (null != this.reduceTraversal)
- clone.reduceTraversal = clone.integrateChild(this.reduceTraversal.clone());
- return clone;
- }
-
- @Override
- public int hashCode() {
- int result = super.hashCode() ^ this.sideEffectKey.hashCode();
- if (this.keyTraversal != null) result ^= this.keyTraversal.hashCode();
- if (this.valueTraversal != null) result ^= this.valueTraversal.hashCode();
- if (this.reduceTraversal != null) result ^= this.reduceTraversal.hashCode();
- return result;
- }
-
- //////////
-
- @Deprecated
- public static class GroupBiOperatorV3d0<K, V> implements BinaryOperator<Map<K, V>>, Serializable {
-
- private final static GroupBiOperatorV3d0 INSTANCE = new GroupBiOperatorV3d0();
-
- @Override
- public Map<K, V> apply(final Map<K, V> mutatingSeed, final Map<K, V> map) {
- for (final K key : map.keySet()) {
- final BulkSet<V> values = (BulkSet<V>) map.get(key);
- BulkSet<V> seedValues = (BulkSet<V>) mutatingSeed.get(key);
- if (null == seedValues) {
- seedValues = new BulkSet<>();
- mutatingSeed.put(key, (V) seedValues);
- }
- seedValues.addAll(values);
- }
- return mutatingSeed;
- }
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/2f3b2ac9/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/util/ReducingBarrierStep.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/util/ReducingBarrierStep.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/util/ReducingBarrierStep.java
index b147092..e54fdca 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/util/ReducingBarrierStep.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/util/ReducingBarrierStep.java
@@ -100,7 +100,7 @@ public abstract class ReducingBarrierStep<S, E> extends AbstractStep<S, E> imple
throw FastNoSuchElementException.instance();
this.processAllStarts();
this.done = true;
- final Traverser<E> traverser = TraversalHelper.getRootTraversal(this.getTraversal()).getTraverserGenerator().generate(this.onGraphComputer ? this.seed : FinalGet.tryFinalGet(this.seed), (Step) this, 1l);
+ final Traverser<E> traverser = TraversalHelper.getRootTraversal(this.getTraversal()).getTraverserGenerator().generate(this.onGraphComputer ? this.seed : this.generateFinalResult(this.seed), (Step) this, 1l);
this.seed = null;
return traverser;
}
http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/2f3b2ac9/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/gryo/GryoMapper.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/gryo/GryoMapper.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/gryo/GryoMapper.java
index 2bf387a..d60142b 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/gryo/GryoMapper.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/gryo/GryoMapper.java
@@ -26,14 +26,14 @@ import org.apache.tinkerpop.gremlin.process.traversal.Operator;
import org.apache.tinkerpop.gremlin.process.traversal.Path;
import org.apache.tinkerpop.gremlin.process.traversal.step.map.CountGlobalStep;
import org.apache.tinkerpop.gremlin.process.traversal.step.map.FoldStep;
+import org.apache.tinkerpop.gremlin.process.traversal.step.map.GroupCountStep;
+import org.apache.tinkerpop.gremlin.process.traversal.step.map.GroupStep;
+import org.apache.tinkerpop.gremlin.process.traversal.step.map.GroupStepV3d0;
import org.apache.tinkerpop.gremlin.process.traversal.step.map.MaxGlobalStep;
import org.apache.tinkerpop.gremlin.process.traversal.step.map.MeanGlobalStep;
import org.apache.tinkerpop.gremlin.process.traversal.step.map.MinGlobalStep;
import org.apache.tinkerpop.gremlin.process.traversal.step.map.SumGlobalStep;
import org.apache.tinkerpop.gremlin.process.traversal.step.map.TreeStep;
-import org.apache.tinkerpop.gremlin.process.traversal.step.sideEffect.GroupCountStep;
-import org.apache.tinkerpop.gremlin.process.traversal.step.sideEffect.GroupStep;
-import org.apache.tinkerpop.gremlin.process.traversal.step.sideEffect.GroupStepV3d0;
import org.apache.tinkerpop.gremlin.process.traversal.step.sideEffect.StoreStep;
import org.apache.tinkerpop.gremlin.process.traversal.step.util.BulkSet;
import org.apache.tinkerpop.gremlin.process.traversal.step.util.Tree;
http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/2f3b2ac9/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/GroupCountStepTest.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/GroupCountStepTest.java b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/GroupCountStepTest.java
new file mode 100644
index 0000000..f4eb7ac
--- /dev/null
+++ b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/GroupCountStepTest.java
@@ -0,0 +1,42 @@
+/*
+ * 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.traversal.step.map;
+
+import org.apache.tinkerpop.gremlin.process.traversal.Traversal;
+import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__;
+import org.apache.tinkerpop.gremlin.process.traversal.step.StepTest;
+
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * @author Marko A. Rodriguez (http://markorodriguez.com)
+ */
+public class GroupCountStepTest extends StepTest {
+
+ @Override
+ protected List<Traversal> getTraversals() {
+ return Arrays.asList(
+ __.groupCount(),
+ __.groupCount().by("name"),
+ __.groupCount().by("age")
+ );
+ }
+}