com.toshiba.mwcloud.gs.hadoop.io.GSRowWritable.java Source code

Java tutorial

Introduction

Here is the source code for com.toshiba.mwcloud.gs.hadoop.io.GSRowWritable.java

Source

/*
   Copyright (c) 2016 TOSHIBA CORPORATION.
    
   Licensed 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 com.toshiba.mwcloud.gs.hadoop.io;

import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;

import java.sql.Blob;
import java.sql.SQLException;
import javax.sql.rowset.serial.SerialBlob;

import java.util.Date;

import org.apache.hadoop.io.Writable;
import org.apache.hadoop.io.VIntWritable;
import org.apache.hadoop.io.VLongWritable;

import com.toshiba.mwcloud.gs.ContainerInfo;
import com.toshiba.mwcloud.gs.GSException;
import com.toshiba.mwcloud.gs.GSType;
import com.toshiba.mwcloud.gs.Row;

/**
 * <div lang="ja">
 * GridDB?RowWritable??<br/>
 * GSRowRecordReader????Map???????<br/>
 * ???MapReduce?GridDB???????????<br/>
 * ?????????????????(GSType[])?? ????
 * </div><div lang="en">
 * Writable for Row object of GridDB generated by GSRowRecordReader and handed over as an input value to the Map task.<br/>
 * In addition, this class is used when a MapReduce job outputs data to GridDB as well.<br/>
 * In this case, assign a column-type array (GSType[]) matching the schema of the container of the output destination to generate the object.
 * </div>
 */
public class GSRowWritable implements Writable {
    protected Object[] values_;
    protected GSType[] types_;

    protected static final byte BLOB = 0x01;
    protected static final byte BOOL = 0x02;
    protected static final byte BYTE = 0x03;
    protected static final byte DOUBLE = 0x04;
    protected static final byte FLOAT = 0x05;
    protected static final byte INTEGER = 0x06;
    protected static final byte LONG = 0x07;
    protected static final byte SHORT = 0x08;
    protected static final byte STRING = 0x09;
    protected static final byte TIMESTAMP = 0x0a;
    protected static final byte BOOL_ARRAY = 0x12;
    protected static final byte BYTE_ARRAY = 0x13;
    protected static final byte DOUBLE_ARRAY = 0x14;
    protected static final byte FLOAT_ARRAY = 0x15;
    protected static final byte INTEGER_ARRAY = 0x16;
    protected static final byte LONG_ARRAY = 0x17;
    protected static final byte SHORT_ARRAY = 0x18;
    protected static final byte STRING_ARRAY = 0x19;
    protected static final byte TIMESTAMP_ARRAY = 0x1a;

    public GSRowWritable() {
    }

    /**
     * <div lang="ja">
     * ?????
     * @param types ??
     * </div><div lang="en">
     * Generate an empty object.
     * @param types column type array
     * </div>
     */
    public GSRowWritable(GSType[] types) {
        values_ = new Object[types.length];
        types_ = new GSType[types.length];
        for (int i = 0; i < types.length; i++) {
            types_[i] = types[i];
        }
    }

    /**
     * <div lang="ja">
     * ???????
     * @param columnIndex ?(0???)
     * @return 
     * </div><div lang="en">
     * Return the value of the specified column number.
     * @param columnIndex column number (a value of 0 or higher and less than the number of columns)
     * @return column value
     * </div>
     */
    public Object getValue(int columnIndex) {
        return values_[columnIndex];
    }

    /**
     * <div lang="ja">
     * ????
     * @param row ???????GridDB?Row
     * @throws GSException GridDB??????
     * </div><div lang="en">
     * Return the values of all columns.
     * @param row GridDB Row object for setting the acquired value
     * @throws GSException an exception occurred in Row object
     * </div>
     */
    public void getValues(Row row) throws GSException {
        for (int i = 0; i < values_.length; i++) {
            row.setValue(i, values_[i]);
        }
    }

