/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.pig.data; import java.io.DataInput; import java.io.DataOutput; import java.io.IOException; import java.util.Iterator; import org.apache.pig.PigException; import org.apache.pig.backend.executionengine.ExecException; import org.apache.pig.backend.hadoop.executionengine.physicalLayer.relationalOperators.Packager; import org.apache.pig.impl.io.NullableTuple; import org.apache.pig.impl.io.PigNullableWritable; /** * This bag does not store the tuples in memory, but has access to an iterator * typically provided by Hadoop. Use this when you already have an iterator over * tuples and do not want to copy over again to a new bag. */ public class ReadOnceBag implements DataBag { // The Packager that created this protected Packager pkgr; //The iterator of Tuples. Marked transient because we will never serialize this. protected transient Iterator<NullableTuple> tupIter; // The key being worked on protected PigNullableWritable keyWritable; /** * */ private static final long serialVersionUID = 2L; public ReadOnceBag() { } /** * This constructor creates a bag out of an existing iterator * of tuples by taking ownership of the iterator and NOT * copying the elements of the iterator. * @param pkg POPackageLite * @param tupIter Iterator<NullableTuple> * @param key Object */ public ReadOnceBag(Packager pkgr, Iterator<NullableTuple> tupIter, PigNullableWritable keyWritable) { this.pkgr = pkgr; this.tupIter = tupIter; this.keyWritable = keyWritable; } /* (non-Javadoc) * @see org.apache.pig.impl.util.Spillable#getMemorySize() */ @Override public long getMemorySize() { return 0; } /* (non-Javadoc) * @see org.apache.pig.impl.util.Spillable#spill() */ @Override public long spill() { throw new RuntimeException("ReadOnceBag does not support spill operation"); } /* (non-Javadoc) * @see org.apache.pig.data.DataBag#add(org.apache.pig.data.Tuple) */ @Override public void add(Tuple t) { throw new RuntimeException("ReadOnceBag does not support add operation"); } /* (non-Javadoc) * @see org.apache.pig.data.DataBag#addAll(org.apache.pig.data.DataBag) */ @Override public void addAll(DataBag b) { throw new RuntimeException("ReadOnceBag does not support addAll operation"); } /* (non-Javadoc) * @see org.apache.pig.data.DataBag#clear() */ @Override public void clear() { throw new RuntimeException("ReadOnceBag does not support clear operation"); } /* (non-Javadoc) * @see org.apache.pig.data.DataBag#isDistinct() */ @Override public boolean isDistinct() { throw new RuntimeException("ReadOnceBag does not support isDistinct operation"); } /* (non-Javadoc) * @see org.apache.pig.data.DataBag#isSorted() */ @Override public boolean isSorted() { throw new RuntimeException("ReadOnceBag does not support isSorted operation"); } /* (non-Javadoc) * @see org.apache.pig.data.DataBag#iterator() */ @Override public Iterator<Tuple> iterator() { return new ReadOnceBagIterator(); } /* (non-Javadoc) * @see org.apache.pig.data.DataBag#markStale(boolean) */ @Override public void markStale(boolean stale) { throw new RuntimeException("ReadOnceBag does not support markStale operation"); } /* (non-Javadoc) * @see org.apache.pig.data.DataBag#size() */ @Override public long size() { throw new RuntimeException("ReadOnceBag does not support size operation"); } /* (non-Javadoc) * @see org.apache.hadoop.io.Writable#readFields(java.io.DataInput) */ @Override public void readFields(DataInput in) throws IOException { throw new RuntimeException("ReadOnceBag does not support readFields operation"); } /* (non-Javadoc) * @see org.apache.hadoop.io.Writable#write(java.io.DataOutput) */ @Override public void write(DataOutput out) throws IOException { int errCode = 2142; String msg = "ReadOnceBag should never be serialized."; throw new ExecException(msg, errCode, PigException.BUG); } /* (non-Javadoc) * @see java.lang.Comparable#compareTo(java.lang.Object) * This has to be defined since DataBag implements * Comparable although, in this case we cannot really compare. */ @Override public int compareTo(Object o) { throw new RuntimeException("ReadOnceBags cannot be compared"); } @Override public boolean equals(Object other) { if (other instanceof ReadOnceBag) { if (pkgr.getKeyTuple()) { if (tupIter == ((ReadOnceBag) other).tupIter && pkgr.getKeyTuple() == ((ReadOnceBag) other).pkgr .getKeyTuple() && pkgr.getKeyAsTuple().equals( ((ReadOnceBag) other).pkgr.getKeyAsTuple())) { return true; } else { return false; } } else { if (tupIter == ((ReadOnceBag) other).tupIter && pkgr.getKey().equals( ((ReadOnceBag) other).pkgr.getKey())) { return true; } else { return false; } } } return false; } @Override public int hashCode() { int hash = 7; if (pkgr.getKeyTuple()) { hash = hash * 31 + pkgr.getKeyAsTuple().hashCode(); } else { hash = hash * 31 + pkgr.getKey().hashCode(); } return hash; } protected class ReadOnceBagIterator implements Iterator<Tuple> { /* (non-Javadoc) * @see java.util.Iterator#hasNext() */ @Override public boolean hasNext() { return tupIter.hasNext(); } /* (non-Javadoc) * @see java.util.Iterator#next() */ @Override public Tuple next() { NullableTuple ntup = tupIter.next(); int index = ntup.getIndex(); Tuple ret = null; try { ret = pkgr.getValueTuple(keyWritable, ntup, index); } catch (ExecException e) { throw new RuntimeException("ReadOnceBag failed to get value tuple : "+e.toString()); } return ret; } /* (non-Javadoc) * @see java.util.Iterator#remove() */ @Override public void remove() { throw new RuntimeException("ReadOnceBag.iterator().remove() is not allowed"); } } }