Skip to content
Permalink
Browse files
implement rings-detection algorithm (#95)
* add cycle detection algorithm
* improve: add field label in Vertex and Edge
* support properties filter in RingsDetection
* add StringValue
* add method object in Value
* update built-in object name in SpreadFilter and improve code style
* add standard rings-detection algorithm
* add RingsDetectionOutput
* resolve circular dependencies
* add message type IdListList rings-detection
  • Loading branch information
corgiboygsj committed Sep 26, 2021
1 parent 6090f98 commit 582f42ccdf5f494acdfb854bf97560d3e628458d
Showing 49 changed files with 1,501 additions and 97 deletions.
@@ -22,5 +22,35 @@
<artifactId>computer-core</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>com.googlecode.aviator</groupId>
<artifactId>aviator</artifactId>
<version>3.0.1</version>
</dependency>
</dependencies>

<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.2.4</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<artifactSet>
<includes>
<include>*:*</include>
</includes>
</artifactSet>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
@@ -96,4 +96,9 @@ public String toString() {
.append("count", this.count)
.toString();
}

@Override
public Object object() {
throw new NotSupportedException();
}
}
@@ -0,0 +1,116 @@
/*
* 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.computer.algorithm.path.rings;

import java.util.Iterator;

import com.baidu.hugegraph.computer.core.graph.edge.Edge;
import com.baidu.hugegraph.computer.core.graph.id.Id;
import com.baidu.hugegraph.computer.core.graph.value.IdList;
import com.baidu.hugegraph.computer.core.graph.value.IdListList;
import com.baidu.hugegraph.computer.core.graph.vertex.Vertex;
import com.baidu.hugegraph.computer.core.worker.Computation;
import com.baidu.hugegraph.computer.core.worker.ComputationContext;

public class RingsDetection implements Computation<IdList> {

@Override
public String name() {
return "rings";
}

@Override
public String category() {
return "path";
}

@Override
public void compute0(ComputationContext context, Vertex vertex) {
vertex.value(new IdListList());
if (vertex.edges().size() == 0) {
return;
}

// Init path
Id id = vertex.id();
IdList path = new IdList();
path.add(id);

for (Edge edge : vertex.edges()) {
/*
* Only send path to vertex whose id is larger than
* or equals current vertex id
*/
if (id.compareTo(edge.targetId()) <= 0) {
context.sendMessage(edge.targetId(), path);
}
}
}

