// Path: src/org/apache/hadoop/fs/FSDataOutputStream.java
// public class FSDataOutputStream extends DataOutputStream implements Syncable {
//   private OutputStream wrappedStream;
// 
//   private static class PositionCache extends FilterOutputStream {
//     private FileSystem.Statistics statistics;
//     long position;
// 
//     public PositionCache(OutputStream out, 
//                          FileSystem.Statistics stats,
//                          long pos) throws IOException {
//       super(out);
//       statistics = stats;
//       position = pos;
//     }
// 
//     public void write(int b) throws IOException {
//       out.write(b);
//       position++;
//       if (statistics != null) {
//         statistics.incrementBytesWritten(1);
//       }
//     }
//     
//     public void write(byte b[], int off, int len) throws IOException {
//       out.write(b, off, len);
//       position += len;                            // update position
//       if (statistics != null) {
//         statistics.incrementBytesWritten(len);
//       }
//     }
//       
//     public long getPos() throws IOException {
//       return position;                            // return cached position
//     }
//     
//     public void close() throws IOException {
//       out.close();
//     }
//   }
// 
//   @Deprecated
//   public FSDataOutputStream(OutputStream out) throws IOException {
//     this(out, null);
//   }
// 
//   public FSDataOutputStream(OutputStream out, FileSystem.Statistics stats)
//     throws IOException {
//     this(out, stats, 0);
//   }
// 
//   public FSDataOutputStream(OutputStream out, FileSystem.Statistics stats,
//                             long startPosition) throws IOException {
//     super(new PositionCache(out, stats, startPosition));
//     wrappedStream = out;
//   }
//   
//   public long getPos() throws IOException {
//     return ((PositionCache)out).getPos();
//   }
// 
//   public void close() throws IOException {
//     out.close();         // This invokes PositionCache.close()
//   }
// 
//   // Returns the underlying output stream. This is used by unit tests.
//   public OutputStream getWrappedStream() {
//     return wrappedStream;
//   }
// 
//   /** {@inheritDoc} */
//   public void sync() throws IOException {
//     if (wrappedStream instanceof Syncable) {
//       ((Syncable)wrappedStream).sync();
//     }
//   }
// }
// 
// Path: src/org/apache/hadoop/mapred/CachePool.java
// public static class CachePoolFullException extends IOException {
// 	CachePoolFullException(String s) {
// 		super(s);
// 	}
// }	
// 
// Path: src/org/apache/hadoop/mapred/CachePool.java
// public static class CacheUnit extends ByteArrayInputStream {		
// 	static int cap = 0;		
// 	private boolean isLast = false;
// 	public CacheUnit() {			
// 		super(new byte[cap]);			
// 		count = 0;
// 	}
// 	public int write(InputStream in) throws IOException {
// 		if (count >= buf.length) {
// 			return 0;
// 		}
// 		int res = in.read(buf, count, buf.length - count);
// 		if (res < 0) {
// 			return res;
// 		}
// 		count += res;
// 		return res;
// 	}
// 	public int write(byte b[], int off, int len){
// 		len = Math.min(len, buf.length - count);			
// 		System.arraycopy(b, off, buf, count, len);
// 		count += len;
// 		return len;
// 	}
// 	public void writeFile(OutputStream out) throws IOException {
// 		out.write(buf, mark, count);
// 	}
// 	public boolean write(int b){
// 		if (count >= buf.length) {
// 		    return false;
// 		}
// 		buf[count++] = (byte)b;
// 		return true;
//   }		
// 	public int getPos() {
// 		return pos;
// 	}
// 	public int getLen() {
// 		return count;
// 	}
// 	public void reinit(){
// 		count = 0;
// 		mark = 0;
// 		pos = 0;			
// 		isLast = false;
// 	}
// 	public boolean isLast() {
// 		return isLast;
// 	}
// 	public void setLast() {
// 		isLast = true;
// 	}
// }


import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.hadoop.fs.FSDataOutputStream;
import org.apache.hadoop.mapred.CachePool.CachePoolFullException;
import org.apache.hadoop.mapred.CachePool.CacheUnit;
	private static long DEFAULTRLENGTH = 0;
	private long rlen = 0;
	
	CacheFile(CachePool p, long rlength) throws IOException {
		this(p, rlength, null, false, null, -1);				
	}
	CacheFile(CachePool p, long rlength, FSDataOutputStream out, boolean asyn, 
			TaskAttemptID tid, int priority) throws IOException{
		if (rlength != DEFAULTRLENGTH) {
			rlength = size2Cap(rlength);
			content = new ArrayList<CacheUnit>((int)(rlength / CacheUnit.cap) + 1);
			rcontent = new ArrayList<CacheUnit>((int)(rlength / CacheUnit.cap) + 1);
			rcontent.addAll(p.getUnits((int)(rlength/CacheUnit.cap)));
		} else {
			content = new LinkedList<CacheUnit>();
			rcontent = new LinkedList<CacheUnit>();
		}		
		rlen = rlength;
		pool = p;
		output = out;		
		taskid = tid;		
	}
	private CacheUnit getUnit() throws CachePoolFullException {
		if (rcontent.size() != 0) {
			return rcontent.remove(0);
		} else {
			rlen += CacheUnit.cap;
			return pool.getUnit();
		}		
	}
