Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(api&core): in oltp apis, add statistics info and support full info about vertices and edges #2262

Merged
merged 16 commits into from
Aug 19, 2023
Merged
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -7,6 +7,8 @@ upload-files/
demo*
gen-java
*.class
swagger-ui-*
hugegraph-dist/dist.sh
Copy link
Member

@imbajin imbajin Aug 11, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, but we need fix/remove it in the dist-script rather than exclude them in git (will be fixed it in another PR) @VGalaxies

yzBIrgUZmN

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok, fixed and rollback change


### STS ###
.apt_generated
58 changes: 49 additions & 9 deletions hugegraph-api/src/main/java/org/apache/hugegraph/api/API.java
Original file line number Diff line number Diff line change
@@ -18,28 +18,30 @@
package org.apache.hugegraph.api;

import java.util.Collection;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.concurrent.Callable;
import java.util.function.Consumer;

import jakarta.ws.rs.ForbiddenException;
import jakarta.ws.rs.NotFoundException;
import jakarta.ws.rs.NotSupportedException;
import jakarta.ws.rs.core.MediaType;

import org.apache.hugegraph.HugeException;
import org.apache.hugegraph.HugeGraph;
import org.apache.hugegraph.core.GraphManager;
import org.apache.hugegraph.define.Checkable;
import org.apache.hugegraph.metrics.MetricsUtil;
import org.slf4j.Logger;

import org.apache.hugegraph.HugeException;
import org.apache.hugegraph.HugeGraph;
import org.apache.hugegraph.util.E;
import org.apache.hugegraph.util.JsonUtil;
import org.apache.hugegraph.util.Log;
import org.slf4j.Logger;

import com.codahale.metrics.Meter;
import com.google.common.collect.ImmutableMap;

import jakarta.ws.rs.ForbiddenException;
import jakarta.ws.rs.NotFoundException;
import jakarta.ws.rs.NotSupportedException;
import jakarta.ws.rs.core.MediaType;

public class API {

protected static final Logger LOG = Log.logger(API.class);
@@ -190,4 +192,42 @@ public static boolean checkAndParseAction(String action) {
String.format("Not support action '%s'", action));
}
}

public static class ApiMeasure {
public static final String EDGE_ITER = "edge_iters";
public static final String VERTICE_ITER = "vertice_iters";
public static final String COST = "cost";
protected long timeStart = System.currentTimeMillis();
protected HashMap<String, Object> mapResult = new LinkedHashMap<>();

public Map<String, Object> getResult() {
mapResult.put(COST, System.currentTimeMillis() - timeStart);
return mapResult;
}

public void put(String key, String value) {
this.mapResult.put(key, value);
}

public void put(String key, long value) {
this.mapResult.put(key, value);
}

public void put(String key, int value) {
this.mapResult.put(key, value);
}

protected void addCount(String key, long value) {
long cur = 0;
if (this.mapResult.containsKey(key)) {
cur = (long) this.mapResult.get(key);
}
this.mapResult.put(key, cur + value);
}

public void addIterCount(long verticeIters, long edgeIters) {
this.addCount(EDGE_ITER, edgeIters);
this.addCount(VERTICE_ITER, verticeIters);
}
}
}
Original file line number Diff line number Diff line change
@@ -20,19 +20,10 @@
import static org.apache.hugegraph.traversal.algorithm.HugeTraverser.DEFAULT_CAPACITY;
import static org.apache.hugegraph.traversal.algorithm.HugeTraverser.DEFAULT_MAX_DEGREE;

import java.util.HashSet;
import java.util.Iterator;
import java.util.List;

import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.inject.Singleton;
import jakarta.ws.rs.DefaultValue;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.PathParam;
import jakarta.ws.rs.Produces;
import jakarta.ws.rs.QueryParam;
import jakarta.ws.rs.core.Context;

import org.slf4j.Logger;
import java.util.Set;

import org.apache.hugegraph.HugeGraph;
import org.apache.hugegraph.api.API;
@@ -44,9 +35,22 @@
import org.apache.hugegraph.traversal.algorithm.ShortestPathTraverser;
import org.apache.hugegraph.type.define.Directions;
import org.apache.hugegraph.util.Log;
import org.apache.tinkerpop.gremlin.structure.Edge;
import org.slf4j.Logger;

import com.codahale.metrics.annotation.Timed;
import com.google.common.collect.ImmutableList;

import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.inject.Singleton;
import jakarta.ws.rs.DefaultValue;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.PathParam;
import jakarta.ws.rs.Produces;
import jakarta.ws.rs.QueryParam;
import jakarta.ws.rs.core.Context;

