Java tutorial
/* * Copyright (c) 2007-2010 Concurrent, Inc. All Rights Reserved. * * Project and contact information: http://www.cascading.org/ * * This file is part of the Cascading project. * * Cascading is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Cascading is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Cascading. If not, see <http://www.gnu.org/licenses/>. */ package cascading.flow.stack; import java.io.IOException; import java.util.HashMap; import java.util.Map; import cascading.flow.FlowCollector; import cascading.flow.FlowProcess; import cascading.flow.StepCounters; import cascading.flow.hadoop.HadoopFlowProcess; import cascading.tap.Tap; import cascading.tap.hadoop.TapCollector; import cascading.tuple.TupleEntry; import cascading.util.Util; import org.apache.hadoop.mapred.JobConf; import org.apache.log4j.Logger; /** Class StackElement is the base class for Map and Reduce operation stacks. */ abstract class StackElement implements FlowCollector { /** Field LOG */ private static final Logger LOG = Logger.getLogger(StackElement.class); private static Map<Tap, TapCollector> trapCollectors = new HashMap<Tap, TapCollector>(); final FlowProcess flowProcess; private String trapName; private final Tap trap; StackElement previous; StackElement next; private static TapCollector getTrapCollector(Tap trap, JobConf jobConf) { TapCollector trapCollector = trapCollectors.get(trap); if (trapCollector == null) { try { jobConf = new JobConf(jobConf); int id = jobConf.getInt("cascading.flow.step.id", 0); String partname; if (jobConf.getBoolean("mapred.task.is.map", true)) partname = String.format("-m-%05d-", id); else partname = String.format("-r-%05d-", id); jobConf.set("cascading.tapcollector.partname", "%s%spart" + partname + "%05d"); trapCollector = (TapCollector) trap.openForWrite(jobConf); trapCollectors.put(trap, trapCollector); } catch (IOException exception) { throw new StackException(exception); } } return trapCollector; } private static synchronized void closeTraps() { for (TapCollector trapCollector : trapCollectors.values()) { try { trapCollector.close(); } catch (Exception exception) { // do nothing } } trapCollectors.clear(); } public StackElement(FlowProcess flowProcess, String trapName, Tap trap) { this.flowProcess = flowProcess; this.trapName = trapName; this.trap = trap; } public StackElement resolveStack() { if (previous != null) return previous.setNext(this); return this; } StackElement setNext(StackElement next) { this.next = next; if (previous != null) return previous.setNext(this); return this; } public abstract void prepare(); public abstract void cleanup(); public FlowProcess getFlowProcess() { return flowProcess; } public JobConf getJobConf() { return ((HadoopFlowProcess) flowProcess).getJobConf(); } protected void handleException(Exception exception, TupleEntry tupleEntry) { handleException(trapName, trap, exception, tupleEntry); } protected void handleException(String trapName, Tap trap, Exception exception, TupleEntry tupleEntry) { if (exception instanceof StackException) throw (StackException) exception; if (trap == null) throw new StackException(exception); if (tupleEntry == null) { LOG.error("failure resolving tuple entry", exception); throw new StackException("failure resolving tuple entry", exception); } getTrapCollector(trap, getJobConf()).add(tupleEntry); getFlowProcess().increment(StepCounters.Tuples_Trapped, 1); LOG.warn("exception trap on branch: '" + trapName + "', for " + Util.truncate(print(tupleEntry), 75), exception); } private String print(TupleEntry tupleEntry) { if (tupleEntry == null || tupleEntry.getFields() == null) return "[uninitialized]"; else if (tupleEntry.getTuple() == null) return "fields: " + tupleEntry.getFields().printVerbose(); else return "fields: " + tupleEntry.getFields().printVerbose() + " tuple: " + tupleEntry.getTuple().print(); } public void open() throws IOException { prepare(); // ok if skipped, don't open resources if failing if (previous != null) previous.open(); } public void close() throws IOException { try { cleanup(); } finally { try { // close if top of stack if (next == null) closeTraps(); } finally { // need to try to close all open resources if (next != null) next.close(); } } } }