int reduce = Integer.parseInt(reduceId);
byte[] buffer = new byte[MAX_BYTES_TO_READ];
// true iff IOException was caused by attempt to access input
boolean isInputException = true;
OutputStream outStream = null;
FSDataInputStream indexIn = null;
FSDataInputStream mapOutputIn = null;
ShuffleServerMetrics shuffleMetrics = (ShuffleServerMetrics)
context.getAttribute("shuffleServerMetrics");
try {
shuffleMetrics.serverHandlerBusy();
outStream = response.getOutputStream();
JobConf conf = (JobConf) context.getAttribute("conf");
LocalDirAllocator lDirAlloc =
(LocalDirAllocator)context.getAttribute("localDirAllocator");
FileSystem fileSys =
(FileSystem) context.getAttribute("local.file.system");
// Index file
Path indexFileName = lDirAlloc.getLocalPathToRead(
mapId+"/file.out.index", conf);
// Map-output file
Path mapOutputFileName = lDirAlloc.getLocalPathToRead(
mapId+"/file.out", conf);
/**
* Read the index file to get the information about where
* the map-output for the given reducer is available.
*/
//open index file
indexIn = fileSys.open(indexFileName);
//seek to the correct offset for the given reduce
indexIn.seek(reduce * 16);
//read the offset and length of the partition data
long startOffset = indexIn.readLong();
long partLength = indexIn.readLong();
indexIn.close();
indexIn = null;
//set the custom "Map-Output-Length" http header to
//the actual number of bytes being transferred
response.setHeader(MAP_OUTPUT_LENGTH, Long.toString(partLength));
//use the same buffersize as used for reading the data from disk
response.setBufferSize(MAX_BYTES_TO_READ);
/**
* Read the data from the sigle map-output file and
* send it to the reducer.
*/
//open the map-output file
mapOutputIn = fileSys.open(mapOutputFileName);
//seek to the correct offset for the reduce
mapOutputIn.seek(startOffset);
long totalRead = 0;
int len = mapOutputIn.read(buffer, 0,
partLength < MAX_BYTES_TO_READ
? (int)partLength : MAX_BYTES_TO_READ);
while (len > 0) {
try {
shuffleMetrics.outputBytes(len);
outStream.write(buffer, 0, len);
outStream.flush();
} catch (IOException ie) {
isInputException = false;
throw ie;
}
totalRead += len;
if (totalRead == partLength) break;
len = mapOutputIn.read(buffer, 0,
(partLength - totalRead) < MAX_BYTES_TO_READ
? (int)(partLength - totalRead) : MAX_BYTES_TO_READ);
}
} catch (IOException ie) {
TaskTracker tracker =
(TaskTracker) context.getAttribute("task.tracker");
Log log = (Log) context.getAttribute("log");
String errorMsg = ("getMapOutput(" + mapId + "," + reduceId +
") failed :\n"+
StringUtils.stringifyException(ie));
log.warn(errorMsg);
if (isInputException) {
tracker.mapOutputLost(mapId, errorMsg);
}
response.sendError(HttpServletResponse.SC_GONE, errorMsg);
shuffleMetrics.failedOutput();
throw ie;
} finally {
if (indexIn != null) {
indexIn.close();
}
if (mapOutputIn != null) {
mapOutputIn.close();
}
shuffleMetrics.serverHandlerFree();
}
outStream.close();
shuffleMetrics.successOutput();