@Override
public void compute(ComputationContext context, Vertex vertex,
Iterator<IdList> messages) {
Id id = vertex.id();
boolean halt = true;
while (messages.hasNext()) {
halt = false;
IdList sequence = messages.next();
if (id.equals(sequence.get(0))) {
// Use the smallest vertex record ring
boolean isMin = true;
for (int i = 1; i < sequence.size(); i++) {
Id pathVertexValue = sequence.get(i);
if (id.compareTo(pathVertexValue) > 0) {
isMin = false;
break;
}
}
if (isMin) {
sequence.add(id);
IdListList sequences = vertex.value();
sequences.add(sequence);
}
} else {
boolean contains = false;
// Drop sequence if path contains this vertex
for (int i = 0; i < sequence.size(); i++) {
Id pathVertexValue = sequence.get(i);
if (pathVertexValue.equals(vertex.id())) {
contains = true;
break;
}
}
// Field ringId is smallest vertex id in path
Id ringId = sequence.get(0);
if (!contains) {
sequence.add(vertex.id());
for (Edge edge : vertex.edges()) {
if (ringId.compareTo(edge.targetId()) <= 0) {
context.sendMessage(edge.targetId(), sequence);
}
}
}
}
}
if (halt) {
vertex.inactivate();
}
}
}
@@ -0,0 +1,63 @@
/*
* 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.computer.algorithm.path.rings;

import java.util.ArrayList;
import java.util.List;

import com.baidu.hugegraph.computer.core.graph.value.IdListList;
import com.baidu.hugegraph.computer.core.output.hg.HugeOutput;
import com.baidu.hugegraph.structure.constant.WriteType;
import com.baidu.hugegraph.structure.graph.Vertex;

public class RingsDetectionOutput extends HugeOutput {

@Override
public String name() {
return "rings";
}

@Override
public void prepareSchema() {
this.client().schema().propertyKey(this.name())
.asText()
.writeType(WriteType.OLAP_COMMON)
.valueList()
.ifNotExist()
.create();
}

@Override
public Vertex constructHugeVertex(
com.baidu.hugegraph.computer.core.graph.vertex.Vertex vertex) {
com.baidu.hugegraph.structure.graph.Vertex hugeVertex =
new com.baidu.hugegraph.structure.graph.Vertex(null);
hugeVertex.id(vertex.id().asObject());

IdListList value = vertex.value();
List<String> propValue = new ArrayList<>();
for (int i = 0; i < value.size(); i++) {
propValue.add(value.get(i).toString());
}

hugeVertex.property(this.name(), propValue);
return hugeVertex;
}
}
@@ -0,0 +1,42 @@
/*
* 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.computer.algorithm.path.rings;

import java.util.Map;

import com.baidu.hugegraph.computer.algorithm.AlgorithmParams;
import com.baidu.hugegraph.computer.core.config.ComputerOptions;
import com.baidu.hugegraph.computer.core.graph.value.IdList;
import com.baidu.hugegraph.computer.core.graph.value.IdListList;

public class RingsDetectionParams implements AlgorithmParams {

@Override
public void setAlgorithmParameters(Map<String, String> params) {
this.setIfAbsent(params, ComputerOptions.WORKER_COMPUTATION_CLASS,
RingsDetection.class.getName());
this.setIfAbsent(params, ComputerOptions.ALGORITHM_MESSAGE_CLASS,
IdList.class.getName());
this.setIfAbsent(params, ComputerOptions.ALGORITHM_RESULT_CLASS,
IdListList.class.getName());
this.setIfAbsent(params, ComputerOptions.OUTPUT_CLASS,
RingsDetectionOutput.class.getName());
}
}
@@ -0,0 +1,85 @@
/*
* 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.computer.algorithm.path.rings.filter;

import java.util.List;

import org.apache.commons.collections.CollectionUtils;

import com.baidu.hugegraph.util.JsonUtil;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.google.common.collect.ImmutableList;

public class FilterDescribe {

private final List<DescribeItem> vertexFilter;
private final List<DescribeItem> edgeFilter;

@JsonCreator
private FilterDescribe(@JsonProperty("vertex_filter")
List<DescribeItem> vertexFilter,
@JsonProperty("edge_filter")
List<DescribeItem> edgeFilter) {
this.vertexFilter = CollectionUtils.isEmpty(vertexFilter) ?
ImmutableList.of() :
ImmutableList.copyOf(vertexFilter);
this.edgeFilter = CollectionUtils.isEmpty(edgeFilter) ?
ImmutableList.of() :
ImmutableList.copyOf(edgeFilter);
}

public static FilterDescribe of(String describe) {
return JsonUtil.fromJson(describe, FilterDescribe.class);
}

public List<DescribeItem> vertexFilter() {
return this.vertexFilter;
}

public List<DescribeItem> edgeFilter() {
return this.edgeFilter;
}

public static class DescribeItem {

private final String label;
private final String propertyFilter;

@JsonCreator
private DescribeItem(@JsonProperty(value = "label",
required = true)
String label,
@JsonProperty(value = "property_filter",
required = true)
String propertyFilter) {
this.label = label;
this.propertyFilter = propertyFilter;
}

public String label() {
return this.label;
}

public String propertyFilter() {
return this.propertyFilter;
}
}
}

0 comments on commit 582f42c

Please sign in to comment.