All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.apache.flink.spargel.java.MessagingFunction Maven / Gradle / Ivy

There is a newer version: 0.9.1-hadoop1
Show newest version
/*
 * 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.spargel.java;

import java.io.Serializable;
import java.util.Collection;
import java.util.Iterator;

import org.apache.flink.api.common.aggregators.Aggregator;
import org.apache.flink.api.common.functions.IterationRuntimeContext;
import org.apache.flink.api.java.tuple.Tuple;
import org.apache.flink.api.java.tuple.Tuple2;
import org.apache.flink.api.java.tuple.Tuple3;
import org.apache.flink.spargel.java.OutgoingEdge;
import org.apache.flink.types.Value;
import org.apache.flink.util.Collector;

/**
 * The base class for functions that produce messages between vertices as a part of a {@link VertexCentricIteration}.
 * 
 * @param  The type of the vertex key (the vertex identifier).
 * @param  The type of the vertex value (the state of the vertex).
 * @param  The type of the message sent between vertices along the edges.
 * @param  The type of the values that are associated with the edges.
 */
@Deprecated
public abstract class MessagingFunction, VertexValue, Message, EdgeValue> implements Serializable {

	private static final long serialVersionUID = 1L;
	
	// --------------------------------------------------------------------------------------------
	//  Public API Methods
	// --------------------------------------------------------------------------------------------
	
	/**
	 * This method is invoked once per superstep for each vertex that was changed in that superstep.
	 * It needs to produce the messages that will be received by vertices in the next superstep.
	 * 
	 * @param vertexKey The key of the vertex that was changed.
	 * @param vertexValue The value (state) of the vertex that was changed.
	 * 
	 * @throws Exception The computation may throw exceptions, which causes the superstep to fail.
	 */
	@Deprecated
	public abstract void sendMessages(VertexKey vertexKey, VertexValue vertexValue) throws Exception;
	
	/**
	 * This method is executed one per superstep before the vertex update function is invoked for each vertex.
	 * 
	 * @throws Exception Exceptions in the pre-superstep phase cause the superstep to fail.
	 */
	@Deprecated
	public void preSuperstep() throws Exception {}
	
	/**
	 * This method is executed one per superstep after the vertex update function has been invoked for each vertex.
	 * 
	 * @throws Exception Exceptions in the post-superstep phase cause the superstep to fail.
	 */
	@Deprecated
	public void postSuperstep() throws Exception {}
	
	
	/**
	 * Gets an {@link java.lang.Iterable} with all outgoing edges. This method is mutually exclusive with
	 * {@link #sendMessageToAllNeighbors(Object)} and may be called only once.
	 * 
	 * @return An iterator with all outgoing edges.
	 */
	@SuppressWarnings("unchecked")
	public Iterable> getOutgoingEdges() {
		if (edgesUsed) {
			throw new IllegalStateException("Can use either 'getOutgoingEdges()' or 'sendMessageToAllTargets()' exactly once.");
		}
		edgesUsed = true;
		
		if (this.edgeWithValueIter != null) {
			this.edgeWithValueIter.set((Iterator>) edges);
			return this.edgeWithValueIter;
		} else {
			this.edgeNoValueIter.set((Iterator>) edges);
			return this.edgeNoValueIter;
		}
	}
	
	/**
	 * Sends the given message to all vertices that are targets of an outgoing edge of the changed vertex.
	 * This method is mutually exclusive to the method {@link #getOutgoingEdges()} and may be called only once.
	 * 
	 * @param m The message to send.
	 */
	public void sendMessageToAllNeighbors(Message m) {
		if (edgesUsed) {
			throw new IllegalStateException("Can use either 'getOutgoingEdges()' or 'sendMessageToAllTargets()' exactly once.");
		}
		
		edgesUsed = true;
		
		outValue.f1 = m;
		
		while (edges.hasNext()) {
			Tuple next = (Tuple) edges.next();
			VertexKey k = next.getField(1);
			outValue.f0 = k;
			out.collect(outValue);
		}
	}
	
