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 2015/10/07 23:57:54 UTC
incubator-tinkerpop git commit: Removed GroupCountStep where
groupCount() just calls GroupStep under the hood. Super simple to do and now
we have 2 less steps to maintain.
Repository: incubator-tinkerpop
Updated Branches:
refs/heads/TINKERPOP3-872 [created] db1cd97e3
Removed GroupCountStep where groupCount() just calls GroupStep under the hood. Super simple to do and now we have 2 less steps to maintain.
Project: http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/commit/db1cd97e
Tree: http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/tree/db1cd97e
Diff: http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/diff/db1cd97e
Branch: refs/heads/TINKERPOP3-872
Commit: db1cd97e3ec98938961e394489dd902acbb3009f
Parents: e54f0aa
Author: Marko A. Rodriguez <ok...@gmail.com>
Authored: Wed Oct 7 15:57:43 2015 -0600
Committer: Marko A. Rodriguez <ok...@gmail.com>
Committed: Wed Oct 7 15:57:43 2015 -0600
----------------------------------------------------------------------
.../traversal/dsl/graph/GraphTraversal.java | 10 +-
.../traversal/step/map/GroupCountStep.java | 182 -------------------
.../process/traversal/step/map/GroupStep.java | 61 ++++---
.../sideEffect/GroupCountSideEffectStep.java | 174 ------------------
.../step/sideEffect/GroupSideEffectStep.java | 55 ++++--
5 files changed, 76 insertions(+), 406 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/db1cd97e/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 f91fed9..7d08407 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,7 +72,6 @@ import org.apache.tinkerpop.gremlin.process.traversal.step.map.DedupLocalStep;
import org.apache.tinkerpop.gremlin.process.traversal.step.map.EdgeOtherVertexStep;
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.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;
@@ -111,7 +110,6 @@ 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.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;
@@ -627,7 +625,7 @@ public interface GraphTraversal<S, E> extends Traversal<S, E> {
}
public default <K, V> GraphTraversal<S, Map<K, V>> group() {
- return this.asAdmin().addStep(new GroupStep<>(this.asAdmin()));
+ return this.asAdmin().addStep(new GroupStep<>(this.asAdmin(), false));
}
/**
@@ -639,7 +637,7 @@ public interface GraphTraversal<S, E> extends Traversal<S, E> {
}
public default <K> GraphTraversal<S, Map<K, Long>> groupCount() {
- return this.asAdmin().addStep(new GroupCountStep<>(this.asAdmin()));
+ return this.asAdmin().addStep(new GroupStep<>(this.asAdmin(), true));
}
public default GraphTraversal<S, Tree> tree() {
@@ -966,7 +964,7 @@ public interface GraphTraversal<S, E> extends Traversal<S, E> {
}
public default GraphTraversal<S, E> group(final String sideEffectKey) {
- return this.asAdmin().addStep(new GroupSideEffectStep<>(this.asAdmin(), sideEffectKey));
+ return this.asAdmin().addStep(new GroupSideEffectStep<>(this.asAdmin(), sideEffectKey, false));
}
/**
@@ -977,7 +975,7 @@ public interface GraphTraversal<S, E> extends Traversal<S, E> {
}
public default GraphTraversal<S, E> groupCount(final String sideEffectKey) {
- return this.asAdmin().addStep(new GroupCountSideEffectStep<>(this.asAdmin(), sideEffectKey));
+ return this.asAdmin().addStep(new GroupSideEffectStep<>(this.asAdmin(), sideEffectKey, true));
}
public default GraphTraversal<S, E> tree(final String sideEffectKey) {
http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/db1cd97e/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
deleted file mode 100644
index 7f3904e..0000000
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/GroupCountStep.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.map;
-
-import org.apache.tinkerpop.gremlin.process.computer.KeyValue;
-import org.apache.tinkerpop.gremlin.process.computer.MapReduce;
-import org.apache.tinkerpop.gremlin.process.computer.traversal.TraversalVertexProgram;
-import org.apache.tinkerpop.gremlin.process.computer.util.StaticMapReduce;
-import org.apache.tinkerpop.gremlin.process.traversal.Traversal;
-import org.apache.tinkerpop.gremlin.process.traversal.Traverser;
-import org.apache.tinkerpop.gremlin.process.traversal.step.MapReducer;
-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.traverser.util.TraverserSet;
-import org.apache.tinkerpop.gremlin.process.traversal.util.TraversalUtil;
-import org.apache.tinkerpop.gremlin.structure.Vertex;
-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.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.function.BiFunction;
-
-/**
- * @author Marko A. Rodriguez (http://markorodriguez.com)
- */
-public final class GroupCountStep<S, E> extends ReducingBarrierStep<S, Map<E, Long>> implements MapReducer, TraversalParent {
-
- private Traversal.Admin<S, E> groupTraversal = null;
-
- public GroupCountStep(final Traversal.Admin traversal) {
- super(traversal);
- this.setSeedSupplier(HashMapSupplier.instance());
- this.setBiFunction(new GroupCountBiFunction(this));
- }
-
-
- @Override
- public void addLocalChild(final Traversal.Admin<?, ?> groupTraversal) {
- this.groupTraversal = this.integrateChild(groupTraversal);
- }
-
- @Override
- public List<Traversal.Admin<S, E>> getLocalChildren() {
- return null == this.groupTraversal ? Collections.emptyList() : Collections.singletonList(this.groupTraversal);
- }
-
- @Override
- public Set<TraverserRequirement> getRequirements() {
- return this.getSelfAndChildRequirements(TraverserRequirement.BULK);
- }
-
- @Override
- public MapReduce<E, Long, E, Long, Map<E, Long>> getMapReduce() {
- return GroupCountMapReduce.instance();
- }
-
- @Override
- public GroupCountStep<S, E> clone() {
- final GroupCountStep<S, E> clone = (GroupCountStep<S, E>) super.clone();
- if (null != this.groupTraversal)
- clone.groupTraversal = clone.integrateChild(this.groupTraversal.clone());
- clone.setBiFunction(new GroupCountBiFunction<>(clone));
- return clone;
- }
-
- @Override
- public int hashCode() {
- int result = super.hashCode();
- for (final Traversal.Admin<S, E> traversal : this.getLocalChildren()) {
- result ^= traversal.hashCode();
- }
- return result;
- }
-
- @Override
- public Traverser<Map<E, Long>> processNextStart() {
- if (this.byPass) {
- final Traverser.Admin<S> traverser = this.starts.next();
- return traverser.asAdmin().split(TraversalUtil.applyNullable(traverser, (Traversal.Admin<S, Map<E, Long>>) this.groupTraversal), this);
- } else {
- return super.processNextStart();
- }
- }
-
- @Override
- public String toString() {
- return StringFactory.stepString(this, this.groupTraversal);
- }
-
- ///////////
-
- private static class GroupCountBiFunction<S, E> implements BiFunction<Map<E, Long>, Traverser<S>, Map<E, Long>>, Serializable {
-
- private final GroupCountStep<S, E> groupCountStep;
-
- private GroupCountBiFunction(final GroupCountStep<S, E> groupCountStep) {
- this.groupCountStep = groupCountStep;
-
- }
-
- @Override
- public Map<E, Long> apply(final Map<E, Long> mutatingSeed, final Traverser<S> traverser) {
- MapHelper.incr(mutatingSeed, TraversalUtil.applyNullable(traverser.asAdmin(), this.groupCountStep.groupTraversal), traverser.bulk());
- return mutatingSeed;
- }
- }
-
- ///////////
-
- public static final class GroupCountMapReduce<E> extends StaticMapReduce<E, Long, E, Long, Map<E, Long>> {
-
- private static final GroupCountMapReduce INSTANCE = new GroupCountMapReduce();
-
- private GroupCountMapReduce() {
-
- }
-
- @Override
- public boolean doStage(final Stage stage) {
- return true;
- }
-
- @Override
- public void map(final Vertex vertex, final MapEmitter<E, Long> emitter) {
- vertex.<TraverserSet<E>>property(TraversalVertexProgram.HALTED_TRAVERSERS).ifPresent(traverserSet -> traverserSet.forEach(traverser -> emitter.emit(traverser.get(), traverser.bulk())));
- }
-
- @Override
- public void reduce(final E key, final Iterator<Long> values, final ReduceEmitter<E, Long> emitter) {
- long counter = 0;
- while (values.hasNext()) {
- counter = counter + values.next();
- }
- emitter.emit(key, counter);
- }
-
- @Override
- public void combine(final E key, final Iterator<Long> values, final ReduceEmitter<E, Long> emitter) {
- reduce(key, values, emitter);
- }
-
- @Override
- public Map<E, Long> generateFinalResult(final Iterator<KeyValue<E, Long>> keyValues) {
- final Map<E, Long> map = new HashMap<>();
- keyValues.forEachRemaining(keyValue -> map.put(keyValue.getKey(), keyValue.getValue()));
- return map;
- }
-
- @Override
- public String getMemoryKey() {
- return REDUCING;
- }
-
- public static final <E> GroupCountMapReduce<E> instance() {
- return INSTANCE;
- }
- }
-}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/db1cd97e/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
index d13f24d..dd0468f 100644
--- 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
@@ -60,19 +60,29 @@ public final class GroupStep<S, K, V> extends ReducingBarrierStep<S, Map<K, V>>
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 Traversal.Admin<S, ?> valueTraversal; // used in OLAP
+ private Traversal.Admin<?, V> reduceTraversal; // used in OLAP
+ private Traversal.Admin<S, V> valueReduceTraversal; // used in OLTP
+ private boolean groupCount = false;
- public GroupStep(final Traversal.Admin traversal) {
+ public GroupStep(final Traversal.Admin traversal, final boolean groupCount) {
super(traversal);
this.setSeedSupplier((Supplier) new GroupStepHelper.GroupMapSupplier());
this.setBiFunction(new GroupBiFunction(this));
+ if (this.groupCount = groupCount) {
+ this.valueReduceTraversal = this.integrateChild(__.count().asAdmin());
+ this.valueTraversal = this.integrateChild(__.identity().asAdmin());
+ this.reduceTraversal = this.integrateChild(__.count().asAdmin());
+ } else {
+ this.valueTraversal = this.integrateChild(__.identity().asAdmin());
+ this.reduceTraversal = this.integrateChild(__.fold().asAdmin());
+ this.valueReduceTraversal = this.integrateChild(__.fold().asAdmin());
+ }
}
@Override
- public List<Traversal.Admin<?,?>> getLocalChildren() {
- final List<Traversal.Admin<?,?>> children = new ArrayList<>(4);
+ 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);
@@ -87,6 +97,8 @@ public final class GroupStep<S, K, V> extends ReducingBarrierStep<S, Map<K, V>>
this.keyTraversal = this.integrateChild(kvTraversal);
this.state = 'v';
} else if ('v' == this.state) {
+ if (this.groupCount)
+ throw new IllegalStateException("The key traversal for groupCount()-step have already been set: " + this);
this.valueReduceTraversal = this.integrateChild(GroupStepHelper.convertValueTraversal(kvTraversal));
final List<Traversal.Admin<?, ?>> splitTraversal = GroupStepHelper.splitOnBarrierStep(this.valueReduceTraversal);
this.valueTraversal = this.integrateChild(splitTraversal.get(0));
@@ -103,6 +115,24 @@ public final class GroupStep<S, K, V> extends ReducingBarrierStep<S, Map<K, V>>
}
@Override
+ public Traverser<Map<K, V>> processNextStart() {
+ if (this.byPass) {
+ final Traverser.Admin<S> traverser = this.starts.next();
+ final K key = TraversalUtil.applyNullable(traverser, this.keyTraversal);
+ this.valueTraversal.addStart(traverser);
+ final BulkSet<?> value = this.valueTraversal.toBulkSet();
+ return traverser.asAdmin().split(new Object[]{key, value}, (Step) this);
+ } else {
+ return super.processNextStart();
+ }
+ }
+
+ @Override
+ public MapReduce<K, Collection<?>, K, V, Map<K, V>> getMapReduce() {
+ return new GroupMapReduce<>(this);
+ }
+
+ @Override
public GroupStep<S, K, V> clone() {
final GroupStep<S, K, V> clone = (GroupStep<S, K, V>) super.clone();
if (null != this.keyTraversal)
@@ -118,28 +148,11 @@ public final class GroupStep<S, K, V> extends ReducingBarrierStep<S, Map<K, V>>
public int hashCode() {
int result = this.valueReduceTraversal.hashCode();
if (this.keyTraversal != null) result ^= this.keyTraversal.hashCode();
+ result ^= Boolean.valueOf(this.groupCount).hashCode();
return result;
}
@Override
- public MapReduce<K, Collection<?>, K, V, Map<K, V>> getMapReduce() {
- return new GroupMapReduce<>(this);
- }
-
- @Override
- public Traverser<Map<K, V>> processNextStart() {
- if (this.byPass) {
- final Traverser.Admin<S> traverser = this.starts.next();
- final K key = TraversalUtil.applyNullable(traverser, this.keyTraversal);
- this.valueTraversal.addStart(traverser);
- final BulkSet<?> value = this.valueTraversal.toBulkSet();
- return traverser.asAdmin().split(new Object[]{key, value}, (Step) this);
- } else {
- return super.processNextStart();
- }
- }
-
- @Override
public String toString() {
return StringFactory.stepString(this, this.keyTraversal, this.valueReduceTraversal);
}
http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/db1cd97e/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
deleted file mode 100644
index f26206a..0000000
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/sideEffect/GroupCountSideEffectStep.java
+++ /dev/null
@@ -1,174 +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.commons.configuration.Configuration;
-import org.apache.tinkerpop.gremlin.process.computer.KeyValue;
-import org.apache.tinkerpop.gremlin.process.computer.MapReduce;
-import org.apache.tinkerpop.gremlin.process.computer.traversal.TraversalVertexProgram;
-import org.apache.tinkerpop.gremlin.process.computer.traversal.VertexTraversalSideEffects;
-import org.apache.tinkerpop.gremlin.process.computer.util.StaticMapReduce;
-import org.apache.tinkerpop.gremlin.process.traversal.Traversal;
-import org.apache.tinkerpop.gremlin.process.traversal.Traverser;
-import org.apache.tinkerpop.gremlin.process.traversal.step.MapReducer;
-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.Graph;
-import org.apache.tinkerpop.gremlin.structure.Vertex;
-import org.apache.tinkerpop.gremlin.structure.util.StringFactory;
-import org.apache.tinkerpop.gremlin.util.function.HashMapSupplier;
-
-import java.util.*;
-import java.util.function.Supplier;
-
-/**
- * @author Marko A. Rodriguez (http://markorodriguez.com)
- */
-public final class GroupCountSideEffectStep<S, E> extends SideEffectStep<S> implements SideEffectCapable, TraversalParent, MapReducer<E, Long, E, Long, Map<E, Long>> {
-
- private Traversal.Admin<S, E> groupTraversal = 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.groupTraversal), traverser.bulk());
- }
-
- @Override
- public String getSideEffectKey() {
- return this.sideEffectKey;
- }
-
- @Override
- public MapReduce<E, Long, E, Long, Map<E, Long>> getMapReduce() {
- return new GroupCountSideEffectMapReduce<>(this);
- }
-
- @Override
- public String toString() {
- return StringFactory.stepString(this, this.sideEffectKey, this.groupTraversal);
- }
-
- @Override
- public void addLocalChild(final Traversal.Admin<?, ?> groupTraversal) {
- this.groupTraversal = this.integrateChild(groupTraversal);
- }
-
- @Override
- public List<Traversal.Admin<S, E>> getLocalChildren() {
- return null == this.groupTraversal ? Collections.emptyList() : Collections.singletonList(this.groupTraversal);
- }
-
- @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.groupTraversal)
- clone.groupTraversal = clone.integrateChild(this.groupTraversal.clone());
- return clone;
- }
-
- @Override
- public int hashCode() {
- int result = super.hashCode() ^ this.sideEffectKey.hashCode();
- if (this.groupTraversal != null) result ^= this.groupTraversal.hashCode();
- return result;
- }
-
- ///////
-
- public static final class GroupCountSideEffectMapReduce<E> extends StaticMapReduce<E, Long, E, Long, Map<E, Long>> {
-
- public static final String GROUP_COUNT_SIDE_EFFECT_STEP_SIDE_EFFECT_KEY = "gremlin.groupCountSideEffectStep.sideEffectKey";
-
- private String sideEffectKey;
- private Supplier<Map<E, Long>> mapSupplier;
-
- private GroupCountSideEffectMapReduce() {
-
- }
-
- public GroupCountSideEffectMapReduce(final GroupCountSideEffectStep step) {
- this.sideEffectKey = step.getSideEffectKey();
- this.mapSupplier = step.getTraversal().asAdmin().getSideEffects().<Map<E, Long>>getRegisteredSupplier(this.sideEffectKey).orElse(HashMap::new);
- }
-
- @Override
- public void storeState(final Configuration configuration) {
- super.storeState(configuration);
- configuration.setProperty(GROUP_COUNT_SIDE_EFFECT_STEP_SIDE_EFFECT_KEY, this.sideEffectKey);
- }
-
- @Override
- public void loadState(final Graph graph, final Configuration configuration) {
- this.sideEffectKey = configuration.getString(GROUP_COUNT_SIDE_EFFECT_STEP_SIDE_EFFECT_KEY);
- this.mapSupplier = TraversalVertexProgram.getTraversal(graph, configuration).getSideEffects().<Map<E, Long>>getRegisteredSupplier(this.sideEffectKey).orElse(HashMap::new);
- }
-
- @Override
- public boolean doStage(final Stage stage) {
- return true;
- }
-
- @Override
- public void map(final Vertex vertex, final MapEmitter<E, Long> emitter) {
- VertexTraversalSideEffects.of(vertex).<Map<E, Number>>get(this.sideEffectKey).ifPresent(map -> map.forEach((k, v) -> emitter.emit(k, v.longValue())));
- }
-
- @Override
- public void reduce(final E key, final Iterator<Long> values, final ReduceEmitter<E, Long> emitter) {
- long counter = 0;
- while (values.hasNext()) {
- counter = counter + values.next();
- }
- emitter.emit(key, counter);
- }
-
- @Override
- public void combine(final E key, final Iterator<Long> values, final ReduceEmitter<E, Long> emitter) {
- reduce(key, values, emitter);
- }
-
- @Override
- public Map<E, Long> generateFinalResult(final Iterator<KeyValue<E, Long>> keyValues) {
- final Map<E, Long> map = this.mapSupplier.get();
- keyValues.forEachRemaining(keyValue -> map.put(keyValue.getKey(), keyValue.getValue()));
- return map;
- }
-
- @Override
- public String getMemoryKey() {
- return this.sideEffectKey;
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/db1cd97e/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
index ef3b88a..82c27f4 100644
--- 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
@@ -59,18 +59,39 @@ public final class GroupSideEffectStep<S, K, V> extends SideEffectStep<S> implem
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 Traversal.Admin<S, ?> valueTraversal; // used in OLAP
+ private Traversal.Admin<?, V> reduceTraversal; // used in OLAP
+ private Traversal.Admin<S, V> valueReduceTraversal; // used in OLTP
///
private String sideEffectKey;
+ private boolean groupCount = false;
private boolean onGraphComputer = false;
private GroupStepHelper.GroupMap<S, K, V> groupMap;
- public GroupSideEffectStep(final Traversal.Admin traversal, final String sideEffectKey) {
+ public GroupSideEffectStep(final Traversal.Admin traversal, final String sideEffectKey, final boolean groupCount) {
super(traversal);
this.sideEffectKey = sideEffectKey;
this.traversal.asAdmin().getSideEffects().registerSupplierIfAbsent(this.sideEffectKey, HashMapSupplier.instance());
+ if (this.groupCount = groupCount) {
+ this.valueReduceTraversal = this.integrateChild(__.count().asAdmin());
+ this.valueTraversal = this.integrateChild(__.identity().asAdmin());
+ this.reduceTraversal = this.integrateChild(__.count().asAdmin());
+ } else {
+ this.valueTraversal = this.integrateChild(__.identity().asAdmin());
+ this.reduceTraversal = this.integrateChild(__.fold().asAdmin());
+ this.valueReduceTraversal = this.integrateChild(__.fold().asAdmin());
+ }
+ }
+
+ @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
@@ -79,6 +100,8 @@ public final class GroupSideEffectStep<S, K, V> extends SideEffectStep<S> implem
this.keyTraversal = this.integrateChild(kvTraversal);
this.state = 'v';
} else if ('v' == this.state) {
+ if (this.groupCount)
+ throw new IllegalStateException("The key traversal for groupCount()-step have already been set: " + this);
this.valueReduceTraversal = this.integrateChild(GroupStepHelper.convertValueTraversal(kvTraversal));
final List<Traversal.Admin<?, ?>> splitTraversal = GroupStepHelper.splitOnBarrierStep(this.valueReduceTraversal);
this.valueTraversal = this.integrateChild(splitTraversal.get(0));
@@ -90,6 +113,11 @@ public final class GroupSideEffectStep<S, K, V> extends SideEffectStep<S> implem
}
@Override
+ public Set<TraverserRequirement> getRequirements() {
+ return this.getSelfAndChildRequirements(TraverserRequirement.OBJECT, TraverserRequirement.SIDE_EFFECTS);
+ }
+
+ @Override
protected void sideEffect(final Traverser.Admin<S> traverser) {
if (this.onGraphComputer) { // OLAP
final Map<K, Collection<?>> map = traverser.sideEffects(this.sideEffectKey);
@@ -106,6 +134,8 @@ public final class GroupSideEffectStep<S, K, V> extends SideEffectStep<S> implem
final Object object = traverser.sideEffects(this.sideEffectKey);
if (!(object instanceof GroupStepHelper.GroupMap))
traverser.sideEffects(this.sideEffectKey, this.groupMap = new GroupStepHelper.GroupMap<>((Map<K, V>) object));
+ else
+ this.groupMap = (GroupStepHelper.GroupMap) object;
}
final K key = TraversalUtil.applyNullable(traverser, this.keyTraversal);
Traversal.Admin<S, V> traversal = this.groupMap.get(key);
@@ -139,22 +169,6 @@ public final class GroupSideEffectStep<S, K, V> extends SideEffectStep<S> implem
}
@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.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)
@@ -170,6 +184,7 @@ public final class GroupSideEffectStep<S, K, V> extends SideEffectStep<S> implem
int result = super.hashCode() ^ this.sideEffectKey.hashCode();
if (this.keyTraversal != null) result ^= this.keyTraversal.hashCode();
result ^= this.valueReduceTraversal.hashCode();
+ result ^= Boolean.valueOf(this.groupCount).hashCode();
return result;
}