    /**
     * <div lang="ja">
     * ????????
     * @param columnIndex ?(0???)
     * @param value 
     * </div><div lang="en">
     * See the value in the column of the specified number.
     * @param columnIndex column number (a value of 0 or higher and less than the number of columns)
     * @param value column value
     * </div>
     */
    public void setValue(int columnIndex, Object value) {
        values_[columnIndex] = value;
    }

    /**
     * <div lang="ja">
     * GridDB?Row????????
     * @param row GridDB?Row
     * @throws GSException GridDB??????
     * </div><div lang="en">
     * Set the values of the GridDB Row object in the columns
     * @param row GridDB Row object
     * @throws GSException an exception occurred in Row object
     * </div>
     */
    public void setValues(Row row) throws GSException {
        if (values_ == null) {
            initialize(row.getSchema());
        }
        for (int i = 0; i < values_.length; i++) {
            values_[i] = row.getValue(i);
        }
    }

    /**
     * <div lang="ja">
     * Blob????
     * @param columnIndex ?(0???)
     * @return Blob?
     * </div><div lang="en">
     * Return the value of the Blob column.
     * @param columnIndex column number (a value of 0 or higher and less than the number of columns)
     * @return value of Blob column
     * </div>
     */
    public Blob getBlob(int columnIndex) {
        return (Blob) values_[columnIndex];
    }

    /**
     * <div lang="ja">
     * Blob?????
     * @param columnIndex ?(0???)
     * @param value Blob?
     * </div><div lang="en">
     * Set Blob value in the column.
     * @param columnIndex column number (a value of 0 or higher and less than the number of columns)
     * @param value Blob column value
     * </div>
     */
    public void setBlob(int columnIndex, Blob value) {
        values_[columnIndex] = value;
    }

    /**
     * <div lang="ja">
     * boolean????
     * @param columnIndex ?(0???)
     * @return boolean?
     * </div><div lang="en">
     * Return the value of the boolean column.
     * @param columnIndex column number (a value of 0 or higher and less than the number of columns)
     * @return value of boolean column
     * </div>
     */
    public boolean getBool(int columnIndex) {
        return (Boolean) values_[columnIndex];
    }

    /**
     * <div lang="ja">
     * boolean?????
     * @param columnIndex ?(0???)
     * @param value boolean?
     * </div><div lang="en">
     * Set boolean value in column.
     * @param columnIndex column number (a value of 0 or higher and less than the number of columns)
     * @param value boolean column value
     * </div>
     */
    public void setBool(int columnIndex, boolean value) {
        values_[columnIndex] = value;
    }

    /**
     * <div lang="ja">
     * byte????
     * @param columnIndex ?(0???)
     * @return byte?
     * </div><div lang="en">
     * Return the value of the byte column.
     * @param columnIndex column number (a value of 0 or higher and less than the number of columns)
     * @return value of byte column
     * </div>
     */
    public byte getByte(int columnIndex) {
        return (Byte) values_[columnIndex];
    }

    /**
     * <div lang="ja">
     * byte?????
     * @param columnIndex ?(0???)
     * @param value byte?
     * </div><div lang="en">
     * Set byte value in column.
     * @param columnIndex column number (a value of 0 or higher and less than the number of columns)
     * @param value byte column value
     * </div>
     */
    public void setByte(int columnIndex, byte value) {
        values_[columnIndex] = value;
    }

    /**
     * <div lang="ja">
     * double????
     * @param columnIndex ?(0???)
     * @return double?
     * </div><div lang="en">
     * Return the value of the double column.
     * @param columnIndex column number (a value of 0 or higher and less than the number of columns)
     * @return value of double column
     * </div>
     */
    public double getDouble(int columnIndex) {
        return (Double) values_[columnIndex];
    }

    /**
     * <div lang="ja">
     * double?????
     * @param columnIndex ?(0???)
     * @param value double?
     * </div><div lang="en">
     * Set double value in column.
     * @param columnIndex column number (a value of 0 or higher and less than the number of columns)
     * @param value value of double column
     * </div>
     */
    public void setDouble(int columnIndex, double value) {
        values_[columnIndex] = value;
    }