	/**
	 * Sends the given message to the vertex identified by the given key. If the target vertex does not exist,
	 * the next superstep will cause an exception due to a non-deliverable message.
	 * 
	 * @param target The key (id) of the target vertex to message.
	 * @param m The message.
	 */
	public void sendMessageTo(VertexKey target, Message m) {
		outValue.f0 = target;
		outValue.f1 = m;
		out.collect(outValue);
	}

	// --------------------------------------------------------------------------------------------
	
	/**
	 * Gets the number of the superstep, starting at 1.
	 * 
	 * @return The number of the current superstep.
	 */
	public int getSuperstepNumber() {
		return this.runtimeContext.getSuperstepNumber();
	}
	
	/**
	 * Gets the iteration aggregator registered under the given name. The iteration aggregator is combines
	 * all aggregates globally once per superstep and makes them available in the next superstep.
	 * 
	 * @param name The name of the aggregator.
	 * @return The aggregator registered under this name, or null, if no aggregator was registered.
	 */
	public > T getIterationAggregator(String name) {
		return this.runtimeContext.getIterationAggregator(name);
	}
	
	/**
	 * Get the aggregated value that an aggregator computed in the previous iteration.
	 * 
	 * @param name The name of the aggregator.
	 * @return The aggregated value of the previous iteration.
	 */
	public  T getPreviousIterationAggregate(String name) {
		return this.runtimeContext.getPreviousIterationAggregate(name);
	}
	
	/**
	 * Gets the broadcast data set registered under the given name. Broadcast data sets
	 * are available on all parallel instances of a function. They can be registered via
	 * {@link VertexCentricIteration#addBroadcastSetForMessagingFunction(String, org.apache.flink.api.java.DataSet)}.
	 * 
	 * @param name The name under which the broadcast set is registered.
	 * @return The broadcast data set.
	 */
	public  Collection getBroadcastSet(String name) {
		return this.runtimeContext.getBroadcastVariable(name);
	}

	// --------------------------------------------------------------------------------------------
	//  internal methods and state
	// --------------------------------------------------------------------------------------------
	
	private Tuple2 outValue;
	
	private IterationRuntimeContext runtimeContext;
	
	private Iterator edges;
	
	private Collector> out;
	
	private EdgesIteratorNoEdgeValue edgeNoValueIter;
	
	private EdgesIteratorWithEdgeValue edgeWithValueIter;
	
	private boolean edgesUsed;
	
	
	void init(IterationRuntimeContext context, boolean hasEdgeValue) {
		this.runtimeContext = context;
		this.outValue = new Tuple2();
		
		if (hasEdgeValue) {
			this.edgeWithValueIter = new EdgesIteratorWithEdgeValue();
		} else {
			this.edgeNoValueIter = new EdgesIteratorNoEdgeValue();
		}
	}
	
	void set(Iterator edges, Collector> out) {
		this.edges = edges;
		this.out = out;
		this.edgesUsed = false;
	}
	
	
	
	private static final class EdgesIteratorNoEdgeValue, EdgeValue> 
		implements Iterator>, Iterable>
	{
		private Iterator> input;
		
		private OutgoingEdge edge = new OutgoingEdge();
		
		
		void set(Iterator> input) {
			this.input = input;
		}
		
		@Override
		public boolean hasNext() {
			return input.hasNext();
		}

		@Override
		public OutgoingEdge next() {
			Tuple2 next = input.next();
			edge.set(next.f1, null);
			return edge;
		}

		@Override
		public void remove() {
			throw new UnsupportedOperationException();
		}

		@Override
		public Iterator> iterator() {
			return this;
		}
	}
	
	
	private static final class EdgesIteratorWithEdgeValue, EdgeValue> 
		implements Iterator>, Iterable>
	{
		private Iterator> input;
		
		private OutgoingEdge edge = new OutgoingEdge();
		
		void set(Iterator> input) {
			this.input = input;
		}
		
		@Override
		public boolean hasNext() {
			return input.hasNext();
		}

		@Override
		public OutgoingEdge next() {
			Tuple3 next = input.next();
			edge.set(next.f1, next.f2);
			return edge;
		}

		@Override
		public void remove() {
			throw new UnsupportedOperationException();
		}
		@Override
		public Iterator> iterator() {
			return this;
		}
	}
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy