use of com.tdunning.plume.local.lazy.op.ParallelDo in project Plume by tdunning.
the class LocalExecutor method execute.
/**
* Execute one-output flow
*
* @param <T>
* @param output
* @return
*/
@SuppressWarnings({ "unchecked", "rawtypes" })
public <T> Iterable<T> execute(LazyCollection<T> output) {
if (output.isMaterialized()) {
// nothing else to execute
return output.getData();
} else {
DeferredOp op = output.getDeferredOp();
final List<T> result = Lists.newArrayList();
// Flatten op
if (op instanceof Flatten) {
Flatten<T> flatten = (Flatten<T>) op;
for (PCollection<T> col : flatten.getOrigins()) {
Iterable<T> res = execute((LazyCollection<T>) col);
result.addAll(Lists.newArrayList(res));
}
// done with it
return result;
}
Iterable parent;
EmitFn<T> emitter = new EmitFn<T>() {
@Override
public void emit(T v) {
result.add(v);
}
};
// ParallelDo
if (op instanceof ParallelDo) {
ParallelDo pDo = (ParallelDo) op;
parent = execute((LazyCollection) pDo.getOrigin());
for (Object obj : parent) {
pDo.getFunction().process(obj, emitter);
}
// MultipleParallelDo -> parallel operations that read the same collection
// In this version of executor, we will only compute the current collection, not its neighbors
} else if (op instanceof MultipleParallelDo) {
MultipleParallelDo mPDo = (MultipleParallelDo) op;
parent = execute((LazyCollection) mPDo.getOrigin());
// get the function that corresponds to this collection
DoFn function = (DoFn) mPDo.getDests().get(output);
for (Object obj : parent) {
function.process(obj, emitter);
}
// GroupByKey
} else if (op instanceof GroupByKey) {
GroupByKey gBK = (GroupByKey) op;
parent = execute(gBK.getOrigin());
Map<Object, List> groupMap = Maps.newHashMap();
// Perform in-memory group by operation
for (Object obj : parent) {
Pair p = (Pair) obj;
List list = groupMap.get(p.getKey());
if (list == null) {
list = new ArrayList();
}
list.add(p.getValue());
groupMap.put(p.getKey(), list);
}
for (Map.Entry<Object, List> entry : groupMap.entrySet()) {
result.add((T) new Pair(entry.getKey(), entry.getValue()));
}
}
return result;
}
}
use of com.tdunning.plume.local.lazy.op.ParallelDo in project Plume by tdunning.
the class MSCRReducer method reduce.
@SuppressWarnings("unchecked")
protected void reduce(final PlumeObject arg0, java.lang.Iterable<PlumeObject> values, Reducer<PlumeObject, PlumeObject, NullWritable, NullWritable>.Context<PlumeObject, PlumeObject, NullWritable, NullWritable> arg2) throws IOException, InterruptedException {
PCollection col = mscr.getChannelByNumber().get(arg0.sourceId);
OutputChannel oC = mscr.getOutputChannels().get(col);
if (oC.reducer != null) {
// apply reducer
ParallelDo pDo = oC.reducer;
// TODO how to check / report this
DoFn reducer = pDo.getFunction();
List<WritableComparable> vals = Lists.newArrayList();
for (PlumeObject val : values) {
vals.add(val.obj);
}
reducer.process(Pair.create(arg0.obj, vals), new EmitFn() {
@Override
public void emit(Object v) {
try {
if (v instanceof Pair) {
Pair p = (Pair) v;
mos.write(arg0.sourceId + "", p.getKey(), p.getValue());
} else {
mos.write(arg0.sourceId + "", NullWritable.get(), (WritableComparable) v);
}
} catch (Exception e) {
// TODO How to report this
e.printStackTrace();
}
}
});
} else {
// direct writing - write all key, value pairs
for (PlumeObject val : values) {
if (oC.output instanceof PTable) {
mos.write(arg0.sourceId + "", arg0.obj, val.obj);
} else {
mos.write(arg0.sourceId + "", NullWritable.get(), val.obj);
}
}
}
}
use of com.tdunning.plume.local.lazy.op.ParallelDo in project Plume by tdunning.
the class Optimizer method fuseParallelDos.
/**
* Fuse producer-consumer ParallelDos as in : {Orig2 => p2 => Orig1 => p1 => Output} to {Orig2 => p1(p2) => Output}
* @param arg The collection that may have compositions internally.
*/
@SuppressWarnings({ "unchecked", "rawtypes" })
<T> void fuseParallelDos(PCollection<T> arg) {
LazyCollection<T> output = (LazyCollection<T>) arg;
if (output.isMaterialized()) {
// stop condition for recursive algorithm
return;
}
DeferredOp dOp = output.getDeferredOp();
if (!(dOp instanceof ParallelDo)) {
// not a ParallelDo
if (dOp instanceof OneToOneOp) {
// Recursively apply this function to parent
fuseParallelDos(((OneToOneOp) dOp).getOrigin());
return;
}
if (dOp instanceof Flatten) {
Flatten<T> flatten = (Flatten) dOp;
// Recursively apply this function to all parents
for (PCollection<T> col : flatten.getOrigins()) {
fuseParallelDos(col);
}
return;
}
}
ParallelDo p1 = (ParallelDo) output.getDeferredOp();
LazyCollection orig1 = (LazyCollection) p1.getOrigin();
if (orig1.isMaterialized()) {
return;
}
if (!(orig1.getDeferredOp() instanceof ParallelDo)) {
// Recursively apply this function to parent node
fuseParallelDos(orig1);
return;
}
// At this point we know ParallelDo fusion can be done -> Perform it
ParallelDo p2 = (ParallelDo) orig1.getDeferredOp();
// Lift combine values
if (p2 instanceof CombineValues) {
LazyCollection lCol = (LazyCollection) p2.getOrigin();
if (!lCol.isMaterialized() && lCol.getDeferredOp() instanceof GroupByKey) {
// Upper parallel do is CombineValues and follows a GroupByKey -> don't join
fuseParallelDos(orig1);
return;
}
}
final DoFn f1 = p1.getFunction();
final DoFn f2 = p2.getFunction();
// Define the joined function
DoFn newFn = new DoFn() {
@Override
public void process(Object v, final EmitFn emitter) {
f2.process(v, new EmitFn() {
@Override
public void emit(Object v) {
f1.process(v, emitter);
}
});
}
};
LazyCollection orig2 = (LazyCollection) p2.getOrigin();
ParallelDo newPDo = new ParallelDo(newFn, orig2, output);
// Clean & change pointers
orig2.downOps.remove(p2);
orig1.downOps.remove(p1);
orig2.addDownOp(newPDo);
output.deferredOp = newPDo;
// Recursively apply this function to the same node => TODO Beware infinite recursion, properly test
fuseParallelDos(output);
}
use of com.tdunning.plume.local.lazy.op.ParallelDo in project Plume by tdunning.
the class Optimizer method fuseSiblingParallelDos.
/**
* Join ParallelDos that use the same PCollection into multiple-output {@link MultipleParallelDo}
* @param arg The original collection that may contain sibling do chains
*/
@SuppressWarnings({ "unchecked", "rawtypes" })
<T> void fuseSiblingParallelDos(PCollection<T> arg) {
LazyCollection<T> output = (LazyCollection<T>) arg;
if (output.isMaterialized()) {
// stop condition for recursive algorithm
return;
}
DeferredOp dOp = output.getDeferredOp();
if (!(dOp instanceof ParallelDo)) {
// not a ParallelDo
if (dOp instanceof OneToOneOp) {
// Recursively apply this function to parent
fuseSiblingParallelDos(((OneToOneOp) dOp).getOrigin());
return;
}
if (dOp instanceof Flatten) {
Flatten<T> flatten = (Flatten) dOp;
// Recursively apply this function to all parents
for (PCollection<T> col : flatten.getOrigins()) {
fuseSiblingParallelDos(col);
}
return;
}
if (dOp instanceof MultipleParallelDo) {
return;
}
}
ParallelDo pDo = (ParallelDo) output.getDeferredOp();
LazyCollection<T> orig = (LazyCollection<T>) pDo.getOrigin();
int willAdd = 0;
for (DeferredOp op : orig.getDownOps()) {
if (op instanceof ParallelDo) {
willAdd++;
}
}
if (willAdd == 1) {
// Parent doesn't have more ParallelDos to fuse
// Recursively apply this function to parent
fuseSiblingParallelDos(orig);
return;
}
// MultipleParallelDo is viable, create it
MultipleParallelDo<T> mPDo = new MultipleParallelDo<T>(orig);
mPDo.addDest(pDo.getFunction(), output);
orig.downOps.remove(pDo);
output.deferredOp = mPDo;
List<DeferredOp> newList = new ArrayList<DeferredOp>();
for (DeferredOp op : orig.getDownOps()) {
if (op instanceof ParallelDo) {
ParallelDo thisPDo = (ParallelDo) op;
mPDo.addDest(thisPDo.getFunction(), thisPDo.getDest());
LazyCollection thisDest = (LazyCollection) thisPDo.getDest();
thisDest.deferredOp = mPDo;
} else {
newList.add(op);
}
}
newList.add(mPDo);
orig.downOps = newList;
// Recursively apply this function to parent
fuseSiblingParallelDos(orig);
}
Aggregations