Skip to content
Permalink
Browse files
Implement triangle_count algorithms and improve some code (#101)
* Implement triangle_count algorithms
* Improve some code
  • Loading branch information
coderzc committed Sep 24, 2021
1 parent bb12226 commit 6090f985e9aa4be54bbf43fe77233099c06214e9
Showing 14 changed files with 516 additions and 56 deletions.
@@ -56,12 +56,12 @@ jobs:
$TRAVIS_DIR/install-hugegraph-from-source.sh $COMMIT_ID | grep -v "Downloading\|Downloaded"
$TRAVIS_DIR/load-data-into-hugegraph.sh
- name: Unit test
run: mvn test -P unit-test

- name: Integrate test
run: mvn test -P integrate-test

- name: Unit test
run: mvn test -P unit-test

- name: Upload coverage to Codecov
uses: codecov/codecov-action@v1
with:
@@ -0,0 +1,122 @@
/*
* 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.community.trianglecount;


import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;

import com.baidu.hugegraph.computer.core.graph.edge.Edge;
import com.baidu.hugegraph.computer.core.graph.edge.Edges;
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.vertex.Vertex;
import com.baidu.hugegraph.computer.core.worker.Computation;
import com.baidu.hugegraph.computer.core.worker.ComputationContext;

public class TriangleCount implements Computation<IdList> {

public static final String ALGORITHM_NAME = "triangle_count";

@Override
public String name() {
return ALGORITHM_NAME;
}

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

@Override
public void compute0(ComputationContext context, Vertex vertex) {
IdList selfId = new IdList();
selfId.add(vertex.id());

context.sendMessageToAllEdgesIf(vertex, selfId, (ids, targetId) -> {
return !ids.get(0).equals(targetId);
});
vertex.value(new TriangleCountValue());
}

@Override
public void compute(ComputationContext context, Vertex vertex,
Iterator<IdList> messages) {
Long count = this.triangleCount(context, vertex, messages);
if (count != null) {
((TriangleCountValue) vertex.value()).count(count);
vertex.inactivate();
}
}

private Long triangleCount(ComputationContext context, Vertex vertex,
Iterator<IdList> messages) {
IdList neighbors = ((TriangleCountValue) vertex.value()).idList();

if (context.superstep() == 1) {
// Collect outgoing neighbors
Set<Id> outNeighbors = getOutNeighbors(vertex);
neighbors.addAll(outNeighbors);

// Collect incoming neighbors
while (messages.hasNext()) {
IdList idList = messages.next();
assert idList.size() == 1;
Id inId = idList.get(0);
if (!outNeighbors.contains(inId)) {
neighbors.add(inId);
}
}

// Send all neighbors to neighbors
for (Id targetId : neighbors.values()) {
context.sendMessage(targetId, neighbors);
}
} else if (context.superstep() == 2) {
long count = 0L;

Set<Id> allNeighbors = new HashSet<>(neighbors.values());
while (messages.hasNext()) {
IdList twoDegreeNeighbors = messages.next();
for (Id twoDegreeNeighbor : twoDegreeNeighbors.values()) {
if (allNeighbors.contains(twoDegreeNeighbor)) {
count++;
}
}
}

return count >> 1;
}
return null;
}

private static Set<Id> getOutNeighbors(Vertex vertex) {
Set<Id> outNeighbors = new HashSet<>();
Edges edges = vertex.edges();
for (Edge edge : edges) {
Id targetId = edge.targetId();
if (!vertex.id().equals(targetId)) {
outNeighbors.add(targetId);
}
}
return outNeighbors;
}
}
@@ -0,0 +1,52 @@
/*
* 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.community.trianglecount;

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

public class TriangleCountOutput extends HugeOutput {

@Override
public String name() {
return TriangleCount.ALGORITHM_NAME;
}

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

@Override
public com.baidu.hugegraph.structure.graph.Vertex constructHugeVertex(
Vertex vertex) {
com.baidu.hugegraph.structure.graph.Vertex hugeVertex =
new com.baidu.hugegraph.structure.graph.Vertex(null);
hugeVertex.id(vertex.id().asObject());
long value = ((TriangleCountValue) vertex.value()).count();
hugeVertex.property(this.name(), value);
return hugeVertex;
}
}
@@ -0,0 +1,44 @@
/*
* 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.community.trianglecount;

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.config.EdgeFrequency;
import com.baidu.hugegraph.computer.core.graph.value.IdList;

public class TriangleCountParams implements AlgorithmParams {

@Override
public void setAlgorithmParameters(Map<String, String> params) {
this.setIfAbsent(params, ComputerOptions.WORKER_COMPUTATION_CLASS,
TriangleCount.class.getName());
this.setIfAbsent(params, ComputerOptions.ALGORITHM_MESSAGE_CLASS,
IdList.class.getName());
this.setIfAbsent(params, ComputerOptions.ALGORITHM_RESULT_CLASS,
TriangleCountValue.class.getName());
this.setIfAbsent(params, ComputerOptions.OUTPUT_CLASS,
TriangleCountOutput.class.getName());
this.setIfAbsent(params, ComputerOptions.INPUT_EDGE_FREQ.name(),
EdgeFrequency.SINGLE.name());
}
}
@@ -0,0 +1,99 @@
/*
* 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.community.trianglecount;

import java.io.IOException;

import javax.ws.rs.NotSupportedException;

import org.apache.commons.lang3.builder.ToStringBuilder;

import com.baidu.hugegraph.computer.core.graph.value.IdList;
import com.baidu.hugegraph.computer.core.graph.value.LongValue;
import com.baidu.hugegraph.computer.core.graph.value.Value;
import com.baidu.hugegraph.computer.core.graph.value.ValueType;
import com.baidu.hugegraph.computer.core.io.RandomAccessInput;
import com.baidu.hugegraph.computer.core.io.RandomAccessOutput;

public class TriangleCountValue implements Value<TriangleCountValue> {

private IdList idList;
private LongValue count;

public TriangleCountValue() {
this.idList = new IdList();
this.count = new LongValue();
}

public IdList idList() {
return this.idList;
}

public long count() {
return this.count.value();
}

public void count(Long count) {
this.count.value(count);
}

@Override
public ValueType valueType() {
return ValueType.UNKNOWN;
}

@Override
public void assign(Value<TriangleCountValue> other) {
throw new NotSupportedException();
}

@Override
public Value<TriangleCountValue> copy() {
TriangleCountValue triangleCountValue = new TriangleCountValue();
triangleCountValue.idList = this.idList.copy();
triangleCountValue.count = this.count.copy();
return triangleCountValue;
}

@Override
public void read(RandomAccessInput in) throws IOException {
this.idList.read(in);
this.count.read(in);
}

@Override
public void write(RandomAccessOutput out) throws IOException {
this.idList.write(out);
this.count.write(out);
}

@Override
public int compareTo(TriangleCountValue other) {
throw new NotSupportedException();
}

@Override
public String toString() {
return new ToStringBuilder(this)
.append("idList", this.idList)
.append("count", this.count)
.toString();
}
}

0 comments on commit 6090f98

Please sign in to comment.