package scs.demos.mapreduce.servant; import java.util.ArrayList; import java.util.Arrays; import java.util.Comparator; import org.omg.CORBA.Any; import org.omg.PortableServer.POA; import scs.demos.mapreduce.FileSplit; import scs.demos.mapreduce.IOFormat; import scs.demos.mapreduce.IOMapReduceException; import scs.demos.mapreduce.OutputCollector; import scs.demos.mapreduce.OutputCollectorHelper; import scs.demos.mapreduce.OutputCollectorPOA; import scs.demos.mapreduce.RecordWriter; import scs.demos.mapreduce.Reducer; import scs.demos.mapreduce.Reporter; import scs.demos.mapreduce.TaskStatus; import scs.demos.mapreduce.schedule.LogError; /** * Servant que implementa a interface OutputCollector usada * na operação map quanto o numero de reducers é maior que zero. */ public class BufferOutputCollectorServant extends OutputCollectorPOA { private Reporter reporter = null; private IOFormat ioformat = null; private FileSplit[] outputSplit = null; private String exception = null; private MapTask task = null; private PartitionerServant partitioner = null; private Reducer combiner = null; private RecordWriter[] out = null; private int numReducers = 0; private String configFileName = null; private POA poa = null; private class ObjToSort { public Any key; public Any value; public ObjToSort(Any key, Any value) { this.key = key; this.value = value; } public ObjToSort() { key = null; value = null; } } private class SortComparator implements Comparator { Comparator comp = null; public SortComparator(Comparator comp) { this.comp = comp; } public int compare(Object obj1,Object obj2) { ObjToSort o1 = (ObjToSort) obj1; ObjToSort o2 = (ObjToSort) obj2; return comp.compare((Object) o1.key,(Object) o2.key); } } private ArrayList<ObjToSort> [] segment = null; public BufferOutputCollectorServant(MapTask task) throws IOMapReduceException { try { this.task = task; this.reporter = task.getReporter(); this.ioformat = task.getIOFormat(); this.outputSplit = task.getOutput(); this.partitioner = task.getPartitioner(); this.combiner = task.getCombiner(); this.numReducers = task.getNumReducers(); this.configFileName = task.getConfigFileName(); this.poa = task.getPoa(); this.out = new RecordWriter[numReducers]; this.segment = new ArrayList[numReducers]; for (int i= 0; i < segment.length; i++) { segment[i] = null; } }catch (Exception e ) { exception = LogError.getStackTrace(e); reporter.report(0,"BufferOutputCollectorServant::BufferOutputCollectorServant - " + exception); throw new IOMapReduceException (); } } public void close() throws IOMapReduceException { try { if (this.out != null) { for (int i = 0; i < out.length;i++) { if (out[i] != null) { out[i].close(); } } } } catch (Exception e) { exception = LogError.getStackTrace(e); reporter.report(0,"BufferOutputCollectorServant::close - " + exception); throw new IOMapReduceException(); } } public void flush() throws IOMapReduceException { try { /* Ordena cada particao e grava arquivo de saida*/ SortComparator comparator = new SortComparator (partitioner.getPartitionComparator()); for(int i=0; i < outputSplit.length; i++) { if (segment[i] == null ) { out[i] = ioformat.getRecordWriter(TaskStatus.MAP); out[i].open(configFileName,outputSplit[i],reporter); out[i].close(); continue; } Object [] objArray = segment[i].toArray(); Arrays.sort(objArray, comparator); if (combiner == null) { out[i] = ioformat.getRecordWriter(TaskStatus.MAP); out[i].open(configFileName,outputSplit[i],reporter); for(int j=0; j < objArray.length; j++) { ObjToSort o = (ObjToSort) objArray[j]; out[i].write(o.key, o.value); } objArray = null; out[i].close(); } else { ObjToSort last = (ObjToSort) objArray[0]; ObjToSort current = null; ArrayList<Any> anyList = new ArrayList<Any> (); OutputCollector combineCollector = OutputCollectorHelper.narrow(poa.servant_to_reference( new DirectOutputCollectorServant(ioformat, reporter, outputSplit[i], configFileName,TaskStatus.MAP))); for(int j=0; j < objArray.length; j++) { current = (ObjToSort) objArray[j]; if (comparator.compare((Object)last,(Object)current)==0) { anyList.add(current.value); last = current; } else { Any[] values = new Any[anyList.size()]; anyList.toArray(values); combiner.reduce(combineCollector, reporter, null); values = null; anyList.clear(); anyList.add(current.value); last = current; } } if (anyList.size() > 0) { Any[] values = new Any[anyList.size()]; anyList.toArray(values); combiner.reduce(combineCollector, reporter, null); values = null; anyList.clear(); } objArray = null; combineCollector.flush(); combineCollector.close(); combineCollector = null; } //objArray = null; //out[i].close(); } } catch (Exception e) { exception = LogError.getStackTrace(e); reporter.report(0,"BufferOutputCollectorServant::flush - " + exception); throw new IOMapReduceException (); } } public void collect(Any key, Any value) throws IOMapReduceException { try{ ObjToSort objToSort = new ObjToSort(key, value); int index = partitioner.getPartition(objToSort.key,objToSort.value,numReducers); if (segment[index] == null) { segment[index] = new ArrayList<ObjToSort> (); } segment[index].add(objToSort); } catch (Exception e) { exception = LogError.getStackTrace(e); reporter.report(0,"BufferOutputCollectorServant::collect - " + exception); throw new IOMapReduceException (); } } }