@Path("graphs/{graph}/traversers/allshortestpaths")
@Singleton
@Tag(name = "AllShortestPathsAPI")
@@ -68,13 +72,20 @@ public String get(@Context GraphManager manager,
@DefaultValue(DEFAULT_MAX_DEGREE) long maxDegree,
@QueryParam("skip_degree")
@DefaultValue("0") long skipDegree,
@QueryParam("with_vertex")
@DefaultValue("false") boolean withVertex,
@QueryParam("with_edge")
@DefaultValue("false") boolean withEdge,
@QueryParam("capacity")
@DefaultValue(DEFAULT_CAPACITY) long capacity) {
LOG.debug("Graph [{}] get shortest path from '{}', to '{}' with " +
"direction {}, edge label {}, max depth '{}', " +
"max degree '{}', skipped degree '{}' and capacity '{}'",
"max degree '{}', skipped degree '{}', capacity '{}', " +
"with vertex '{}' and with edge '{}'",
graph, source, target, direction, edgeLabel, depth,
maxDegree, skipDegree, capacity);
maxDegree, skipDegree, capacity, withVertex, withEdge);

ApiMeasure measure = new ApiMeasure();

Id sourceId = VertexAPI.checkAndParseVertexId(source);
Id targetId = VertexAPI.checkAndParseVertexId(target);
@@ -86,8 +97,34 @@ public String get(@Context GraphManager manager,
List<String> edgeLabels = edgeLabel == null ? ImmutableList.of() :
ImmutableList.of(edgeLabel);
HugeTraverser.PathSet paths = traverser.allShortestPaths(
sourceId, targetId, dir, edgeLabels,
depth, maxDegree, skipDegree, capacity);
return manager.serializer(g).writePaths("paths", paths, false);
sourceId, targetId, dir, edgeLabels,
depth, maxDegree, skipDegree, capacity);

measure.addIterCount(traverser.vertexIterCounter.get(),
traverser.edgeIterCounter.get());

Iterator<?> iterVertex;
Set<Id> vertexIds = new HashSet<>();
for (HugeTraverser.Path path : paths) {
vertexIds.addAll(path.vertices());
}
if (withVertex && !vertexIds.isEmpty()) {
iterVertex = g.vertices(vertexIds.toArray());
measure.addIterCount(vertexIds.size(), 0L);
} else {
iterVertex = vertexIds.iterator();
}

Iterator<?> iterEdge;
Set<Edge> edges = paths.getEdges();
if (withEdge && !edges.isEmpty()) {
iterEdge = edges.iterator();
} else {
iterEdge = HugeTraverser.EdgeRecord.getEdgeIds(edges).iterator();
}

return manager.serializer(g, measure.getResult())
.writePaths("paths", paths, false,
iterVertex, iterEdge);
}
}
Original file line number Diff line number Diff line change
@@ -21,18 +21,6 @@
import static org.apache.hugegraph.traversal.algorithm.HugeTraverser.DEFAULT_MAX_DEGREE;
import static org.apache.hugegraph.traversal.algorithm.HugeTraverser.DEFAULT_PATHS_LIMIT;

import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.inject.Singleton;
import jakarta.ws.rs.DefaultValue;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.PathParam;
import jakarta.ws.rs.Produces;
import jakarta.ws.rs.QueryParam;
import jakarta.ws.rs.core.Context;

import org.slf4j.Logger;

import org.apache.hugegraph.HugeGraph;
import org.apache.hugegraph.api.API;
import org.apache.hugegraph.api.graph.EdgeAPI;
@@ -43,8 +31,20 @@
import org.apache.hugegraph.traversal.algorithm.PathsTraverser;
import org.apache.hugegraph.type.define.Directions;
import org.apache.hugegraph.util.Log;
import org.slf4j.Logger;

import com.codahale.metrics.annotation.Timed;

import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.inject.Singleton;
import jakarta.ws.rs.DefaultValue;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.PathParam;
import jakarta.ws.rs.Produces;
import jakarta.ws.rs.QueryParam;
import jakarta.ws.rs.core.Context;

@Path("graphs/{graph}/traversers/crosspoints")
@Singleton
@Tag(name = "CrosspointsAPI")
@@ -74,6 +74,7 @@ public String get(@Context GraphManager manager,
graph, source, target, direction, edgeLabel,
depth, maxDegree, capacity, limit);

ApiMeasure measure = new ApiMeasure();
Id sourceId = VertexAPI.checkAndParseVertexId(source);
Id targetId = VertexAPI.checkAndParseVertexId(target);
Directions dir = Directions.convert(EdgeAPI.parseDirection(direction));
@@ -84,6 +85,9 @@ public String get(@Context GraphManager manager,
dir, edgeLabel, depth,
maxDegree, capacity,
limit);
return manager.serializer(g).writePaths("crosspoints", paths, true);
measure.addIterCount(traverser.vertexIterCounter.get(),
traverser.edgeIterCounter.get());
return manager.serializer(g, measure.getResult())
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

prefer to update the serializer(g) method and set default an ApiMeasure

Copy link
Contributor Author

@DanGuge DanGuge Jul 31, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rejected:

  1. ApiMeasurer should be passed in from an outside api implementation so that it can carry data
  2. not all apis need ApiMeasurer and keeping the ApiMeasurer null for those APIs can prevent ApiMeasurer from being serialized

.writePaths("crosspoints", paths, true);
}
}
Loading