This is an automated email from the ASF dual-hosted git repository. jin pushed a commit to branch olap-algo in repository https://gitbox.apache.org/repos/asf/incubator-hugegraph.git
commit d1f4177c4ffd4690fe9a48e6af84043cc65bfe71 Author: Jermy Li <[email protected]> AuthorDate: Tue Jun 9 15:32:26 2020 +0800 add subgraph_stat algorithm (#23) Change-Id: If4faafc1a952186c17314c599f611f7ab6132b7b --- .../hugegraph/job/algorithm/AbstractAlgorithm.java | 19 +- .../hugegraph/job/algorithm/AlgorithmPool.java | 2 + .../job/algorithm/SubgraphStatAlgorithm.java | 207 +++++++++++++++++++++ .../job/algorithm/cent/AbstractCentAlgorithm.java | 2 +- .../cent/BetweenessCentralityAlgorithm.java | 2 +- .../cent/ClosenessCentralityAlgorithm.java | 2 +- .../cent/EigenvectorCentralityAlgorithm.java | 2 +- .../algorithm/comm/ClusterCoeffcientAlgorithm.java | 2 +- .../job/algorithm/comm/KCoreAlgorithm.java | 2 +- .../hugegraph/job/algorithm/comm/LpaAlgorithm.java | 7 +- .../job/algorithm/comm/TriangleCountAlgorithm.java | 2 +- .../job/algorithm/path/RingsDetectAlgorithm.java | 2 +- .../job/algorithm/rank/PageRankAlgorithm.java | 49 ++--- .../similarity/FusiformSimilarityAlgorithm.java | 2 +- 14 files changed, 256 insertions(+), 46 deletions(-) diff --git a/hugegraph-core/src/main/java/com/baidu/hugegraph/job/algorithm/AbstractAlgorithm.java b/hugegraph-core/src/main/java/com/baidu/hugegraph/job/algorithm/AbstractAlgorithm.java index f94912902..67d508a47 100644 --- a/hugegraph-core/src/main/java/com/baidu/hugegraph/job/algorithm/AbstractAlgorithm.java +++ b/hugegraph-core/src/main/java/com/baidu/hugegraph/job/algorithm/AbstractAlgorithm.java @@ -132,14 +132,15 @@ public abstract class AbstractAlgorithm implements Algorithm { } protected static Directions directionOutIn(Map<String, Object> parameters) { - E.checkArgument(parameters.containsKey(KEY_DIRECTION), - "The direction must be set"); + if (!parameters.containsKey(KEY_DIRECTION)) { + return Directions.OUT; + } Object direction = parameter(parameters, KEY_DIRECTION); - Directions direct = parseDirection(direction); - E.checkArgument(direct == Directions.OUT || direct == Directions.IN, - "The direction for triangle_count must be " + - "either OUT or IN, but got: %s", direct); - return direct; + Directions dir = parseDirection(direction); + E.checkArgument(dir == Directions.OUT || dir == Directions.IN, + "The value of %s must be either OUT or IN, but got: %s", + KEY_DIRECTION, dir); + return dir; } protected static double alpha(Map<String, Object> parameters) { @@ -153,8 +154,8 @@ public abstract class AbstractAlgorithm implements Algorithm { public static void checkAlpha(double alpha) { E.checkArgument(alpha > 0 && alpha <= 1.0, - "The alpha of must be in range (0, 1], but got %s", - alpha); + "The value of %s must be in range (0, 1], but got %s", + KEY_ALPHA, alpha); } protected static long top(Map<String, Object> parameters) { diff --git a/hugegraph-core/src/main/java/com/baidu/hugegraph/job/algorithm/AlgorithmPool.java b/hugegraph-core/src/main/java/com/baidu/hugegraph/job/algorithm/AlgorithmPool.java index 7a8e4291a..9a8412077 100644 --- a/hugegraph-core/src/main/java/com/baidu/hugegraph/job/algorithm/AlgorithmPool.java +++ b/hugegraph-core/src/main/java/com/baidu/hugegraph/job/algorithm/AlgorithmPool.java @@ -60,6 +60,8 @@ public class AlgorithmPool { INSTANCE.register(new KCoreAlgorithm()); INSTANCE.register(new PageRankAlgorithm()); + + INSTANCE.register(new SubgraphStatAlgorithm()); } private final Map<String, Algorithm> algorithms; diff --git a/hugegraph-core/src/main/java/com/baidu/hugegraph/job/algorithm/SubgraphStatAlgorithm.java b/hugegraph-core/src/main/java/com/baidu/hugegraph/job/algorithm/SubgraphStatAlgorithm.java new file mode 100644 index 000000000..385fbbb5b --- /dev/null +++ b/hugegraph-core/src/main/java/com/baidu/hugegraph/job/algorithm/SubgraphStatAlgorithm.java @@ -0,0 +1,207 @@ +/* + * Copyright 2017 HugeGraph Authors + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with this + * work for additional information regarding copyright ownership. The ASF + * licenses this file to You under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ + +package com.baidu.hugegraph.job.algorithm; + +import java.util.Iterator; +import java.util.Map; + +import org.apache.commons.configuration.PropertiesConfiguration; +import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversalSource; +import org.apache.tinkerpop.gremlin.structure.Vertex; + +import com.baidu.hugegraph.HugeGraph; +import com.baidu.hugegraph.backend.id.Id; +import com.baidu.hugegraph.config.CoreOptions; +import com.baidu.hugegraph.config.HugeConfig; +import com.baidu.hugegraph.job.Job; +import com.baidu.hugegraph.job.algorithm.cent.BetweenessCentralityAlgorithm; +import com.baidu.hugegraph.job.algorithm.cent.ClosenessCentralityAlgorithm; +import com.baidu.hugegraph.job.algorithm.cent.DegreeCentralityAlgorithm; +import com.baidu.hugegraph.job.algorithm.cent.EigenvectorCentralityAlgorithm; +import com.baidu.hugegraph.job.algorithm.comm.ClusterCoeffcientAlgorithm; +import com.baidu.hugegraph.job.algorithm.path.RingsDetectAlgorithm; +import com.baidu.hugegraph.job.algorithm.rank.PageRankAlgorithm; +import com.baidu.hugegraph.task.HugeTask; +import com.baidu.hugegraph.traversal.optimize.HugeScriptTraversal; +import com.baidu.hugegraph.util.E; +import com.baidu.hugegraph.util.InsertionOrderUtil; +import com.google.common.collect.ImmutableMap; + +public class SubgraphStatAlgorithm extends AbstractAlgorithm { + + public static final String KEY_SUBGRAPH = "subgraph"; + public static final String KEY_COPY_SCHEMA = "copy_schema"; + + @Override + public String name() { + return "subgraph_stat"; + } + + @Override + public String category() { + return CATEGORY_AGGR; + } + + @Override + public void checkParameters(Map<String, Object> parameters) { + subgraph(parameters); + } + + @Override + public Object call(Job<Object> job, Map<String, Object> parameters) { + HugeGraph graph = this.createTempGraph(job); + try (Traverser traverser = new Traverser(job)) { + this.initGraph(job.graph(), graph, subgraph(parameters), + copySchema(parameters)); + Job<Object> tmpJob = new TempJob<>(graph, job, job.task()); + return traverser.subgraphStat(tmpJob); + } finally { + graph.truncateBackend(); + // FIXME: task thread can't call close() here (will hang) + graph.closeTx(); + } + } + + private HugeGraph createTempGraph(Job<Object> job) { + Id id = job.task().id(); + PropertiesConfiguration config = new PropertiesConfiguration(); + config.setProperty(CoreOptions.BACKEND.name(), "memory"); + config.setProperty(CoreOptions.STORE.name(), "tmp_" + id); + config.setDelimiterParsingDisabled(true); + return new HugeGraph(new HugeConfig(config)); + } + + @SuppressWarnings("resource") + private void initGraph(HugeGraph parent, HugeGraph graph, + String script, boolean copySchema) { + if (copySchema) { + graph.schema().copyFrom(parent.schema()); + } + new HugeScriptTraversal<>(graph.traversal(), "gremlin-groovy", + script, ImmutableMap.of(), + ImmutableMap.of()).iterate(); + graph.tx().commit(); + } + + protected static String subgraph(Map<String, Object> parameters) { + Object subgraph = parameters.get(KEY_SUBGRAPH); + E.checkArgument(subgraph != null, + "Must pass parameter '%s'", KEY_SUBGRAPH); + E.checkArgument(subgraph instanceof String, + "Invalid parameter '%s', expect a String, but got %s", + KEY_SUBGRAPH, subgraph.getClass().getSimpleName()); + return (String) subgraph; + } + + protected static boolean copySchema(Map<String, Object> parameters) { + if (!parameters.containsKey(KEY_COPY_SCHEMA)) { + return false; + } + return parameterBoolean(parameters, KEY_COPY_SCHEMA); + } + + private static class Traverser extends AlgoTraverser { + + private static Map<String, Object> PARAMS = ImmutableMap.of( + "depth", 10L, + "degree", -1L, + "sample", -1L, + "workers", 0); + + public Traverser(Job<Object> job) { + super(job); + } + + public Object subgraphStat(Job<Object> job) { + Map<String, Object> results = InsertionOrderUtil.newMap(); + + GraphTraversalSource g = job.graph().traversal(); + results.put("vertices_count", g.V().count().next()); + results.put("edges_count", g.E().count().next()); + + Algorithm algo = new DegreeCentralityAlgorithm(); + Map<String, Object> parameters = ImmutableMap.copyOf(PARAMS); + results.put("degrees", algo.call(job, parameters)); + + algo = new BetweenessCentralityAlgorithm(); + results.put("betweeness", algo.call(job, parameters)); + + algo = new EigenvectorCentralityAlgorithm(); + results.put("eigenvectors", algo.call(job, parameters)); + + algo = new ClosenessCentralityAlgorithm(); + results.put("closeness", algo.call(job, parameters)); + + results.put("page_ranks", pageRanks(job)); + + algo = new ClusterCoeffcientAlgorithm(); + results.put("cluster_coeffcient", algo.call(job, parameters)); + + algo = new RingsDetectAlgorithm(); + parameters = ImmutableMap.<String, Object>builder() + .putAll(PARAMS) + .put("count_only", true) + .build(); + results.put("rings", algo.call(job, parameters)); + + return results; + } + + private Map<Object, Double> pageRanks(Job<Object> job) { + PageRankAlgorithm algo = new PageRankAlgorithm(); + algo.call(job, ImmutableMap.of("alpha", 0.15)); + + // Collect page ranks + Map<Object, Double> ranks = InsertionOrderUtil.newMap(); + Iterator<Vertex> vertices = job.graph().vertices(); + while (vertices.hasNext()) { + Vertex vertex = vertices.next(); + ranks.put(vertex.id(), vertex.value(R_RANK)); + } + return ranks; + } + } + + private static class TempJob<V> extends Job<V> { + + private final Job<V> parent; + + public TempJob(HugeGraph graph, Job<V> job, HugeTask<V> task) { + this.scheduler(graph.taskScheduler()); + this.task(task); + this.parent = job; + } + + @Override + public String type() { + return "temp"; + } + + @Override + public V execute() throws Exception { + return null; + } + + @Override + public void updateProgress(int progress) { + this.parent.updateProgress(progress); + } + } +} diff --git a/hugegraph-core/src/main/java/com/baidu/hugegraph/job/algorithm/cent/AbstractCentAlgorithm.java b/hugegraph-core/src/main/java/com/baidu/hugegraph/job/algorithm/cent/AbstractCentAlgorithm.java index fb0c33d50..22372ad09 100644 --- a/hugegraph-core/src/main/java/com/baidu/hugegraph/job/algorithm/cent/AbstractCentAlgorithm.java +++ b/hugegraph-core/src/main/java/com/baidu/hugegraph/job/algorithm/cent/AbstractCentAlgorithm.java @@ -56,7 +56,7 @@ public abstract class AbstractCentAlgorithm extends AbstractAlgorithm { top(parameters); } - public static class Traverser extends AlgoTraverser { + protected static class Traverser extends AlgoTraverser { public Traverser(Job<Object> job) { super(job); diff --git a/hugegraph-core/src/main/java/com/baidu/hugegraph/job/algorithm/cent/BetweenessCentralityAlgorithm.java b/hugegraph-core/src/main/java/com/baidu/hugegraph/job/algorithm/cent/BetweenessCentralityAlgorithm.java index 4f3415a15..370299163 100644 --- a/hugegraph-core/src/main/java/com/baidu/hugegraph/job/algorithm/cent/BetweenessCentralityAlgorithm.java +++ b/hugegraph-core/src/main/java/com/baidu/hugegraph/job/algorithm/cent/BetweenessCentralityAlgorithm.java @@ -71,7 +71,7 @@ public class BetweenessCentralityAlgorithm extends AbstractCentAlgorithm { String sourceCLabel, long topN) { assert depth > 0; - assert degree > 0L; + assert degree > 0L || degree == NO_LIMIT; assert topN >= 0L; GraphTraversal<Vertex, Vertex> t = constructSource(sourceLabel, diff --git a/hugegraph-core/src/main/java/com/baidu/hugegraph/job/algorithm/cent/ClosenessCentralityAlgorithm.java b/hugegraph-core/src/main/java/com/baidu/hugegraph/job/algorithm/cent/ClosenessCentralityAlgorithm.java index 6719eee1e..56d61504a 100644 --- a/hugegraph-core/src/main/java/com/baidu/hugegraph/job/algorithm/cent/ClosenessCentralityAlgorithm.java +++ b/hugegraph-core/src/main/java/com/baidu/hugegraph/job/algorithm/cent/ClosenessCentralityAlgorithm.java @@ -80,7 +80,7 @@ public class ClosenessCentralityAlgorithm extends AbstractCentAlgorithm { String sourceCLabel, long topN) { assert depth > 0; - assert degree > 0L; + assert degree > 0L || degree == NO_LIMIT; assert topN >= 0L; GraphTraversal<Vertex, Vertex> t = constructSource(sourceLabel, diff --git a/hugegraph-core/src/main/java/com/baidu/hugegraph/job/algorithm/cent/EigenvectorCentralityAlgorithm.java b/hugegraph-core/src/main/java/com/baidu/hugegraph/job/algorithm/cent/EigenvectorCentralityAlgorithm.java index 39cec64cd..ec065fa07 100644 --- a/hugegraph-core/src/main/java/com/baidu/hugegraph/job/algorithm/cent/EigenvectorCentralityAlgorithm.java +++ b/hugegraph-core/src/main/java/com/baidu/hugegraph/job/algorithm/cent/EigenvectorCentralityAlgorithm.java @@ -73,7 +73,7 @@ public class EigenvectorCentralityAlgorithm extends AbstractCentAlgorithm { String sourceCLabel, long topN) { assert depth > 0; - assert degree > 0L; + assert degree > 0L || degree == NO_LIMIT; assert topN >= 0L; // TODO: support parameters: Directions dir, String label diff --git a/hugegraph-core/src/main/java/com/baidu/hugegraph/job/algorithm/comm/ClusterCoeffcientAlgorithm.java b/hugegraph-core/src/main/java/com/baidu/hugegraph/job/algorithm/comm/ClusterCoeffcientAlgorithm.java index 0e5760e24..7ac30cd2d 100644 --- a/hugegraph-core/src/main/java/com/baidu/hugegraph/job/algorithm/comm/ClusterCoeffcientAlgorithm.java +++ b/hugegraph-core/src/main/java/com/baidu/hugegraph/job/algorithm/comm/ClusterCoeffcientAlgorithm.java @@ -41,7 +41,7 @@ public class ClusterCoeffcientAlgorithm extends AbstractCommAlgorithm { @Override public Object call(Job<Object> job, Map<String, Object> parameters) { try (Traverser traverser = new Traverser(job)) { - return traverser.clusterCoeffcient(direction(parameters), + return traverser.clusterCoeffcient(directionOutIn(parameters), degree(parameters)); } } diff --git a/hugegraph-core/src/main/java/com/baidu/hugegraph/job/algorithm/comm/KCoreAlgorithm.java b/hugegraph-core/src/main/java/com/baidu/hugegraph/job/algorithm/comm/KCoreAlgorithm.java index 6a721258a..923c1a2a3 100644 --- a/hugegraph-core/src/main/java/com/baidu/hugegraph/job/algorithm/comm/KCoreAlgorithm.java +++ b/hugegraph-core/src/main/java/com/baidu/hugegraph/job/algorithm/comm/KCoreAlgorithm.java @@ -98,7 +98,7 @@ public class KCoreAlgorithm extends AbstractCommAlgorithm { return parameterBoolean(parameters, KEY_MERGED); } - public static class Traverser extends AlgoTraverser { + private static class Traverser extends AlgoTraverser { public Traverser(Job<Object> job, int workers) { super(job, "kcore", workers); diff --git a/hugegraph-core/src/main/java/com/baidu/hugegraph/job/algorithm/comm/LpaAlgorithm.java b/hugegraph-core/src/main/java/com/baidu/hugegraph/job/algorithm/comm/LpaAlgorithm.java index 59c420ae7..e15665cfc 100644 --- a/hugegraph-core/src/main/java/com/baidu/hugegraph/job/algorithm/comm/LpaAlgorithm.java +++ b/hugegraph-core/src/main/java/com/baidu/hugegraph/job/algorithm/comm/LpaAlgorithm.java @@ -80,7 +80,7 @@ public class LpaAlgorithm extends AbstractCommAlgorithm { } } - public static class Traverser extends AlgoTraverser { + private static class Traverser extends AlgoTraverser { private static final long LIMIT = MAX_QUERY_LIMIT; @@ -242,11 +242,10 @@ public class LpaAlgorithm extends AbstractCommAlgorithm { private String labelOfVertex(Id vid) { // TODO: cache with Map<Id, String> - Iterator<Vertex> iter = this.graph().vertices(vid); - if (!iter.hasNext()) { + Vertex vertex = this.vertex(vid); + if (vertex == null) { return null; } - Vertex vertex = iter.next(); return this.labelOfVertex(vertex); } diff --git a/hugegraph-core/src/main/java/com/baidu/hugegraph/job/algorithm/comm/TriangleCountAlgorithm.java b/hugegraph-core/src/main/java/com/baidu/hugegraph/job/algorithm/comm/TriangleCountAlgorithm.java index 6128c6b17..0adb4707c 100644 --- a/hugegraph-core/src/main/java/com/baidu/hugegraph/job/algorithm/comm/TriangleCountAlgorithm.java +++ b/hugegraph-core/src/main/java/com/baidu/hugegraph/job/algorithm/comm/TriangleCountAlgorithm.java @@ -49,7 +49,7 @@ public class TriangleCountAlgorithm extends AbstractCommAlgorithm { @Override public Object call(Job<Object> job, Map<String, Object> parameters) { try (Traverser traverser = new Traverser(job)) { - return traverser.triangleCount(direction(parameters), + return traverser.triangleCount(directionOutIn(parameters), degree(parameters)); } } diff --git a/hugegraph-core/src/main/java/com/baidu/hugegraph/job/algorithm/path/RingsDetectAlgorithm.java b/hugegraph-core/src/main/java/com/baidu/hugegraph/job/algorithm/path/RingsDetectAlgorithm.java index c7c0c677a..3d5bd163e 100644 --- a/hugegraph-core/src/main/java/com/baidu/hugegraph/job/algorithm/path/RingsDetectAlgorithm.java +++ b/hugegraph-core/src/main/java/com/baidu/hugegraph/job/algorithm/path/RingsDetectAlgorithm.java @@ -80,7 +80,7 @@ public class RingsDetectAlgorithm extends AbstractAlgorithm { return parameterBoolean(parameters, KEY_COUNT_ONLY); } - public static class Traverser extends AlgoTraverser { + private static class Traverser extends AlgoTraverser { public Traverser(Job<Object> job, int workers) { super(job, "ring", workers); diff --git a/hugegraph-core/src/main/java/com/baidu/hugegraph/job/algorithm/rank/PageRankAlgorithm.java b/hugegraph-core/src/main/java/com/baidu/hugegraph/job/algorithm/rank/PageRankAlgorithm.java index 2773a9db0..9f51bf7b6 100644 --- a/hugegraph-core/src/main/java/com/baidu/hugegraph/job/algorithm/rank/PageRankAlgorithm.java +++ b/hugegraph-core/src/main/java/com/baidu/hugegraph/job/algorithm/rank/PageRankAlgorithm.java @@ -65,8 +65,7 @@ public class PageRankAlgorithm extends AbstractCommAlgorithm { @Override public Object call(Job<Object> job, Map<String, Object> parameters) { - Traverser traverser = new Traverser(job); - try { + try (Traverser traverser = new Traverser(job)) { return traverser.pageRank(alpha(parameters), times(parameters), precision(parameters), @@ -78,11 +77,13 @@ public class PageRankAlgorithm extends AbstractCommAlgorithm { } } - protected static class Traverser extends AlgoTraverser { + private static class Traverser extends AlgoTraverser { - // DoublePair.left is rank computed by previous step, DoublePair.right - // is rank computed by current step. - private Map<Id, DoublePair> vertexRankMap; + /* + * DoublePair.left is rank computed by previous step, + * DoublePair.right is rank computed by current step. + */ + private final Map<Id, DoublePair> vertexRankMap; public Traverser(Job<Object> job) { super(job); @@ -100,7 +101,7 @@ public class PageRankAlgorithm extends AbstractCommAlgorithm { double changedRank = 0.0; long numOfVertices = this.initRankMap(); - for (times = 0; times <= maxTimes; times++) { + for (times = 0; times < maxTimes; times++) { Id currentSourceVertexId = null; // the edges are ordered by ownerVertex Iterator<Edge> edges = this.edges(direction); @@ -134,15 +135,16 @@ public class PageRankAlgorithm extends AbstractCommAlgorithm { double sumRank = this.computeRank(alpha, numOfVertices); double compensatedRank = 1.0 - sumRank; - changedRank = - this.compensateRank(compensatedRank / numOfVertices); + changedRank = this.compensateRank(compensatedRank / + numOfVertices); LOG.debug("PageRank execution times:{}, changedRank:{} ", times, changedRank); if (changedRank < precision) { break; } } - this.writeBackRankValue(); + + this.writeBackRankValues(); return ImmutableMap.of("alpha", alpha, "iteration_times", times, @@ -212,14 +214,12 @@ public class PageRankAlgorithm extends AbstractCommAlgorithm { } } - private void writeBackRankValue() { - for (Map.Entry<Id, DoublePair> entry : - this.vertexRankMap.entrySet()) { - Id vertexId = entry.getKey(); - Iterator<Vertex> vertices = this.graph().vertices(vertexId); - if (vertices.hasNext()) { - Vertex vertex = vertices.next(); - vertex.property(R_RANK, entry.getValue().left()); + private void writeBackRankValues() { + for (Map.Entry<Id, DoublePair> e : this.vertexRankMap.entrySet()) { + Id vertexId = e.getKey(); + Vertex vertex = this.vertex(vertexId); + if (vertex != null) { + vertex.property(R_RANK, e.getValue().left()); this.commitIfNeeded(); } } @@ -258,7 +258,7 @@ public class PageRankAlgorithm extends AbstractCommAlgorithm { } public double left() { - return left; + return this.left; } public void left(double value) { @@ -266,17 +266,18 @@ public class PageRankAlgorithm extends AbstractCommAlgorithm { } public double right() { - return right; + return this.right; } public void right(double value) { this.right = value; } + @Override public String toString() { StringBuilder sb = new StringBuilder(); - sb.append("left:").append(left) - .append(", right: ").append(right); + sb.append("left:").append(this.left) + .append(", right: ").append(this.right); return sb.toString(); } @@ -286,12 +287,12 @@ public class PageRankAlgorithm extends AbstractCommAlgorithm { return false; } DoublePair other = (DoublePair) obj; - return this.left == other.left && right == other.right; + return this.left == other.left && this.right == other.right; } @Override public int hashCode() { - return Double.hashCode(left) ^ Double.hashCode(right); + return Double.hashCode(this.left) ^ Double.hashCode(this.right); } } } diff --git a/hugegraph-core/src/main/java/com/baidu/hugegraph/job/algorithm/similarity/FusiformSimilarityAlgorithm.java b/hugegraph-core/src/main/java/com/baidu/hugegraph/job/algorithm/similarity/FusiformSimilarityAlgorithm.java index 673430623..82294f48b 100644 --- a/hugegraph-core/src/main/java/com/baidu/hugegraph/job/algorithm/similarity/FusiformSimilarityAlgorithm.java +++ b/hugegraph-core/src/main/java/com/baidu/hugegraph/job/algorithm/similarity/FusiformSimilarityAlgorithm.java @@ -136,7 +136,7 @@ public class FusiformSimilarityAlgorithm extends AbstractAlgorithm { return limit; } - protected static class Traverser extends AlgoTraverser { + private static class Traverser extends AlgoTraverser { public Traverser(Job<Object> job, int workers) { super(job, "fusiform", workers);