// Path: src/org/apache/hadoop/fs/FSDataOutputStream.java
// public class FSDataOutputStream extends DataOutputStream implements Syncable {
//   private OutputStream wrappedStream;
// 
//   private static class PositionCache extends FilterOutputStream {
//     private FileSystem.Statistics statistics;
//     long position;
// 
//     public PositionCache(OutputStream out, 
//                          FileSystem.Statistics stats,
//                          long pos) throws IOException {
//       super(out);
//       statistics = stats;
//       position = pos;
//     }
// 
//     public void write(int b) throws IOException {
//       out.write(b);
//       position++;
//       if (statistics != null) {
//         statistics.incrementBytesWritten(1);
//       }
//     }
//     
//     public void write(byte b[], int off, int len) throws IOException {
//       out.write(b, off, len);
//       position += len;                            // update position
//       if (statistics != null) {
//         statistics.incrementBytesWritten(len);
//       }
//     }
//       
//     public long getPos() throws IOException {
//       return position;                            // return cached position
//     }
//     
//     public void close() throws IOException {
//       out.close();
//     }
//   }
// 
//   @Deprecated
//   public FSDataOutputStream(OutputStream out) throws IOException {
//     this(out, null);
//   }
// 
//   public FSDataOutputStream(OutputStream out, FileSystem.Statistics stats)
//     throws IOException {
//     this(out, stats, 0);
//   }
// 
//   public FSDataOutputStream(OutputStream out, FileSystem.Statistics stats,
//                             long startPosition) throws IOException {
//     super(new PositionCache(out, stats, startPosition));
//     wrappedStream = out;
//   }
//   
//   public long getPos() throws IOException {
//     return ((PositionCache)out).getPos();
//   }
// 
//   public void close() throws IOException {
//     out.close();         // This invokes PositionCache.close()
//   }
// 
//   // Returns the underlying output stream. This is used by unit tests.
//   public OutputStream getWrappedStream() {
//     return wrappedStream;
//   }
// 
//   /** {@inheritDoc} */
//   public void sync() throws IOException {
//     if (wrappedStream instanceof Syncable) {
//       ((Syncable)wrappedStream).sync();
//     }
//   }
// }
// 
// Path: src/org/apache/hadoop/mapred/CachePool.java
// public static class CachePoolFullException extends IOException {
// 	CachePoolFullException(String s) {
// 		super(s);
// 	}
// }	
// 
// Path: src/org/apache/hadoop/mapred/CachePool.java
// public static class CacheUnit extends ByteArrayInputStream {		
// 	static int cap = 0;		
// 	private boolean isLast = false;
// 	public CacheUnit() {			
// 		super(new byte[cap]);			
// 		count = 0;
// 	}
// 	public int write(InputStream in) throws IOException {
// 		if (count >= buf.length) {
// 			return 0;
// 		}
// 		int res = in.read(buf, count, buf.length - count);
// 		if (res < 0) {
// 			return res;
// 		}
// 		count += res;
// 		return res;
// 	}
// 	public int write(byte b[], int off, int len){
// 		len = Math.min(len, buf.length - count);			
// 		System.arraycopy(b, off, buf, count, len);
// 		count += len;
// 		return len;
// 	}
// 	public void writeFile(OutputStream out) throws IOException {
// 		out.write(buf, mark, count);
// 	}
// 	public boolean write(int b){
// 		if (count >= buf.length) {
// 		    return false;
// 		}
// 		buf[count++] = (byte)b;
// 		return true;
//   }		
// 	public int getPos() {
// 		return pos;
// 	}
// 	public int getLen() {
// 		return count;
// 	}
// 	public void reinit(){
// 		count = 0;
// 		mark = 0;
// 		pos = 0;			
// 		isLast = false;
// 	}
// 	public boolean isLast() {
// 		return isLast;
// 	}
// 	public void setLast() {
// 		isLast = true;
// 	}
// }


// Path: src/org/apache/hadoop/mapred/CacheFile.java
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.hadoop.fs.FSDataOutputStream;
import org.apache.hadoop.mapred.CachePool.CachePoolFullException;
import org.apache.hadoop.mapred.CachePool.CacheUnit;

	private static long DEFAULTRLENGTH = 0;
	private long rlen = 0;
	
	CacheFile(CachePool p, long rlength) throws IOException {
		this(p, rlength, null, false, null, -1);				
	}
	CacheFile(CachePool p, long rlength, FSDataOutputStream out, boolean asyn, 
			TaskAttemptID tid, int priority) throws IOException{
		if (rlength != DEFAULTRLENGTH) {
			rlength = size2Cap(rlength);
			content = new ArrayList<CacheUnit>((int)(rlength / CacheUnit.cap) + 1);
			rcontent = new ArrayList<CacheUnit>((int)(rlength / CacheUnit.cap) + 1);
			rcontent.addAll(p.getUnits((int)(rlength/CacheUnit.cap)));
		} else {
			content = new LinkedList<CacheUnit>();
			rcontent = new LinkedList<CacheUnit>();
		}		
		rlen = rlength;
		pool = p;
		output = out;		
		taskid = tid;		
	}
	private CacheUnit getUnit() throws CachePoolFullException {
		if (rcontent.size() != 0) {
			return rcontent.remove(0);
		} else {
			rlen += CacheUnit.cap;
			return pool.getUnit();
		}		
	}
	public void write(byte b[], int off, int length) throws CachePoolFullException, InterruptedException {