Skip to content

Commit

Permalink
add direction and label parameter for centrality algorithms (#13)
Browse files Browse the repository at this point in the history
Change-Id: I20b72ea0da673359e2bd21888010290efca81441
  • Loading branch information
javeme authored and imbajin committed Nov 1, 2022
1 parent 56bf814 commit e2b1a0f
Show file tree
Hide file tree
Showing 6 changed files with 89 additions and 25 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@
import com.baidu.hugegraph.type.define.Directions;
import com.baidu.hugegraph.type.define.HugeKeys;
import com.baidu.hugegraph.util.Bytes;
import com.baidu.hugegraph.util.CollectionUtil;
import com.baidu.hugegraph.util.E;
import com.baidu.hugegraph.util.JsonUtil;

Expand Down Expand Up @@ -119,6 +120,9 @@ protected static String edgeLabel(Map<String, Object> parameters) {
}

protected static Directions direction(Map<String, Object> parameters) {
if (!parameters.containsKey(KEY_DIRECTION)) {
return Directions.BOTH;
}
Object direction = parameter(parameters, KEY_DIRECTION);
return parseDirection(direction);
}
Expand Down Expand Up @@ -437,7 +441,11 @@ public void put(K key, long value) {
}

public Set<Map.Entry<K, MutableLong>> entrySet() {
this.shrinkIfNeeded(this.topN);
if (this.tops.size() <= this.topN) {
this.tops = CollectionUtil.sortByValue(this.tops, false);
} else {
this.shrinkIfNeeded(this.topN);
}
return this.tops.entrySet();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,14 @@
import org.apache.tinkerpop.gremlin.process.traversal.Pop;
import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversal;
import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__;
import org.apache.tinkerpop.gremlin.structure.Direction;
import org.apache.tinkerpop.gremlin.structure.Vertex;

import com.baidu.hugegraph.backend.id.Id;
import com.baidu.hugegraph.job.Job;
import com.baidu.hugegraph.job.algorithm.AbstractAlgorithm;
import com.baidu.hugegraph.structure.HugeElement;
import com.baidu.hugegraph.type.define.Directions;

public abstract class AbstractCentAlgorithm extends AbstractAlgorithm {

Expand All @@ -46,6 +48,8 @@ public void checkParameters(Map<String, Object> parameters) {
depth(parameters);
degree(parameters);
sample(parameters);
direction(parameters);
edgeLabel(parameters);
sourceSample(parameters);
sourceLabel(parameters);
sourceCLabel(parameters);
Expand Down Expand Up @@ -83,9 +87,11 @@ protected GraphTraversal<Vertex, Vertex> constructSource(
}

protected GraphTraversal<Vertex, Vertex> constructPath(
GraphTraversal<Vertex, Vertex> t, long degree,
long sample, String sourceLabel, String sourceCLabel) {
GraphTraversal<?, Vertex> unit = constructPathUnit(degree, sample,
GraphTraversal<Vertex, Vertex> t, Directions dir,
String label, long degree, long sample,
String sourceLabel, String sourceCLabel) {
GraphTraversal<?, Vertex> unit = constructPathUnit(dir, label,
degree, sample,
sourceLabel,
sourceCLabel);
t = t.as("v").repeat(__.local(unit).simplePath().as("v"));
Expand All @@ -94,10 +100,21 @@ protected GraphTraversal<Vertex, Vertex> constructPath(
}

protected GraphTraversal<Vertex, Vertex> constructPathUnit(
Directions dir, String label,
long degree, long sample,
String sourceLabel,
String sourceCLabel) {
GraphTraversal<Vertex, Vertex> unit = __.both();
if (dir == null) {
dir = Directions.BOTH;
}
Direction direction = dir.direction();

String[] labels = {};
if (label != null) {
labels = new String[]{label};
}

GraphTraversal<Vertex, Vertex> unit = __.to(direction, labels);
if (sourceLabel != null) {
unit = unit.hasLabel(sourceLabel);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
import org.apache.tinkerpop.gremlin.structure.Vertex;

import com.baidu.hugegraph.job.Job;
import com.baidu.hugegraph.type.define.Directions;

public class BetweenessCentralityAlgorithm extends AbstractCentAlgorithm {

Expand All @@ -42,7 +43,9 @@ public String name() {
@Override
public Object call(Job<Object> job, Map<String, Object> parameters) {
Traverser traverser = new Traverser(job);
return traverser.betweenessCentrality(depth(parameters),
return traverser.betweenessCentrality(direction(parameters),
edgeLabel(parameters),
depth(parameters),
degree(parameters),
sample(parameters),
sourceLabel(parameters),
Expand All @@ -57,7 +60,9 @@ public Traverser(Job<Object> job) {
super(job);
}

public Object betweenessCentrality(int depth,
public Object betweenessCentrality(Directions direction,
String label,
int depth,
long degree,
long sample,
String sourceLabel,
Expand All @@ -71,7 +76,8 @@ public Object betweenessCentrality(int depth,
GraphTraversal<Vertex, Vertex> t = constructSource(sourceLabel,
sourceSample,
sourceCLabel);
t = constructPath(t, degree, sample, sourceLabel, sourceCLabel);
t = constructPath(t, direction, label, degree, sample,
sourceLabel, sourceCLabel);
t = t.emit().until(__.loops().is(P.gte(depth)));
t = filterNonShortestPath(t);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
import org.apache.tinkerpop.gremlin.structure.Vertex;

import com.baidu.hugegraph.job.Job;
import com.baidu.hugegraph.type.define.Directions;

public class ClosenessCentralityAlgorithm extends AbstractCentAlgorithm {

Expand All @@ -51,7 +52,9 @@ public void checkParameters(Map<String, Object> parameters) {
@Override
public Object call(Job<Object> job, Map<String, Object> parameters) {
Traverser traverser = new Traverser(job);
return traverser.closenessCentrality(depth(parameters),
return traverser.closenessCentrality(direction(parameters),
edgeLabel(parameters),
depth(parameters),
degree(parameters),
sample(parameters),
sourceLabel(parameters),
Expand All @@ -66,7 +69,9 @@ public Traverser(Job<Object> job) {
super(job);
}

public Object closenessCentrality(int depth,
public Object closenessCentrality(Directions direction,
String label,
int depth,
long degree,
long sample,
String sourceLabel,
Expand All @@ -80,7 +85,8 @@ public Object closenessCentrality(int depth,
GraphTraversal<Vertex, Vertex> t = constructSource(sourceLabel,
sourceSample,
sourceCLabel);
t = constructPath(t, degree, sample, sourceLabel, sourceCLabel);
t = constructPath(t, direction, label, degree, sample,
sourceLabel, sourceCLabel);
t = t.emit().until(__.loops().is(P.gte(depth)));
t = filterNonShortestPath(t);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,9 @@
import java.util.Iterator;
import java.util.Map;

import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversalSource;
import org.apache.tinkerpop.gremlin.structure.Edge;
import org.apache.tinkerpop.gremlin.structure.Vertex;
import org.apache.tinkerpop.gremlin.util.iterator.IteratorUtils;

import com.baidu.hugegraph.backend.id.Id;
import com.baidu.hugegraph.job.Job;
Expand All @@ -41,13 +41,15 @@ public String name() {
@Override
public void checkParameters(Map<String, Object> parameters) {
direction(parameters);
edgeLabel(parameters);
top(parameters);
}

@Override
public Object call(Job<Object> job, Map<String, Object> parameters) {
Traverser traverser = new Traverser(job);
return traverser.degreeCentrality(direction(parameters),
edgeLabel(parameters),
top(parameters));
}

Expand All @@ -57,9 +59,11 @@ public Traverser(Job<Object> job) {
super(job);
}

public Object degreeCentrality(Directions direction, long topN) {
public Object degreeCentrality(Directions direction,
String label,
long topN) {
if (direction == null || direction == Directions.BOTH) {
return degreeCentrality(topN);
return degreeCentrality(label, topN);
}
assert direction == Directions.OUT || direction == Directions.IN;
assert topN >= 0L;
Expand All @@ -69,6 +73,7 @@ public Object degreeCentrality(Directions direction, long topN) {
JsonMap degrees = new JsonMap();
TopMap<Id> tops = new TopMap<>(topN);
Id vertex = null;
Id labelId = this.getEdgeLabelId(label);
long degree = 0L;
long total = 0L;

Expand All @@ -77,12 +82,20 @@ public Object degreeCentrality(Directions direction, long topN) {
HugeEdge edge = (HugeEdge) edges.next();
this.updateProgress(++total);

Id schemaLabel = edge.schemaLabel().id();
if (labelId != null && !labelId.equals(schemaLabel)) {
continue;
}

Id source = edge.ownerVertex().id();
if (source.equals(vertex)) {
// edges belong to same source vertex
degree++;
continue;
}

if (vertex != null) {
// next vertex found
if (topN <= 0L) {
degrees.append(vertex, degree);
} else {
Expand All @@ -107,25 +120,26 @@ public Object degreeCentrality(Directions direction, long topN) {
return degrees.asJson();
}

protected Object degreeCentrality(long topN) {
protected Object degreeCentrality(String label, long topN) {
assert topN >= 0L;
long total = 0L;
JsonMap degrees = new JsonMap();
TopMap<Id> tops = new TopMap<>(topN);

GraphTraversalSource traversal = this.graph().traversal();
Iterator<Vertex> vertices = this.vertices();

degrees.startObject();
while (vertices.hasNext()) {
Vertex source = vertices.next();
Id source = (Id) vertices.next().id();
this.updateProgress(++total);

Long degree = traversal.V(source).bothE().count().next();
if (topN <= 0L) {
degrees.append(source.id(), degree);
} else {
tops.put((Id) source.id(), degree);
long degree = this.degree(source, label);
if (degree > 0L) {
if (topN <= 0L) {
degrees.append(source, degree);
} else {
tops.put(source, degree);
}
}
}

Expand All @@ -136,5 +150,12 @@ protected Object degreeCentrality(long topN) {

return degrees.asJson();
}

private long degree(Id source, String label) {
Id labelId = this.getEdgeLabelId(label);
Iterator<Edge> edges = this.edgesOfVertex(source, Directions.BOTH,
labelId, NO_LIMIT);
return IteratorUtils.count(edges);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
import org.apache.tinkerpop.gremlin.structure.Vertex;

import com.baidu.hugegraph.job.Job;
import com.baidu.hugegraph.type.define.Directions;

public class EigenvectorCentralityAlgorithm extends AbstractCentAlgorithm {

Expand All @@ -44,7 +45,9 @@ public String name() {
@Override
public Object call(Job<Object> job, Map<String, Object> parameters) {
Traverser traverser = new Traverser(job);
return traverser.eigenvectorCentrality(depth(parameters),
return traverser.eigenvectorCentrality(direction(parameters),
edgeLabel(parameters),
depth(parameters),
degree(parameters),
sample(parameters),
sourceLabel(parameters),
Expand All @@ -59,7 +62,9 @@ public Traverser(Job<Object> job) {
super(job);
}

public Object eigenvectorCentrality(int depth,
public Object eigenvectorCentrality(Directions direction,
String label,
int depth,
long degree,
long sample,
String sourceLabel,
Expand All @@ -83,7 +88,8 @@ public Object eigenvectorCentrality(int depth,
GraphTraversal<Vertex, Vertex> t = constructSource(sourceLabel,
sourceSample,
sourceCLabel);
GraphTraversal<?, Vertex> unit = constructPathUnit(degree, sample,
GraphTraversal<?, Vertex> unit = constructPathUnit(direction, label,
degree, sample,
sourceLabel,
sourceCLabel);
t = t.repeat(__.groupCount("m").by(T.id)
Expand Down

0 comments on commit e2b1a0f

Please sign in to comment.