package org.apache.hadoop.hive.mastiff;
import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import org.apache.hadoop.io.Writable;
import cn.ac.ncic.mastiff.ValPair;
/**
* RowWritable is used to pass each record's data and
* query's metadata from {@link SegmentFileRecordReader} to {@link MastiffSerDe} <br/>
*
* Since we could not get selected column ids from conf in serde, the metadata
* of selected columns should be the workaround to get that from RecordReader.
* In order to pass the query's metadata, two kinds of RowWritable object are involved
* <ul>
* <li>The first record passed from recordReader, we fill the RowWritable with valid cf ids and
* valid columns along with the real data</li>
* <li>Other records except for first, only its data was set</li> </li>
*/
public class RowWritable implements Writable {
private byte isFirst; // first 1, others 0
private List<ValPair> vps;
private List<Integer> validCfs;
private List<Integer> validColumns;
public RowWritable() {
}
/**
* Set the data to be transported
*
* @param isFirst
* 1 for first record, 0 for the others
* @param curVps
* Current line's data
* @param validCfs
* Query's selected cf
* @param validColumns
* Query's selected columns
*/
public void set(byte isFirst, List<ValPair> curVps, List<Integer> validCfs,
List<Integer> validColumns) {
this.isFirst = isFirst;
vps = curVps;
if (validCfs != null) {
this.validCfs = validCfs;
}
if (validColumns != null) {
this.validColumns = validColumns;
}
}
/**
* First Record : <code>|1|num_cfs|num_columns|valid_cfs|valid_columns|real_data|</code> <br/>
* Other Records: <code>|0|num_cfs|real_data|</code>
*/
@Override
public void write(DataOutput out) throws IOException {
out.writeByte(isFirst);
out.writeInt(vps.size());
if (isFirst == 1) {
out.writeInt(validColumns.size());
for (int i = 0; i < validCfs.size(); i++) {
out.writeInt(validCfs.get(i));
}
for (int j = 0; j < validColumns.size(); j++) {
out.writeInt(validColumns.get(j));
}
}
for (int k = 0; k < vps.size(); k++) {
vps.get(k).write(out);
}
}
@Override
public void readFields(DataInput in) throws IOException {
isFirst = in.readByte();
int vpcount = in.readInt();
if (vps == null) {
vps = new ArrayList<ValPair>();
} else {
vps.clear();
}
if (isFirst == 1) { // first record
int clmcount = in.readInt();
validCfs = new ArrayList<Integer>();
validColumns = new ArrayList<Integer>();
for (int i = 0; i < vpcount; i++) {
validCfs.add(in.readInt());
}
for (int j = 0; j < clmcount; j++) {
validColumns.add(in.readInt());
}
}
for (int k = 0; k < vpcount; k++) {
ValPair curVp = new ValPair();
curVp.readFields(in);
vps.add(curVp);
}
}
public List<ValPair> getVps() {
return vps;
}
public List<Integer> getValidCfs() {
return validCfs;
}
public byte getIsFirst() {
return isFirst;
}
public List<Integer> getValidColumns() {
return validColumns;
}
}