    /**
     * <div lang="ja">
     * float????
     * @param columnIndex ?(0???)
     * @return float?
     * </div><div lang="en">
     * Return the value of the float column.
     * @param columnIndex column number (a value of 0 or higher and less than the number of columns)
     * @return value of float column
     * </div>
     */
    public float getFloat(int columnIndex) {
        return (Float) values_[columnIndex];
    }

    /**
     * <div lang="ja">
     * float?????
     * @param columnIndex ?(0???)
     * @param value float?
     * </div><div lang="en">
     * Set float value in column.
     * @param columnIndex column number (a value of 0 or higher and less than the number of columns)
     * @param value float column value
     * </div>
     */
    public void setFloat(int columnIndex, float value) {
        values_[columnIndex] = value;
    }

    /**
     * <div lang="ja">
     * int????
     * @param columnIndex ?(0???)
     * @return int?
     * </div><div lang="en">
     * Return the value of the int column.
     * @param columnIndex column number (a value of 0 or higher and less than the number of columns)
     * @return value of int column
     * </div>
     */
    public int getInteger(int columnIndex) {
        return (Integer) values_[columnIndex];
    }

    /**
     * <div lang="ja">
     * int?????
     * @param columnIndex ?(0???)
     * @param value int?
     * </div><div lang="en">
     * Set int value in column.
     * @param columnIndex column number (a value of 0 or higher and less than the number of columns)
     * @param value int column value
     * </div>
     */
    public void setInteger(int columnIndex, int value) {
        values_[columnIndex] = value;
    }

    /**
     * <div lang="ja">
     * long????
     * @param columnIndex ?(0???)
     * @return long?
     * </div><div lang="en">
     * Return the value of the long column.
     * @param columnIndex column number (a value of 0 or higher and less than the number of columns)
     * @return value of long column
     * </div>
     */
    public long getLong(int columnIndex) {
        return (Long) values_[columnIndex];
    }

    /**
     * <div lang="ja">
     * long?????
     * @param columnIndex ?(0???)
     * @param value long?
     * </div><div lang="en">
     * Set long value in column.
     * @param columnIndex column number (a value of 0 or higher and less than the number of columns)
     * @param value long column value
     * </div>
     */
    public void setLong(int columnIndex, long value) {
        values_[columnIndex] = value;
    }

    /**
     * <div lang="ja">
     * short????
     * @param columnIndex ?(0???)
     * @return short?
     * </div><div lang="en">
     * Return the value of the short column.
     * @param columnIndex column number (a value of 0 or higher and less than the number of columns)
     * @return value of short column
     * </div>
     */
    public short getShort(int columnIndex) {
        return (Short) values_[columnIndex];
    }

    /**
     * <div lang="ja">
     * short?????
     * @param columnIndex ?(0???)
     * @param value short?
     * </div><div lang="en">
     * Set short value in column.
     * @param columnIndex column number (a value of 0 or higher and less than the number of columns)
     * @param value short column value
     * </div>
     */
    public void setShort(int columnIndex, short value) {
        values_[columnIndex] = value;
    }

    /**
     * <div lang="ja">
     * String????
     * @param columnIndex ?(0???)
     * @return String?
     * </div><div lang="en">
     * Return the value of the String column.
     * @param columnIndex column number (a value of 0 or higher and less than the number of columns)
     * @return value of String column
     * </div>
     */
    public String getString(int columnIndex) {
        return (String) values_[columnIndex];
    }

    /**
     * <div lang="ja">
     * String?????
     * @param columnIndex ?(0???)
     * @param value String?
     * </div><div lang="en">
     * Set String value in column.
     * @param columnIndex column number (a value of 0 or higher and less than the number of columns)
     * @param value String column value
     * </div>
     */
    public void setString(int columnIndex, String value) {
        values_[columnIndex] = value;
    }

    /**
     * <div lang="ja">
     * Date????
     * @param columnIndex ?(0???)
     * @return Date?
     * </div><div lang="en">
     * Return the value of the Date column.
     * @param columnIndex column number (a value of 0 or higher and less than the number of columns)
     * @return value of Date column
     * </div>
     */
    public Date getTimestamp(int columnIndex) {
        return (Date) values_[columnIndex];
    }

