diff --git a/hugegraph-api/pom.xml b/hugegraph-api/pom.xml
index 0ef7194e7e..2da1f4dea8 100644
--- a/hugegraph-api/pom.xml
+++ b/hugegraph-api/pom.xml
@@ -101,7 +101,7 @@
- 0.32.0.0
+ 0.33.0.0
diff --git a/hugegraph-api/src/main/java/com/baidu/hugegraph/api/traversers/CrosspointsAPI.java b/hugegraph-api/src/main/java/com/baidu/hugegraph/api/traversers/CrosspointsAPI.java
index 4cec79b3fd..8d02cae284 100644
--- a/hugegraph-api/src/main/java/com/baidu/hugegraph/api/traversers/CrosspointsAPI.java
+++ b/hugegraph-api/src/main/java/com/baidu/hugegraph/api/traversers/CrosspointsAPI.java
@@ -39,11 +39,16 @@
import com.baidu.hugegraph.backend.id.Id;
import com.baidu.hugegraph.core.GraphManager;
import com.baidu.hugegraph.server.RestServer;
-import com.baidu.hugegraph.traversal.optimize.HugeTraverser;
+import com.baidu.hugegraph.traversal.algorithm.HugeTraverser;
+import com.baidu.hugegraph.traversal.algorithm.PathsTraverser;
import com.baidu.hugegraph.type.define.Directions;
import com.baidu.hugegraph.util.Log;
import com.codahale.metrics.annotation.Timed;
+import static com.baidu.hugegraph.traversal.algorithm.HugeTraverser.DEFAULT_CAPACITY;
+import static com.baidu.hugegraph.traversal.algorithm.HugeTraverser.DEFAULT_DEGREE;
+import static com.baidu.hugegraph.traversal.algorithm.HugeTraverser.DEFAULT_PATHS_LIMIT;
+
@Path("graphs/{graph}/traversers/crosspoints")
@Singleton
public class CrosspointsAPI extends API {
@@ -60,9 +65,12 @@ public String get(@Context GraphManager manager,
@QueryParam("direction") String direction,
@QueryParam("label") String edgeLabel,
@QueryParam("max_depth") int depth,
- @QueryParam("max_degree") @DefaultValue("-1") long degree,
- @QueryParam("capacity") @DefaultValue("-1") long capacity,
- @QueryParam("limit") @DefaultValue("10") long limit) {
+ @QueryParam("max_degree")
+ @DefaultValue(DEFAULT_DEGREE) long degree,
+ @QueryParam("capacity")
+ @DefaultValue(DEFAULT_CAPACITY) long capacity,
+ @QueryParam("limit")
+ @DefaultValue(DEFAULT_PATHS_LIMIT) long limit) {
LOG.debug("Graph [{}] get crosspoints with paths from '{}', to '{}' " +
"with direction '{}', edge label '{}', max depth '{}', " +
"max degree '{}', capacity '{}' and limit '{}'",
@@ -74,7 +82,7 @@ public String get(@Context GraphManager manager,
Directions dir = Directions.convert(EdgeAPI.parseDirection(direction));
HugeGraph g = graph(manager, graph);
- HugeTraverser traverser = new HugeTraverser(g);
+ PathsTraverser traverser = new PathsTraverser(g);
Set paths = traverser.paths(sourceId, dir,
targetId, dir,
edgeLabel, depth,
diff --git a/hugegraph-api/src/main/java/com/baidu/hugegraph/api/traversers/CustomizedCrosspointsAPI.java b/hugegraph-api/src/main/java/com/baidu/hugegraph/api/traversers/CustomizedCrosspointsAPI.java
new file mode 100644
index 0000000000..df14df0c33
--- /dev/null
+++ b/hugegraph-api/src/main/java/com/baidu/hugegraph/api/traversers/CustomizedCrosspointsAPI.java
@@ -0,0 +1,201 @@
+/*
+ * 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.api.traversers;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import javax.inject.Singleton;
+import javax.ws.rs.Consumes;
+import javax.ws.rs.POST;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.Context;
+
+import org.apache.tinkerpop.gremlin.structure.Vertex;
+import org.slf4j.Logger;
+
+import com.baidu.hugegraph.HugeGraph;
+import com.baidu.hugegraph.api.API;
+import com.baidu.hugegraph.api.filter.StatusFilter.Status;
+import com.baidu.hugegraph.backend.id.Id;
+import com.baidu.hugegraph.core.GraphManager;
+import com.baidu.hugegraph.schema.EdgeLabel;
+import com.baidu.hugegraph.server.RestServer;
+import com.baidu.hugegraph.structure.HugeVertex;
+import com.baidu.hugegraph.traversal.algorithm.CustomizedCrosspointsTraverser;
+import com.baidu.hugegraph.traversal.algorithm.HugeTraverser;
+import com.baidu.hugegraph.type.define.Directions;
+import com.baidu.hugegraph.util.E;
+import com.baidu.hugegraph.util.Log;
+import com.codahale.metrics.annotation.Timed;
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+import static com.baidu.hugegraph.traversal.algorithm.HugeTraverser.*;
+
+@Path("graphs/{graph}/traversers/customizedcrosspoints")
+@Singleton
+public class CustomizedCrosspointsAPI extends API {
+
+ private static final Logger LOG = Log.logger(RestServer.class);
+
+ @POST
+ @Timed
+ @Status(Status.CREATED)
+ @Consumes(APPLICATION_JSON)
+ @Produces(APPLICATION_JSON_WITH_CHARSET)
+ public String post(@Context GraphManager manager,
+ @PathParam("graph") String graph,
+ CrosspointsRequest request) {
+ E.checkArgumentNotNull(request,
+ "The crosspoints request body can't be null");
+ E.checkArgumentNotNull(request.sources,
+ "The sources of crosspoints request " +
+ "can't be null");
+ E.checkArgument(request.pathPatterns != null &&
+ !request.pathPatterns.isEmpty(),
+ "The steps of crosspoints request can't be empty");
+
+ LOG.debug("Graph [{}] get customized crosspoints from source vertex " +
+ "'{}', with path_pattern '{}', with_path '{}', with_vertex " +
+ "'{}', capacity '{}' and limit '{}'", graph, request.sources,
+ request.pathPatterns, request.withPath, request.withVertex,
+ request.capacity, request.limit);
+
+ HugeGraph g = graph(manager, graph);
+ List sources = request.sources.sourcesVertices(g);
+ List patterns;
+ patterns = pathPatterns(g, request);
+
+ CustomizedCrosspointsTraverser traverser =
+ new CustomizedCrosspointsTraverser(g);
+ CustomizedCrosspointsTraverser.CrosspointsPaths paths;
+ paths = traverser.crosspointsPaths(sources, patterns, request.capacity,
+ request.limit);
+ Iterator iter = Collections.emptyIterator();
+ if (!request.withVertex) {
+ return manager.serializer(g).writeCrosspoints(paths, iter,
+ request.withPath);
+ }
+ Set ids = new HashSet<>();
+ if (request.withPath) {
+ for (HugeTraverser.Path p : paths.paths()) {
+ ids.addAll(p.vertices());
+ }
+ } else {
+ ids = paths.crosspoints();
+ }
+ if (!ids.isEmpty()) {
+ iter = g.vertices(ids.toArray());
+ }
+ return manager.serializer(g).writeCrosspoints(paths, iter,
+ request.withPath);
+ }
+
+ private static List
+ pathPatterns(HugeGraph graph, CrosspointsRequest request) {
+ int stepSize = request.pathPatterns.size();
+ List pathPatterns;
+ pathPatterns = new ArrayList<>(stepSize);
+ for (PathPattern pattern : request.pathPatterns) {
+ CustomizedCrosspointsTraverser.PathPattern pathPattern;
+ pathPattern = new CustomizedCrosspointsTraverser.PathPattern();
+ for (Step step : pattern.steps) {
+ pathPattern.add(step.jsonToStep(graph));
+ }
+ pathPatterns.add(pathPattern);
+ }
+ return pathPatterns;
+ }
+
+ private static class CrosspointsRequest {
+
+ @JsonProperty("sources")
+ public SourceVertices sources;
+ @JsonProperty("path_patterns")
+ public List pathPatterns;
+ @JsonProperty("capacity")
+ public long capacity = Long.valueOf(DEFAULT_CAPACITY);
+ @JsonProperty("limit")
+ public long limit = Long.valueOf(DEFAULT_PATHS_LIMIT);
+ @JsonProperty("with_path")
+ public boolean withPath = false;
+ @JsonProperty("with_vertex")
+ public boolean withVertex = false;
+
+ @Override
+ public String toString() {
+ return String.format("pathRequest{sourceVertex=%s,pathPatterns=%s" +
+ ",withPath=%s,withVertex=%s,capacity=%s," +
+ "limit=%s}", this.sources, this.pathPatterns,
+ this.withPath, this.withVertex, this.capacity,
+ this.limit);
+ }
+ }
+
+ private static class PathPattern {
+
+ @JsonProperty("steps")
+ public List steps;
+ }
+
+ private static class Step {
+
+ @JsonProperty("direction")
+ public Directions direction;
+ @JsonProperty("labels")
+ public List labels;
+ @JsonProperty("properties")
+ public Map properties;
+ @JsonProperty("degree")
+ public long degree = Long.valueOf(DEFAULT_DEGREE);
+
+ @Override
+ public String toString() {
+ return String.format("step:{direction=%s,labels=%s,properties=%s," +
+ "degree=%s}", this.direction, this.labels,
+ this.properties, this.degree);
+ }
+
+ private CustomizedCrosspointsTraverser.Step jsonToStep(HugeGraph g) {
+ E.checkArgument(this.degree > 0 || this.degree == NO_LIMIT,
+ "The degree must be > 0 or == -1, but got: %s",
+ this.degree);
+ Map labelIds = new HashMap<>();
+ if (this.labels != null) {
+ for (String label : this.labels) {
+ EdgeLabel el = g.edgeLabel(label);
+ labelIds.put(el.id(), label);
+ }
+ }
+ return new CustomizedCrosspointsTraverser.Step(this.direction,
+ labelIds,
+ this.properties,
+ this.degree);
+ }
+ }
+}
diff --git a/hugegraph-api/src/main/java/com/baidu/hugegraph/api/traversers/CustomizedPathsAPI.java b/hugegraph-api/src/main/java/com/baidu/hugegraph/api/traversers/CustomizedPathsAPI.java
new file mode 100644
index 0000000000..74b49ad771
--- /dev/null
+++ b/hugegraph-api/src/main/java/com/baidu/hugegraph/api/traversers/CustomizedPathsAPI.java
@@ -0,0 +1,215 @@
+/*
+ * 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.api.traversers;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import javax.inject.Singleton;
+import javax.ws.rs.Consumes;
+import javax.ws.rs.POST;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.Context;
+
+import org.apache.tinkerpop.gremlin.structure.Vertex;
+import org.slf4j.Logger;
+
+import com.baidu.hugegraph.HugeGraph;
+import com.baidu.hugegraph.api.API;
+import com.baidu.hugegraph.api.filter.StatusFilter.Status;
+import com.baidu.hugegraph.backend.id.Id;
+import com.baidu.hugegraph.core.GraphManager;
+import com.baidu.hugegraph.schema.EdgeLabel;
+import com.baidu.hugegraph.schema.PropertyKey;
+import com.baidu.hugegraph.server.RestServer;
+import com.baidu.hugegraph.structure.HugeVertex;
+import com.baidu.hugegraph.traversal.algorithm.CustomizePathsTraverser;
+import com.baidu.hugegraph.traversal.algorithm.HugeTraverser;
+import com.baidu.hugegraph.type.define.Directions;
+import com.baidu.hugegraph.util.E;
+import com.baidu.hugegraph.util.Log;
+import com.codahale.metrics.annotation.Timed;
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+import static com.baidu.hugegraph.traversal.algorithm.HugeTraverser.*;
+
+@Path("graphs/{graph}/traversers/customizedpaths")
+@Singleton
+public class CustomizedPathsAPI extends API {
+
+ private static final Logger LOG = Log.logger(RestServer.class);
+
+ @POST
+ @Timed
+ @Status(Status.CREATED)
+ @Consumes(APPLICATION_JSON)
+ @Produces(APPLICATION_JSON_WITH_CHARSET)
+ public String post(@Context GraphManager manager,
+ @PathParam("graph") String graph,
+ PathRequest request) {
+ E.checkArgumentNotNull(request, "The path request body can't be null");
+ E.checkArgumentNotNull(request.sources,
+ "The sources of path request can't be null");
+ E.checkArgument(request.steps != null && !request.steps.isEmpty(),
+ "The steps of path request can't be empty");
+ if (request.sortBy == null) {
+ request.sortBy = SortBy.NONE;
+ }
+
+ LOG.debug("Graph [{}] get customized paths from source vertex '{}', " +
+ "with steps '{}', sort by '{}', capacity '{}', limit '{}' " +
+ "and with_vertex '{}'", graph, request.sources, request.steps,
+ request.sortBy, request.capacity, request.limit,
+ request.withVertex);
+
+ HugeGraph g = graph(manager, graph);
+ List sources = request.sources.sourcesVertices(g);
+ List steps = step(g, request);
+ boolean sorted = request.sortBy != SortBy.NONE;
+
+ CustomizePathsTraverser traverser = new CustomizePathsTraverser(g);
+ List paths;
+ paths = traverser.customizedPaths(sources, steps, sorted,
+ request.capacity, request.limit);
+
+ if (sorted) {
+ boolean incr = request.sortBy == SortBy.INCR;
+ paths = CustomizePathsTraverser.topNPath(paths, incr,
+ request.limit);
+ }
+
+ if (!request.withVertex) {
+ return manager.serializer(g).writePaths("paths", paths, false);
+ }
+
+ Set ids = new HashSet<>();
+ for (HugeTraverser.Path p : paths) {
+ ids.addAll(p.vertices());
+ }
+ Iterator iter = Collections.emptyIterator();
+ if (!ids.isEmpty()) {
+ iter = g.vertices(ids.toArray());
+ }
+ return manager.serializer(g).writePaths("paths", paths, false, iter);
+ }
+
+ private static List step(HugeGraph graph,
+ PathRequest req) {
+ int stepSize = req.steps.size();
+ List steps = new ArrayList<>(stepSize);
+ for (Step step : req.steps) {
+ steps.add(step.jsonToStep(graph));
+ }
+ return steps;
+ }
+
+ private static class PathRequest {
+
+ @JsonProperty("sources")
+ public SourceVertices sources;
+ @JsonProperty("steps")
+ public List steps;
+ @JsonProperty("sort_by")
+ public SortBy sortBy;
+ @JsonProperty("capacity")
+ public long capacity = Long.valueOf(DEFAULT_CAPACITY);
+ @JsonProperty("limit")
+ public long limit = Long.valueOf(DEFAULT_PATHS_LIMIT);
+ @JsonProperty("with_vertex")
+ public boolean withVertex = false;
+
+ @Override
+ public String toString() {
+ return String.format("pathRequest{sourceVertex=%s,steps=%s," +
+ "sortBy=%s,capacity=%s,limit=%s," +
+ "withVertex=%s}", this.sources, this.steps,
+ this.sortBy, this.capacity, this.limit,
+ this.withVertex);
+ }
+ }
+
+ private static class Step {
+
+ @JsonProperty("direction")
+ public Directions direction;
+ @JsonProperty("labels")
+ public List labels;
+ @JsonProperty("properties")
+ public Map properties;
+ @JsonProperty("weight_by")
+ public String weightBy;
+ @JsonProperty("default_weight")
+ public double defaultWeight = Double.valueOf(DEFAULT_WEIGHT);
+ @JsonProperty("degree")
+ public long degree = Long.valueOf(DEFAULT_DEGREE);
+ @JsonProperty("sample")
+ public long sample = Long.valueOf(DEFAULT_SAMPLE);
+
+ @Override
+ public String toString() {
+ return String.format("step:{direction=%s,labels=%s,properties=%s," +
+ "weightBy=%s,defaultWeight=%s,degree=%s," +
+ "sample=%s}", this.direction, this.labels,
+ this.properties, this.weightBy,
+ this.defaultWeight, this.degree, this.sample);
+ }
+
+ private CustomizePathsTraverser.Step jsonToStep(HugeGraph graph) {
+ E.checkArgument(this.degree > 0 || this.degree == NO_LIMIT,
+ "The degree must be > 0 or == -1, but got: %s",
+ this.degree);
+ E.checkArgument(this.sample > 0 || this.sample == NO_LIMIT,
+ "The sample must be > 0, but got: %s",
+ this.sample);
+ E.checkArgument(this.degree == NO_LIMIT || this.degree >= sample,
+ "Degree must be greater than or equal to sample," +
+ " but got degree %s and sample %s", degree, sample);
+ Map labelIds = new HashMap<>();
+ if (this.labels != null) {
+ for (String label : this.labels) {
+ EdgeLabel el = graph.edgeLabel(label);
+ labelIds.put(el.id(), label);
+ }
+ }
+ PropertyKey weightBy = null;
+ if (this.weightBy != null) {
+ weightBy = graph.propertyKey(this.weightBy);
+ }
+ return new CustomizePathsTraverser.Step(this.direction, labelIds,
+ this.properties, weightBy,
+ this.defaultWeight,
+ this.degree, this.sample);
+ }
+ }
+
+ private enum SortBy {
+ INCR,
+ DECR,
+ NONE
+ }
+}
diff --git a/hugegraph-api/src/main/java/com/baidu/hugegraph/api/traversers/KneighborAPI.java b/hugegraph-api/src/main/java/com/baidu/hugegraph/api/traversers/KneighborAPI.java
index 273cdd86f7..b4e1d9fcb0 100644
--- a/hugegraph-api/src/main/java/com/baidu/hugegraph/api/traversers/KneighborAPI.java
+++ b/hugegraph-api/src/main/java/com/baidu/hugegraph/api/traversers/KneighborAPI.java
@@ -39,11 +39,14 @@
import com.baidu.hugegraph.backend.id.Id;
import com.baidu.hugegraph.core.GraphManager;
import com.baidu.hugegraph.server.RestServer;
-import com.baidu.hugegraph.traversal.optimize.HugeTraverser;
+import com.baidu.hugegraph.traversal.algorithm.HugeTraverser;
import com.baidu.hugegraph.type.define.Directions;
import com.baidu.hugegraph.util.Log;
import com.codahale.metrics.annotation.Timed;
+import static com.baidu.hugegraph.traversal.algorithm.HugeTraverser.DEFAULT_DEGREE;
+import static com.baidu.hugegraph.traversal.algorithm.HugeTraverser.DEFAULT_ELEMENTS_LIMIT;
+
@Path("graphs/{graph}/traversers/kneighbor")
@Singleton
public class KneighborAPI extends API {
@@ -59,8 +62,10 @@ public String get(@Context GraphManager manager,
@QueryParam("direction") String direction,
@QueryParam("label") String edgeLabel,
@QueryParam("max_depth") int depth,
- @QueryParam("max_degree") @DefaultValue("-1") long degree,
- @QueryParam("limit") @DefaultValue("-1") long limit) {
+ @QueryParam("max_degree")
+ @DefaultValue(DEFAULT_DEGREE) long degree,
+ @QueryParam("limit")
+ @DefaultValue(DEFAULT_ELEMENTS_LIMIT) long limit) {
LOG.debug("Graph [{}] get k-neighbor from '{}' with " +
"direction '{}', edge label '{}', max depth '{}', " +
"max degree '{}' and limit '{}'",
diff --git a/hugegraph-api/src/main/java/com/baidu/hugegraph/api/traversers/KoutAPI.java b/hugegraph-api/src/main/java/com/baidu/hugegraph/api/traversers/KoutAPI.java
index 6fc5e7d6f0..4825637778 100644
--- a/hugegraph-api/src/main/java/com/baidu/hugegraph/api/traversers/KoutAPI.java
+++ b/hugegraph-api/src/main/java/com/baidu/hugegraph/api/traversers/KoutAPI.java
@@ -39,11 +39,15 @@
import com.baidu.hugegraph.backend.id.Id;
import com.baidu.hugegraph.core.GraphManager;
import com.baidu.hugegraph.server.RestServer;
-import com.baidu.hugegraph.traversal.optimize.HugeTraverser;
+import com.baidu.hugegraph.traversal.algorithm.HugeTraverser;
import com.baidu.hugegraph.type.define.Directions;
import com.baidu.hugegraph.util.Log;
import com.codahale.metrics.annotation.Timed;
+import static com.baidu.hugegraph.traversal.algorithm.HugeTraverser.DEFAULT_CAPACITY;
+import static com.baidu.hugegraph.traversal.algorithm.HugeTraverser.DEFAULT_DEGREE;
+import static com.baidu.hugegraph.traversal.algorithm.HugeTraverser.DEFAULT_ELEMENTS_LIMIT;
+
@Path("graphs/{graph}/traversers/kout")
@Singleton
public class KoutAPI extends API {
@@ -61,9 +65,12 @@ public String get(@Context GraphManager manager,
@QueryParam("max_depth") int depth,
@QueryParam("nearest")
@DefaultValue("true") boolean nearest,
- @QueryParam("max_degree") @DefaultValue("-1") long degree,
- @QueryParam("capacity") @DefaultValue("-1") long capacity,
- @QueryParam("limit") @DefaultValue("-1") long limit) {
+ @QueryParam("max_degree")
+ @DefaultValue(DEFAULT_DEGREE) long degree,
+ @QueryParam("capacity")
+ @DefaultValue(DEFAULT_CAPACITY) long capacity,
+ @QueryParam("limit")
+ @DefaultValue(DEFAULT_ELEMENTS_LIMIT) long limit) {
LOG.debug("Graph [{}] get k-out from '{}' with " +
"direction '{}', edge label '{}', max depth '{}', nearest " +
"'{}', max degree '{}', capacity '{}' and limit '{}'",
diff --git a/hugegraph-api/src/main/java/com/baidu/hugegraph/api/traversers/PathsAPI.java b/hugegraph-api/src/main/java/com/baidu/hugegraph/api/traversers/PathsAPI.java
index 823d03c93f..7da795edc2 100644
--- a/hugegraph-api/src/main/java/com/baidu/hugegraph/api/traversers/PathsAPI.java
+++ b/hugegraph-api/src/main/java/com/baidu/hugegraph/api/traversers/PathsAPI.java
@@ -39,11 +39,16 @@
import com.baidu.hugegraph.backend.id.Id;
import com.baidu.hugegraph.core.GraphManager;
import com.baidu.hugegraph.server.RestServer;
-import com.baidu.hugegraph.traversal.optimize.HugeTraverser;
+import com.baidu.hugegraph.traversal.algorithm.HugeTraverser;
+import com.baidu.hugegraph.traversal.algorithm.PathsTraverser;
import com.baidu.hugegraph.type.define.Directions;
import com.baidu.hugegraph.util.Log;
import com.codahale.metrics.annotation.Timed;
+import static com.baidu.hugegraph.traversal.algorithm.HugeTraverser.DEFAULT_CAPACITY;
+import static com.baidu.hugegraph.traversal.algorithm.HugeTraverser.DEFAULT_DEGREE;
+import static com.baidu.hugegraph.traversal.algorithm.HugeTraverser.DEFAULT_PATHS_LIMIT;
+
@Path("graphs/{graph}/traversers/paths")
@Singleton
public class PathsAPI extends API {
@@ -60,9 +65,12 @@ public String get(@Context GraphManager manager,
@QueryParam("direction") String direction,
@QueryParam("label") String edgeLabel,
@QueryParam("max_depth") int depth,
- @QueryParam("max_degree") @DefaultValue("-1") long degree,
- @QueryParam("capacity") @DefaultValue("-1") long capacity,
- @QueryParam("limit") @DefaultValue("10") long limit) {
+ @QueryParam("max_degree")
+ @DefaultValue(DEFAULT_DEGREE) long degree,
+ @QueryParam("capacity")
+ @DefaultValue(DEFAULT_CAPACITY) long capacity,
+ @QueryParam("limit")
+ @DefaultValue(DEFAULT_PATHS_LIMIT) long limit) {
LOG.debug("Graph [{}] get paths from '{}', to '{}' with " +
"direction {}, edge label {}, max depth '{}', " +
"max degree '{}', capacity '{}' and limit '{}'",
@@ -74,7 +82,7 @@ public String get(@Context GraphManager manager,
Directions dir = Directions.convert(EdgeAPI.parseDirection(direction));
HugeGraph g = graph(manager, graph);
- HugeTraverser traverser = new HugeTraverser(g);
+ PathsTraverser traverser = new PathsTraverser(g);
Set paths;
paths = traverser.paths(sourceId, dir, targetId, dir.opposite(),
edgeLabel, depth, degree, capacity, limit);
diff --git a/hugegraph-api/src/main/java/com/baidu/hugegraph/api/traversers/Rays.java b/hugegraph-api/src/main/java/com/baidu/hugegraph/api/traversers/RaysAPI.java
similarity index 77%
rename from hugegraph-api/src/main/java/com/baidu/hugegraph/api/traversers/Rays.java
rename to hugegraph-api/src/main/java/com/baidu/hugegraph/api/traversers/RaysAPI.java
index 059f2d54c5..edeccbe34e 100644
--- a/hugegraph-api/src/main/java/com/baidu/hugegraph/api/traversers/Rays.java
+++ b/hugegraph-api/src/main/java/com/baidu/hugegraph/api/traversers/RaysAPI.java
@@ -39,14 +39,19 @@
import com.baidu.hugegraph.backend.id.Id;
import com.baidu.hugegraph.core.GraphManager;
import com.baidu.hugegraph.server.RestServer;
-import com.baidu.hugegraph.traversal.optimize.HugeTraverser;
+import com.baidu.hugegraph.traversal.algorithm.HugeTraverser;
+import com.baidu.hugegraph.traversal.algorithm.SubGraphTraverser;
import com.baidu.hugegraph.type.define.Directions;
import com.baidu.hugegraph.util.Log;
import com.codahale.metrics.annotation.Timed;
+import static com.baidu.hugegraph.traversal.algorithm.HugeTraverser.DEFAULT_CAPACITY;
+import static com.baidu.hugegraph.traversal.algorithm.HugeTraverser.DEFAULT_DEGREE;
+import static com.baidu.hugegraph.traversal.algorithm.HugeTraverser.DEFAULT_PATHS_LIMIT;
+
@Path("graphs/{graph}/traversers/rays")
@Singleton
-public class Rays extends API {
+public class RaysAPI extends API {
private static final Logger LOG = Log.logger(RestServer.class);
@@ -59,9 +64,12 @@ public String get(@Context GraphManager manager,
@QueryParam("direction") String direction,
@QueryParam("label") String edgeLabel,
@QueryParam("max_depth") int depth,
- @QueryParam("max_degree") @DefaultValue("-1") long degree,
- @QueryParam("capacity") @DefaultValue("-1") long capacity,
- @QueryParam("limit") @DefaultValue("-1") long limit) {
+ @QueryParam("max_degree")
+ @DefaultValue(DEFAULT_DEGREE) long degree,
+ @QueryParam("capacity")
+ @DefaultValue(DEFAULT_CAPACITY) long capacity,
+ @QueryParam("limit")
+ @DefaultValue(DEFAULT_PATHS_LIMIT) long limit) {
LOG.debug("Graph [{}] get rays paths from '{}' with " +
"direction '{}', edge label '{}', max depth '{}', " +
"max degree '{}' and limit '{}'",
@@ -72,7 +80,7 @@ public String get(@Context GraphManager manager,
HugeGraph g = graph(manager, graph);
- HugeTraverser traverser = new HugeTraverser(g);
+ SubGraphTraverser traverser = new SubGraphTraverser(g);
List paths = traverser.rays(source, dir, edgeLabel,
depth, degree, capacity,
limit);
diff --git a/hugegraph-api/src/main/java/com/baidu/hugegraph/api/traversers/Rings.java b/hugegraph-api/src/main/java/com/baidu/hugegraph/api/traversers/RingsAPI.java
similarity index 77%
rename from hugegraph-api/src/main/java/com/baidu/hugegraph/api/traversers/Rings.java
rename to hugegraph-api/src/main/java/com/baidu/hugegraph/api/traversers/RingsAPI.java
index 7e1f4444c0..3921f3b4e1 100644
--- a/hugegraph-api/src/main/java/com/baidu/hugegraph/api/traversers/Rings.java
+++ b/hugegraph-api/src/main/java/com/baidu/hugegraph/api/traversers/RingsAPI.java
@@ -39,14 +39,19 @@
import com.baidu.hugegraph.backend.id.Id;
import com.baidu.hugegraph.core.GraphManager;
import com.baidu.hugegraph.server.RestServer;
-import com.baidu.hugegraph.traversal.optimize.HugeTraverser;
+import com.baidu.hugegraph.traversal.algorithm.HugeTraverser;
+import com.baidu.hugegraph.traversal.algorithm.SubGraphTraverser;
import com.baidu.hugegraph.type.define.Directions;
import com.baidu.hugegraph.util.Log;
import com.codahale.metrics.annotation.Timed;
+import static com.baidu.hugegraph.traversal.algorithm.HugeTraverser.DEFAULT_CAPACITY;
+import static com.baidu.hugegraph.traversal.algorithm.HugeTraverser.DEFAULT_DEGREE;
+import static com.baidu.hugegraph.traversal.algorithm.HugeTraverser.DEFAULT_PATHS_LIMIT;
+
@Path("graphs/{graph}/traversers/rings")
@Singleton
-public class Rings extends API {
+public class RingsAPI extends API {
private static final Logger LOG = Log.logger(RestServer.class);
@@ -59,9 +64,12 @@ public String get(@Context GraphManager manager,
@QueryParam("direction") String direction,
@QueryParam("label") String edgeLabel,
@QueryParam("max_depth") int depth,
- @QueryParam("max_degree") @DefaultValue("-1") long degree,
- @QueryParam("capacity") @DefaultValue("-1") long capacity,
- @QueryParam("limit") @DefaultValue("-1") long limit) {
+ @QueryParam("max_degree")
+ @DefaultValue(DEFAULT_DEGREE) long degree,
+ @QueryParam("capacity")
+ @DefaultValue(DEFAULT_CAPACITY) long capacity,
+ @QueryParam("limit")
+ @DefaultValue(DEFAULT_PATHS_LIMIT) long limit) {
LOG.debug("Graph [{}] get rings paths reachable from '{}' with " +
"direction '{}', edge label '{}', max depth '{}', " +
"max degree '{}' and limit '{}'",
@@ -72,7 +80,7 @@ public String get(@Context GraphManager manager,
HugeGraph g = graph(manager, graph);
- HugeTraverser traverser = new HugeTraverser(g);
+ SubGraphTraverser traverser = new SubGraphTraverser(g);
List paths = traverser.rings(source, dir, edgeLabel,
depth, degree,
capacity, limit);
diff --git a/hugegraph-api/src/main/java/com/baidu/hugegraph/api/traversers/ShortestPathAPI.java b/hugegraph-api/src/main/java/com/baidu/hugegraph/api/traversers/ShortestPathAPI.java
index 13e6687c13..841a177436 100644
--- a/hugegraph-api/src/main/java/com/baidu/hugegraph/api/traversers/ShortestPathAPI.java
+++ b/hugegraph-api/src/main/java/com/baidu/hugegraph/api/traversers/ShortestPathAPI.java
@@ -39,11 +39,14 @@
import com.baidu.hugegraph.backend.id.Id;
import com.baidu.hugegraph.core.GraphManager;
import com.baidu.hugegraph.server.RestServer;
-import com.baidu.hugegraph.traversal.optimize.HugeTraverser;
+import com.baidu.hugegraph.traversal.algorithm.ShortestPathTraverser;
import com.baidu.hugegraph.type.define.Directions;
import com.baidu.hugegraph.util.Log;
import com.codahale.metrics.annotation.Timed;
+import static com.baidu.hugegraph.traversal.algorithm.HugeTraverser.DEFAULT_CAPACITY;
+import static com.baidu.hugegraph.traversal.algorithm.HugeTraverser.DEFAULT_DEGREE;
+
@Path("graphs/{graph}/traversers/shortestpath")
@Singleton
public class ShortestPathAPI extends API {
@@ -60,9 +63,10 @@ public String get(@Context GraphManager manager,
@QueryParam("direction") String direction,
@QueryParam("label") String edgeLabel,
@QueryParam("max_depth") int depth,
- @QueryParam("max_degree") @DefaultValue("-1") long degree,
+ @QueryParam("max_degree")
+ @DefaultValue(DEFAULT_DEGREE) long degree,
@QueryParam("capacity")
- @DefaultValue("-1") long capacity) {
+ @DefaultValue(DEFAULT_CAPACITY) long capacity) {
LOG.debug("Graph [{}] get shortest path from '{}', to '{}' with " +
"direction {}, edge label {}, max depth '{}', " +
"max degree '{}' and capacity '{}'",
@@ -75,7 +79,7 @@ public String get(@Context GraphManager manager,
HugeGraph g = graph(manager, graph);
- HugeTraverser traverser = new HugeTraverser(g);
+ ShortestPathTraverser traverser = new ShortestPathTraverser(g);
List path = traverser.shortestPath(sourceId, targetId, dir,
edgeLabel, depth, degree,
capacity);
diff --git a/hugegraph-api/src/main/java/com/baidu/hugegraph/api/traversers/SourceVertices.java b/hugegraph-api/src/main/java/com/baidu/hugegraph/api/traversers/SourceVertices.java
new file mode 100644
index 0000000000..3ab05b5255
--- /dev/null
+++ b/hugegraph-api/src/main/java/com/baidu/hugegraph/api/traversers/SourceVertices.java
@@ -0,0 +1,98 @@
+/*
+ * 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.api.traversers;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.tinkerpop.gremlin.structure.Vertex;
+
+import com.baidu.hugegraph.HugeGraph;
+import com.baidu.hugegraph.backend.id.Id;
+import com.baidu.hugegraph.backend.query.Condition;
+import com.baidu.hugegraph.backend.query.ConditionQuery;
+import com.baidu.hugegraph.structure.HugeVertex;
+import com.baidu.hugegraph.type.HugeType;
+import com.baidu.hugegraph.type.define.HugeKeys;
+import com.baidu.hugegraph.util.E;
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+public class SourceVertices {
+
+ @JsonProperty("ids")
+ public Set