/* * 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.tuple; import java.io.DataInputStream; import java.io.IOException; import java.io.InputStream; import java.util.Comparator; import java.util.List; import cascading.tuple.hadoop.TupleSerialization; import org.apache.hadoop.io.WritableUtils; import org.apache.log4j.Logger; /** Class TupleInputStream is used internally to read Tuples from storage. */ public class TupleInputStream extends DataInputStream { /** Field LOG */ private static final Logger LOG = Logger.getLogger( TupleInputStream.class ); InputStream inputStream; ElementReader elementReader; public interface ElementReader { Object read( int token, DataInputStream inputStream ) throws IOException; Comparator getComparatorFor( int type, DataInputStream inputStream ) throws IOException; void close(); } public TupleInputStream( InputStream inputStream, ElementReader elementReader ) { super( inputStream ); this.inputStream = inputStream; this.elementReader = elementReader; } public TupleInputStream( InputStream inputStream ) { super( inputStream ); this.inputStream = inputStream; this.elementReader = new TupleSerialization().getElementReader(); } public InputStream getInputStream() { return inputStream; } public Tuple readTuple() throws IOException { return readTuple( new Tuple() ); } public Tuple readTuple( Tuple tuple ) throws IOException { List<Object> elements = Tuple.elements( tuple ); elements.clear(); int len = getNumElements(); for( int i = 0; i < len; i++ ) elements.add( getNextElement() ); return tuple; } public int getNumElements() throws IOException { return readVInt(); } public int readToken() throws IOException { return readVInt(); } public Object getNextElement() throws IOException { return readType( readToken() ); } public TuplePair readTuplePair() throws IOException { return readTuplePair( new TuplePair() ); } public TuplePair readTuplePair( TuplePair tuplePair ) throws IOException { Tuple[] tuples = TuplePair.tuples( tuplePair ); readTuple( tuples[ 0 ] ); // guaranteed to not be null readTuple( tuples[ 1 ] ); // guaranteed to not be null return tuplePair; } public IndexTuple readIndexTuple() throws IOException { return readIndexTuple( new IndexTuple() ); } public IndexTuple readIndexTuple( IndexTuple indexTuple ) throws IOException { indexTuple.setIndex( readVInt() ); indexTuple.setTuple( readTuple() ); return indexTuple; } public long readVLong() throws IOException { return WritableUtils.readVLong( this ); } public int readVInt() throws IOException { return WritableUtils.readVInt( this ); } public String readString() throws IOException { return WritableUtils.readString( this ); } private final Object readType( int type ) throws IOException { switch( type ) { case 0: return null; case 1: return readString(); case 2: return readFloat(); case 3: return readDouble(); case 4: return readVInt(); case 5: return readVLong(); case 6: return readBoolean(); case 7: return readShort(); case 8: return readTuple(); case 9: return readTuplePair(); case 10: return readIndexTuple(); default: return elementReader.read( type, this ); } } public Comparator getComparatorFor( int type ) throws IOException { if( type >= 0 && type <= 10 ) return null; return elementReader.getComparatorFor( type, this ); } @Override public void close() throws IOException { if( LOG.isDebugEnabled() ) LOG.debug( "closing tuple input stream" ); try { super.close(); } finally { if( elementReader != null ) elementReader.close(); } } }