    /**
     * <div lang="ja">
     * Date?????
     * @param columnIndex ?(0???)
     * @param value Date?
     * </div><div lang="en">
     * Set Date value in column.
     * @param columnIndex column number (a value of 0 or higher and less than the number of columns)
     * @param value Date column value
     * </div>
     */
    public void setTimestamp(int columnIndex, Date value) {
        values_[columnIndex] = value;
    }

    /**
     * <div lang="ja">
     * boolean?????
     * @param columnIndex ?(0???)
     * @return boolean??
     * </div><div lang="en">
     * Return the value of the boolean array column.
     * @param columnIndex column number (a value of 0 or higher and less than the number of columns)
     * @return value of boolean array column
     * </div>
     */
    public boolean[] getBoolArray(int columnIndex) {
        return (boolean[]) values_[columnIndex];
    }

    /**
     * <div lang="ja">
     * boolean??????
     * @param columnIndex ?(0???)
     * @param value boolean??
     * </div><div lang="en">
     * Set boolean array value in column.
     * @param columnIndex column number (a value of 0 or higher and less than the number of columns)
     * @param value boolean array column value
     * </div>
     */
    public void setBoolArray(int columnIndex, boolean[] value) {
        values_[columnIndex] = value;
    }

    /**
     * <div lang="ja">
     * byte?????
     * @param columnIndex ?(0???)
     * @return byte??
     * </div><div lang="en">
     * Return the value of the byte array column.
     * @param columnIndex column number (a value of 0 or higher and less than the number of columns)
     * @return value of byte array column
     * </div>
     */
    public byte[] getByteArray(int columnIndex) {
        return (byte[]) values_[columnIndex];
    }

    /**
     * <div lang="ja">
     * byte??????
     * @param columnIndex ?(0???)
     * @param value byte??
     * </div><div lang="en">
     * Set byte array value in column.
     * @param columnIndex column number (a value of 0 or higher and less than the number of columns)
     * @param value byte array column value
     * </div>
     */
    public void setByteArray(int columnIndex, byte[] value) {
        values_[columnIndex] = value;
    }

    /**
     * <div lang="ja">
     * double?????
     * @param columnIndex ?(0???)
     * @return double??
     * </div><div lang="en">
     * Return the value of the double array column.
     * @param columnIndex column number (a value of 0 or higher and less than the number of columns)
     * @return value of double array column
     * </div>
     */
    public double[] getDoubleArray(int columnIndex) {
        return (double[]) values_[columnIndex];
    }

    /**
     * <div lang="ja">
     * double??????
     * @param columnIndex ?(0???)
     * @param value double??
     * </div><div lang="en">
     * Set double array value in column.
     * @param columnIndex column number (a value of 0 or higher and less than the number of columns)
     * @param value double array column value
     * </div>
     */
    public void setDoubleArray(int columnIndex, double[] value) {
        values_[columnIndex] = value;
    }

    /**
     * <div lang="ja">
     * float?????
     * @param columnIndex ?(0???)
     * @return float??
     * </div><div lang="en">
     * Return the value of the float array column.
     * @param columnIndex column number (a value of 0 or higher and less than the number of columns)
     * @return value of float array column
     * </div>
     */
    public float[] getFloatArray(int columnIndex) {
        return (float[]) values_[columnIndex];
    }

    /**
     * <div lang="ja">
     * float??????
     * @param columnIndex ?(0???)
     * @param value float??
     * </div><div lang="en">
     * Set float array value in column.
     * @param columnIndex column number (a value of 0 or higher and less than the number of columns)
     * @param value float array column value
     * </div>
     */
    public void setFloatArray(int columnIndex, float[] value) {
        values_[columnIndex] = value;
    }

    /**
     * <div lang="ja">
     * int?????
     * @param columnIndex ?(0???)
     * @return int??
     * </div><div lang="en">
     * Return the value of the int array column.
     * @param columnIndex column number (a value of 0 or higher and less than the number of columns)
     * @return value of int array column
     * </div>
     */
    public int[] getIntegerArray(int columnIndex) {
        return (int[]) values_[columnIndex];
    }

    /**
     * <div lang="ja">
     * int??????
     * @param columnIndex ?(0???)
     * @param value int??
     * </div><div lang="en">
     * Set int array value in column.
     * @param columnIndex column number (a value of 0 or higher and less than the number of columns)
     * @param value int array column value
     * </div>
     */
    public void setIntegerArray(int columnIndex, int[] value) {
        values_[columnIndex] = value;
    }

    /**
     * <div lang="ja">
     * long?????
     * @param columnIndex ?(0???)
     * @return long??
     * </div><div lang="en">
     * Return the value of the long array column.
     * @param columnIndex column number (a value of 0 or higher and less than the number of columns)
     * @return value of long array column
     * </div>
     */
    public long[] getLongArray(int columnIndex) {
        return (long[]) values_[columnIndex];
    }

    /**
     * <div lang="ja">
     * long??????
     * @param columnIndex ?(0???)
     * @param value long??
     * </div><div lang="en">
     * Set long array value in column.
     * @param columnIndex column number (a value of 0 or higher and less than the number of columns)
     * @param value long array column value
     * </div>
     */
    public void setLongArray(int columnIndex, long[] value) {
        values_[columnIndex] = value;
    }

    /**
     * <div lang="ja">
     * short?????
     * @param columnIndex ?(0???)
     * @return short??
     * </div><div lang="en">
     * Return the value of the short array column.
     * @param columnIndex column number (a value of 0 or higher and less than the number of columns)
     * @return value of short array column
     * </div>
     */
    public short[] getShortArray(int columnIndex) {
        return (short[]) values_[columnIndex];
    }

    /**
     * <div lang="ja">
     * short??????
     * @param columnIndex ?(0???)
     * @param value short??
     * </div><div lang="en">
     * Set short array value in column.
     * @param columnIndex column number (a value of 0 or higher and less than the number of columns)
     * @param value short array column value
     * </div>
     */
    public void setShortArray(int columnIndex, short[] value) {
        values_[columnIndex] = value;
    }

    /**
     * <div lang="ja">
     * String?????
     * @param columnIndex ?(0???)
     * @return String??
     * </div><div lang="en">
     * Return the value of the String array column.
     * @param columnIndex column number (a value of 0 or higher and less than the number of columns)
     * @return value of String array column
     * </div>
     */
    public String[] getStringArray(int columnIndex) {
        return (String[]) values_[columnIndex];
    }

    /**
     * <div lang="ja">
     * String??????
     * @param columnIndex ?(0???)
     * @param value String??
     * </div><div lang="en">
     * Set String array value in column.
     * @param columnIndex column number (a value of 0 or higher and less than the number of columns)
     * @param value String array column value
     * </div>
     */
    public void setStringArray(int columnIndex, String[] value) {
        values_[columnIndex] = value;
    }

    /**
     * <div lang="ja">
     * Date?????
     * @param columnIndex ?(0???)
     * @return Date??
     * </div><div lang="en">
     * Return the value of the Date array column.
     * @param columnIndex column number (a value of 0 or higher and less than the number of columns)
     * @return value of Date array column
     * </div>
     */
    public Date[] getTimestampArray(int columnIndex) {
        return (Date[]) values_[columnIndex];
    }

    /**
     * <div lang="ja">
     * Date??????
     * @param columnIndex ?(0???)
     * @param value Date??
     * </div><div lang="en">
     * Set Date array value in column.
     * @param columnIndex column number (a value of 0 or higher and less than the number of columns)
     * @param value Date array column value
     * </div>
     */
    public void setTimestampArray(int columnIndex, Date[] value) {
        values_[columnIndex] = value;
    }

