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

eu.stratosphere.nephele.io.RuntimeOutputGate Maven / Gradle / Ivy

There is a newer version: 0.5.2-hadoop2
Show newest version
/***********************************************************************************************************************
 * Copyright (C) 2010-2013 by the Stratosphere project (http://stratosphere.eu)
 *
 * Licensed 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 eu.stratosphere.nephele.io;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import eu.stratosphere.core.io.IOReadableWritable;
import eu.stratosphere.nephele.event.task.AbstractEvent;
import eu.stratosphere.nephele.io.channels.AbstractOutputChannel;
import eu.stratosphere.nephele.io.channels.ChannelID;
import eu.stratosphere.nephele.io.channels.ChannelType;
import eu.stratosphere.nephele.io.channels.bytebuffered.InMemoryOutputChannel;
import eu.stratosphere.nephele.io.channels.bytebuffered.NetworkOutputChannel;
import eu.stratosphere.nephele.jobgraph.JobID;

/**
 * In Nephele output gates are a specialization of general gates and connect
 * record writers and output channels. As channels, output gates are always
 * parameterized to a specific type of record which they can transport.
 * 

* This class is in general not thread-safe. * * @param * the type of record that can be transported through this gate */ public class RuntimeOutputGate extends AbstractGate implements OutputGate { /** * The log object used for debugging. */ private static final Log LOG = LogFactory.getLog(OutputGate.class); /** * The list of output channels attached to this gate. */ private final ArrayList> outputChannels = new ArrayList>(); /** * Channel selector to determine which channel is supposed receive the next record. */ private final ChannelSelector channelSelector; /** * The class of the record transported through this output gate. */ private final Class type; /** * Stores whether all records passed to this output gate shall be transmitted through all connected output channels. */ private final boolean isBroadcast; /** * Constructs a new runtime output gate. * * @param jobID * the ID of the job this input gate belongs to * @param gateID * the ID of the gate * @param inputClass * the class of the record that can be transported through this * gate * @param index * the index assigned to this output gate at the {@link Environment} object * @param channelSelector * the channel selector to be used for this output gate * @param isBroadcast * true if every records passed to this output gate shall be transmitted through all connected * output channels, false otherwise */ public RuntimeOutputGate(final JobID jobID, final GateID gateID, final Class inputClass, final int index, final ChannelSelector channelSelector, final boolean isBroadcast) { super(jobID, gateID, index); this.isBroadcast = isBroadcast; this.type = inputClass; if (this.isBroadcast) { this.channelSelector = null; } else { if (channelSelector == null) { this.channelSelector = new DefaultChannelSelector(); } else { this.channelSelector = channelSelector; } } } @Override public final Class getType() { return this.type; } /** * Adds a new output channel to the output gate. * * @param outputChannel * the output channel to be added. */ private void addOutputChannel(AbstractOutputChannel outputChannel) { if (!this.outputChannels.contains(outputChannel)) { this.outputChannels.add(outputChannel); } } /** * Removes the output channel with the given ID from the output gate if it * exists. * * @param outputChannelID * the ID of the channel to be removed */ public void removeOutputChannel(ChannelID outputChannelID) { for (int i = 0; i < this.outputChannels.size(); i++) { final AbstractOutputChannel outputChannel = this.outputChannels.get(i); if (outputChannel.getID().equals(outputChannelID)) { this.outputChannels.remove(i); return; } } LOG.debug("Cannot find output channel with ID " + outputChannelID + " to remove"); } /** * Removes all output channels from the output gate. */ public void removeAllOutputChannels() { this.outputChannels.clear(); } @Override public boolean isInputGate() { return false; } @Override public int getNumberOfOutputChannels() { return this.outputChannels.size(); } /** * Returns the output channel from position pos of the gate's * internal channel list. * * @param pos * the position to retrieve the channel from * @return the channel from the given position or null if such * position does not exist. */ public AbstractOutputChannel getOutputChannel(int pos) { if (pos < this.outputChannels.size()) { return this.outputChannels.get(pos); } else { return null; } } @Override public NetworkOutputChannel createNetworkOutputChannel(final OutputGate outputGate, final ChannelID channelID, final ChannelID connectedChannelID) { final NetworkOutputChannel enoc = new NetworkOutputChannel(outputGate, this.outputChannels.size(), channelID, connectedChannelID); addOutputChannel(enoc); return enoc; } @Override public InMemoryOutputChannel createInMemoryOutputChannel(final OutputGate outputGate, final ChannelID channelID, final ChannelID connectedChannelID) { final InMemoryOutputChannel einoc = new InMemoryOutputChannel(outputGate, this.outputChannels.size(), channelID, connectedChannelID); addOutputChannel(einoc); return einoc; } @Override public void requestClose() throws IOException, InterruptedException { // Close all output channels for (int i = 0; i < this.getNumberOfOutputChannels(); i++) { final AbstractOutputChannel outputChannel = this.getOutputChannel(i); outputChannel.requestClose(); } } @Override public boolean isClosed() throws IOException, InterruptedException { boolean allClosed = true; for (int i = 0; i < this.getNumberOfOutputChannels(); i++) { final AbstractOutputChannel outputChannel = this.getOutputChannel(i); if (!outputChannel.isClosed()) { allClosed = false; } } return allClosed; } @Override public void writeRecord(final T record) throws IOException, InterruptedException { if (this.isBroadcast) { if (getChannelType() == ChannelType.INMEMORY) { final int numberOfOutputChannels = this.outputChannels.size(); for (int i = 0; i < numberOfOutputChannels; ++i) { this.outputChannels.get(i).writeRecord(record); } } else { // Use optimization for byte buffered channels this.outputChannels.get(0).writeRecord(record); } } else { // Non-broadcast gate, use channel selector to select output channels final int numberOfOutputChannels = this.outputChannels.size(); final int[] selectedOutputChannels = this.channelSelector.selectChannels(record, numberOfOutputChannels); if (selectedOutputChannels == null) { return; } for (int i = 0; i < selectedOutputChannels.length; ++i) { if (selectedOutputChannels[i] < numberOfOutputChannels) { final AbstractOutputChannel outputChannel = this.outputChannels.get(selectedOutputChannels[i]); outputChannel.writeRecord(record); } } } } @Override public List> getOutputChannels() { return this.outputChannels; } @Override public String toString() { return "Output " + super.toString(); } @Override public void publishEvent(AbstractEvent event) throws IOException, InterruptedException { // Copy event to all connected channels final Iterator> it = this.outputChannels.iterator(); while (it.hasNext()) { it.next().transferEvent(event); } } @Override public void flush() throws IOException, InterruptedException { // Flush all connected channels final Iterator> it = this.outputChannels.iterator(); while (it.hasNext()) { it.next().flush(); } } @Override public boolean isBroadcast() { return this.isBroadcast; } @Override public ChannelSelector getChannelSelector() { return this.channelSelector; } @Override public void releaseAllChannelResources() { final Iterator> it = this.outputChannels.iterator(); while (it.hasNext()) { it.next().releaseAllResources(); } } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy