/* * 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 org.apache.flink.graph.asm.degree.annotate; import org.apache.flink.api.common.functions.JoinFunction; import org.apache.flink.api.common.functions.MapFunction; import org.apache.flink.api.common.functions.ReduceFunction; import org.apache.flink.api.java.functions.FunctionAnnotation.ForwardedFields; import org.apache.flink.api.java.functions.FunctionAnnotation.ForwardedFieldsFirst; import org.apache.flink.api.java.functions.FunctionAnnotation.ForwardedFieldsSecond; import org.apache.flink.api.java.tuple.Tuple2; import org.apache.flink.api.java.tuple.Tuple3; import org.apache.flink.graph.Edge; import org.apache.flink.graph.Vertex; import org.apache.flink.types.LongValue; public class DegreeAnnotationFunctions { // -------------------------------------------------------------------------------------------- // Vertex functions // -------------------------------------------------------------------------------------------- /** * Emits the source vertex ID along with an initial count. * * @param <K> ID type * @param <EV> edge value type */ @ForwardedFields("0") public static class MapEdgeToSourceId<K, EV> implements MapFunction<Edge<K, EV>, Vertex<K, LongValue>> { private Vertex<K, LongValue> output = new Vertex<>(null, new LongValue(1)); @Override public Vertex<K, LongValue> map(Edge<K, EV> value) throws Exception { output.f0 = value.f0; return output; } } /** * Emits the target vertex ID along with an initial count. * * @param <K> ID type * @param <EV> edge value type */ @ForwardedFields("1->0") public static class MapEdgeToTargetId<K, EV> implements MapFunction<Edge<K, EV>, Vertex<K, LongValue>> { private Vertex<K, LongValue> output = new Vertex<>(null, new LongValue(1)); @Override public Vertex<K, LongValue> map(Edge<K, EV> value) throws Exception { output.f0 = value.f1; return output; } } /** * Combines the vertex degree count. * * @param <K> ID type */ @ForwardedFields("0") public static class DegreeCount<K> implements ReduceFunction<Vertex<K, LongValue>> { @Override public Vertex<K, LongValue> reduce(Vertex<K, LongValue> left, Vertex<K, LongValue> right) throws Exception { LongValue count = left.f1; count.setValue(count.getValue() + right.f1.getValue()); return left; } } /** * Performs a left outer join to apply a zero count for vertices with * out- or in-degree of zero. * * @param <K> ID type * @param <VV> vertex value type */ @ForwardedFieldsFirst("0") @ForwardedFieldsSecond("0") public static class JoinVertexWithVertexDegree<K, VV> implements JoinFunction<Vertex<K, VV>, Vertex<K, LongValue>, Vertex<K, LongValue>> { private LongValue zero = new LongValue(0); private Vertex<K, LongValue> output = new Vertex<>(); @Override public Vertex<K, LongValue> join(Vertex<K, VV> vertex, Vertex<K, LongValue> vertexDegree) throws Exception { output.f0 = vertex.f0; output.f1 = (vertexDegree == null) ? zero : vertexDegree.f1; return output; } } // -------------------------------------------------------------------------------------------- // Edge functions // -------------------------------------------------------------------------------------------- /** * Assigns the vertex degree to this edge value. * * @param <K> ID type * @param <EV> edge value type * @param <D> degree type */ @ForwardedFieldsFirst("0; 1; 2->2.0") @ForwardedFieldsSecond("0; 1->2.1") public static class JoinEdgeWithVertexDegree<K, EV, D> implements JoinFunction<Edge<K, EV>, Vertex<K, D>, Edge<K, Tuple2<EV, D>>> { private Tuple2<EV, D> valueAndDegree = new Tuple2<>(); private Edge<K, Tuple2<EV, D>> output = new Edge<>(null, null, valueAndDegree); @Override public Edge<K, Tuple2<EV, D>> join(Edge<K, EV> edge, Vertex<K, D> vertex) throws Exception { output.f0 = edge.f0; output.f1 = edge.f1; valueAndDegree.f0 = edge.f2; valueAndDegree.f1 = vertex.f1; return output; } } /** * Composes the vertex degree with this edge value. * * @param <K> ID type * @param <EV> edge value type * @param <D> degree type */ @ForwardedFieldsFirst("0; 1; 2.0; 2.1") @ForwardedFieldsSecond("0; 1->2.2") public static class JoinEdgeDegreeWithVertexDegree<K, EV, D> implements JoinFunction<Edge<K, Tuple2<EV, D>>, Vertex<K, D>, Edge<K, Tuple3<EV, D, D>>> { private Tuple3<EV, D, D> valueAndDegrees = new Tuple3<>(); private Edge<K, Tuple3<EV, D, D>> output = new Edge<>(null, null, valueAndDegrees); @Override public Edge<K, Tuple3<EV, D, D>> join(Edge<K, Tuple2<EV, D>> edge, Vertex<K, D> vertex) throws Exception { Tuple2<EV, D> valueAndDegree = edge.f2; output.f0 = edge.f0; output.f1 = edge.f1; valueAndDegrees.f0 = valueAndDegree.f0; valueAndDegrees.f1 = valueAndDegree.f1; valueAndDegrees.f2 = vertex.f1; return output; } } }