    /*
     * (non-Javadoc)
     * @see org.apache.hadoop.io.Writable#readFields(java.io.DataInput)
     */
    @Override
    public void readFields(DataInput in) throws IOException {
        int size = in.readInt();
        values_ = new Object[size];
        types_ = new GSType[size];
        for (int i = 0; i < size; i++) {
            readColumn(in, i);
        }
    }

    /*
     * (non-Javadoc)
     * @see org.apache.hadoop.io.Writable#write(java.io.DataOutput)
     */
    @Override
    public void write(DataOutput out) throws IOException {
        out.writeInt(values_.length);
        for (int i = 0; i < values_.length; i++) {
            writeColumn(out, i);
        }
    }

    /*
     * (non-Javadoc)
     * @see java.lang.Object#hashCode()
     */
    @Override
    public int hashCode() {
        int hash = 1;
        for (Object column : values_) {
            if (column != null) {
                hash = hash * 31 + column.hashCode();
            }
        }
        return hash;
    }

    /*
     * (non-Javadoc)
     * @see java.lang.Object#toString()
     */
    @Override
    public String toString() {
        StringBuffer sb = new StringBuffer();
        for (Object column : values_) {
            sb.append(column + "\t");
        }
        return sb.toString();
    }

    private void initialize(ContainerInfo containerInfo) {
        int count = containerInfo.getColumnCount();
        values_ = new Object[count];
        types_ = new GSType[count];
        for (int i = 0; i < count; i++) {
            types_[i] = containerInfo.getColumnInfo(i).getType();
        }
    }

    private void readColumn(DataInput in, int i) throws IOException {
        byte type = in.readByte();
        switch (type) {
        case BLOB:
            types_[i] = GSType.BLOB;
            values_[i] = readBlob(in);
            break;
        case BOOL:
            types_[i] = GSType.BOOL;
            values_[i] = in.readBoolean();
            break;
        case BYTE:
            types_[i] = GSType.BYTE;
            values_[i] = in.readByte();
            break;
        case DOUBLE:
            types_[i] = GSType.DOUBLE;
            values_[i] = in.readDouble();
            break;
        case FLOAT:
            types_[i] = GSType.FLOAT;
            values_[i] = in.readFloat();
            break;
        case INTEGER:
            types_[i] = GSType.INTEGER;
            VIntWritable vint = new VIntWritable();
            vint.readFields(in);
            values_[i] = vint.get();
            break;
        case LONG:
            types_[i] = GSType.LONG;
            VLongWritable vlong = new VLongWritable();
            vlong.readFields(in);
            values_[i] = vlong.get();
            break;
        case SHORT:
            types_[i] = GSType.SHORT;
            values_[i] = in.readShort();
            break;
        case STRING:
            types_[i] = GSType.STRING;
            values_[i] = readString(in);
            break;
        case TIMESTAMP:
            types_[i] = GSType.TIMESTAMP;
            values_[i] = new Date(in.readLong());
            break;
        case BOOL_ARRAY:
            types_[i] = GSType.BOOL_ARRAY;
            values_[i] = readBoolArray(in);
            break;
        case BYTE_ARRAY:
            types_[i] = GSType.BYTE_ARRAY;
            values_[i] = readByteArray(in);
            break;
        case DOUBLE_ARRAY:
            types_[i] = GSType.DOUBLE_ARRAY;
            values_[i] = readDoubleArray(in);
            break;
        case FLOAT_ARRAY:
            types_[i] = GSType.FLOAT_ARRAY;
            values_[i] = readFloatArray(in);
            break;
        case INTEGER_ARRAY:
            types_[i] = GSType.INTEGER_ARRAY;
            values_[i] = readIntegerArray(in);
            break;
        case LONG_ARRAY:
            types_[i] = GSType.LONG_ARRAY;
            values_[i] = readLongArray(in);
            break;
        case SHORT_ARRAY:
            types_[i] = GSType.SHORT_ARRAY;
            values_[i] = readShortArray(in);
            break;
        case STRING_ARRAY:
            types_[i] = GSType.STRING_ARRAY;
            values_[i] = readStringArray(in);
            break;
        case TIMESTAMP_ARRAY:
            types_[i] = GSType.TIMESTAMP_ARRAY;
            values_[i] = readTimestampArray(in);
            break;
        default:
            throw new IOException();
        }
    }

