eu.stratosphere.nephele.services.iomanager.HeaderlessChannelReaderInputView Maven / Gradle / Ivy
/***********************************************************************************************************************
* 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.services.iomanager;
import java.io.EOFException;
import java.io.IOException;
import java.util.List;
import eu.stratosphere.core.memory.MemorySegment;
/**
* A {@link DataInputView} that is backed by a {@link BlockChannelReader}, making it effectively a data input
* stream. This view is similar to the {@link ChannelReaderInputView}, but does not expect
* a header for each block, giving a direct stream abstraction over sequence of written
* blocks. It therefore requires specification of the number of blocks and the number of
* bytes in the last block.
*
*/
public class HeaderlessChannelReaderInputView extends ChannelReaderInputView
{
private int numBlocksRemaining; // the number of blocks not yet consumed
private final int lastBlockBytes; // the number of valid bytes in the last block
/**
* Creates a new channel reader that reads from the given channel, expecting a specified
* number of blocks in the channel, and returns only a specified number of bytes from
* the last block.
*
* WARNING: If the number of blocks given here is higher than the number of blocks in the
* channel, then the last blocks will not be filled by the reader and will contain
* undefined data.
*
* @param reader The reader that reads the data from disk back into memory.
* @param memory A list of memory segments that the reader uses for reading the data in. If the
* list contains more than one segment, the reader will asynchronously pre-fetch
* blocks ahead.
* @param numBlocks The number of blocks this channel will read.
* @param numBytesInLastBlock The number of valid bytes in the last block.
* @param waitForFirstBlock A flag indicating weather this constructor call should block
* until the first block has returned from the asynchronous I/O reader.
*
* @throws IOException Thrown, if the read requests for the first blocks fail to be
* served by the reader.
*/
public HeaderlessChannelReaderInputView(BlockChannelReader reader, List memory, int numBlocks,
int numBytesInLastBlock, boolean waitForFirstBlock)
throws IOException
{
super(reader, memory, numBlocks, 0, waitForFirstBlock);
this.numBlocksRemaining = numBlocks;
this.lastBlockBytes = numBytesInLastBlock;
}
@Override
protected MemorySegment nextSegment(MemorySegment current) throws IOException
{
// check for end-of-stream
if (this.numBlocksRemaining <= 0) {
this.reader.close();
throw new EOFException();
}
// send a request first. if we have only a single segment, this same segment will be the one obtained in
// the next lines
if (current != null) {
sendReadRequest(current);
}
// get the next segment
this.numBlocksRemaining--;
return this.reader.getNextReturnedSegment();
}
@Override
protected int getLimitForSegment(MemorySegment segment)
{
return this.numBlocksRemaining > 0 ? segment.size() : this.lastBlockBytes;
}
}