/*
* 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.POPackageLite;
import org.apache.pig.impl.io.NullableTuple;
/**
* This bag is specifically created for use by POPackageLite. So it has three
* properties, the NullableTuple iterator, the key (Object) and the keyInfo
* (Map<Integer, Pair<Boolean, Map<Integer, Integer>>>) all three
* of which are required in the constructor call. 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 Package operator that created this
POPackageLite pkg;
//The iterator of Tuples. Marked transient because we will never serialize this.
transient Iterator<NullableTuple> tupIter;
// The key being worked on
Object key;
/**
*
*/
private static final long serialVersionUID = 2L;
/**
* 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(POPackageLite pkg, Iterator<NullableTuple> tupIter, Object key) {
this.pkg = pkg;
this.tupIter = tupIter;
this.key = key;
}
/* (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(pkg.getKeyTuple())
{
if(tupIter == ((ReadOnceBag)other).tupIter && pkg.getKeyTuple() == ((ReadOnceBag)other).pkg.getKeyTuple() && pkg.getKeyAsTuple().equals(((ReadOnceBag)other).pkg.getKeyAsTuple()))
{
return true;
}
else
{
return false;
}
}
else
{
if(tupIter == ((ReadOnceBag)other).tupIter && pkg.getKey().equals(((ReadOnceBag)other).pkg.getKey()))
{
return true;
}
else
{
return false;
}
}
}
return false;
}
@Override
public int hashCode() {
int hash = 7;
if(pkg.getKeyTuple())
{
hash = hash*31 + pkg.getKeyAsTuple().hashCode();
}
else
{
hash = hash*31 + pkg.getKey().hashCode();
}
return hash;
}
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 = pkg.getValueTuple(ntup, index, key);
} 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");
}
}
}