    private Blob readBlob(DataInput in) throws IOException {
        int len = in.readInt();
        byte[] buffer = new byte[len];
        in.readFully(buffer);
        try {
            return new SerialBlob(buffer);
        } catch (SQLException e) {
            throw new IOException(e);
        }
    }

    private String readString(DataInput in) throws IOException {
        int len = in.readInt();
        byte[] buffer = new byte[len];
        in.readFully(buffer);
        return new String(buffer, "UTF-8");
    }

    private boolean[] readBoolArray(DataInput in) throws IOException {
        int len = in.readInt();
        boolean[] buffer = new boolean[len];
        for (int i = 0; i < len; i++) {
            buffer[i] = in.readBoolean();
        }
        return buffer;
    }

    private byte[] readByteArray(DataInput in) throws IOException {
        int len = in.readInt();
        byte[] buffer = new byte[len];
        for (int i = 0; i < len; i++) {
            buffer[i] = in.readByte();
        }
        return buffer;
    }

    private double[] readDoubleArray(DataInput in) throws IOException {
        int len = in.readInt();
        double[] buffer = new double[len];
        for (int i = 0; i < len; i++) {
            buffer[i] = in.readDouble();
        }
        return buffer;
    }

    private float[] readFloatArray(DataInput in) throws IOException {
        int len = in.readInt();
        float[] buffer = new float[len];
        for (int i = 0; i < len; i++) {
            buffer[i] = in.readFloat();
        }
        return buffer;
    }

    private int[] readIntegerArray(DataInput in) throws IOException {
        int len = in.readInt();
        int[] buffer = new int[len];
        for (int i = 0; i < len; i++) {
            buffer[i] = in.readInt();
        }
        return buffer;
    }

    private long[] readLongArray(DataInput in) throws IOException {
        int len = in.readInt();
        long[] buffer = new long[len];
        for (int i = 0; i < len; i++) {
            buffer[i] = in.readLong();
        }
        return buffer;
    }

    private short[] readShortArray(DataInput in) throws IOException {
        int len = in.readInt();
        short[] buffer = new short[len];
        for (int i = 0; i < len; i++) {
            buffer[i] = in.readShort();
        }
        return buffer;
    }

    private String[] readStringArray(DataInput in) throws IOException {
        int len = in.readInt();
        String[] buffer = new String[len];
        for (int i = 0; i < len; i++) {
            buffer[i] = readString(in);
        }
        return buffer;
    }

    private Date[] readTimestampArray(DataInput in) throws IOException {
        int len = in.readInt();
        Date[] buffer = new Date[len];
        for (int i = 0; i < len; i++) {
            buffer[i] = new Date(in.readLong());
        }
        return buffer;
    }

    private void writeColumn(DataOutput out, int i) throws IOException {
        switch (types_[i]) {
        case BLOB:
            out.writeByte(BLOB);
            writeBlob(out, (Blob) values_[i]);
            break;
        case BOOL:
            out.writeByte(BOOL);
            out.writeBoolean((Boolean) values_[i]);
            break;
        case BYTE:
            out.writeByte(BYTE);
            out.writeByte((Byte) values_[i]);
            break;
        case DOUBLE:
            out.writeByte(DOUBLE);
            out.writeDouble((Double) values_[i]);
            break;
        case FLOAT:
            out.writeByte(FLOAT);
            out.writeFloat((Float) values_[i]);
            break;
        case INTEGER:
            out.writeByte(INTEGER);
            new VIntWritable((Integer) values_[i]).write(out);
            break;
        case LONG:
            out.writeByte(LONG);
            new VLongWritable((Long) values_[i]).write(out);
            break;
        case SHORT:
            out.writeByte(SHORT);
            out.writeShort((Short) values_[i]);
            break;
        case STRING:
            out.writeByte(STRING);
            writeString(out, (String) values_[i]);
            break;
        case TIMESTAMP:
            out.writeByte(TIMESTAMP);
            out.writeLong(((Date) values_[i]).getTime());
            break;
        case BOOL_ARRAY:
            out.writeByte(BOOL_ARRAY);
            writeBoolArray(out, (boolean[]) values_[i]);
            break;
        case BYTE_ARRAY:
            out.writeByte(BYTE_ARRAY);
            writeByteArray(out, (byte[]) values_[i]);
            break;
        case DOUBLE_ARRAY:
            out.writeByte(DOUBLE_ARRAY);
            writeDoubleArray(out, (double[]) values_[i]);
            break;
        case FLOAT_ARRAY:
            out.writeByte(FLOAT_ARRAY);
            writeFloatArray(out, (float[]) values_[i]);
            break;
        case INTEGER_ARRAY:
            out.writeByte(INTEGER_ARRAY);
            writeIntegerArray(out, (int[]) values_[i]);
            break;
        case LONG_ARRAY:
            out.writeByte(LONG_ARRAY);
            writeLongArray(out, (long[]) values_[i]);
            break;
        case SHORT_ARRAY:
            out.writeByte(SHORT_ARRAY);
            writeShortArray(out, (short[]) values_[i]);
            break;
        case STRING_ARRAY:
            out.writeByte(STRING_ARRAY);
            writeStringArray(out, (String[]) values_[i]);
            break;
        case TIMESTAMP_ARRAY:
            out.writeByte(TIMESTAMP_ARRAY);
            writeTimestampArray(out, (Date[]) values_[i]);
            break;
        default:
            throw new IOException();
        }
    }

    private void writeBlob(DataOutput out, Blob obj) throws IOException {
        try {
            int len = (int) obj.length();
            byte[] buffer = obj.getBytes(1, len);
            out.writeInt(len);
            out.write(buffer);
        } catch (SQLException e) {
            throw new IOException(e);
        }
    }

    private void writeString(DataOutput out, String obj) throws IOException {
        byte[] buffer = obj.getBytes("UTF-8");
        out.writeInt(buffer.length);
        out.write(buffer);
    }

    private void writeBoolArray(DataOutput out, boolean[] obj) throws IOException {
        out.writeInt(obj.length);
        for (int i = 0; i < obj.length; i++) {
            out.writeBoolean(obj[i]);
        }
    }

    private void writeByteArray(DataOutput out, byte[] obj) throws IOException {
        out.writeInt(obj.length);
        out.write(obj);
    }

    private void writeDoubleArray(DataOutput out, double[] obj) throws IOException {
        out.writeInt(obj.length);
        for (int i = 0; i < obj.length; i++) {
            out.writeDouble(obj[i]);
        }
    }

    private void writeFloatArray(DataOutput out, float[] obj) throws IOException {
        out.writeInt(obj.length);
        for (int i = 0; i < obj.length; i++) {
            out.writeFloat(obj[i]);
        }
    }

    private void writeIntegerArray(DataOutput out, int[] obj) throws IOException {
        out.writeInt(obj.length);
        for (int i = 0; i < obj.length; i++) {
            out.writeInt(obj[i]);
        }
    }

    private void writeLongArray(DataOutput out, long[] obj) throws IOException {
        out.writeInt(obj.length);
        for (int i = 0; i < obj.length; i++) {
            out.writeLong(obj[i]);
        }
    }

    private void writeShortArray(DataOutput out, short[] obj) throws IOException {
        out.writeInt(obj.length);
        for (int i = 0; i < obj.length; i++) {
            out.writeShort(obj[i]);
        }
    }

    private void writeStringArray(DataOutput out, String[] obj) throws IOException {
        out.writeInt(obj.length);
        for (int i = 0; i < obj.length; i++) {
            writeString(out, obj[i]);
        }
    }

    private void writeTimestampArray(DataOutput out, Date[] obj) throws IOException {
        out.writeInt(obj.length);
        for (int i = 0; i < obj.length; i++) {
            out.writeLong(obj[i].getTime());
        }
    }
}