org.voltdb.hadoop.VoltRecord.java Source code

Java tutorial

Introduction

Here is the source code for org.voltdb.hadoop.VoltRecord.java

Source

/* This file is part of VoltDB.
 * Copyright (C) 2008-2017 VoltDB Inc.
 *
 * Permission is hereby granted, free of charge, to any person obtaining
 * a copy of this software and associated documentation files (the
 * "Software"), to deal in the Software without restriction, including
 * without limitation the rights to use, copy, modify, merge, publish,
 * distribute, sublicense, and/or sell copies of the Software, and to
 * permit persons to whom the Software is furnished to do so, subject to
 * the following conditions:
 *
 * The above copyright notice and this permission notice shall be
 * included in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
 * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 * OTHER DEALINGS IN THE SOFTWARE.
 */

package org.voltdb.hadoop;

import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import org.apache.hadoop.io.Text;
import org.apache.hadoop.io.Writable;
import org.voltdb.utils.CSVBulkDataLoader;
import org.voltdb.utils.RowWithMetaData;

import com.google_voltpatches.common.collect.FluentIterable;

/**
 * A {@link Writable} wrapper around a {@linkplain List} of object values that
 * represent the field contents of a Volt table row
 */
public class VoltRecord implements Writable, Iterable<Object> {
    private final List<Object> m_fields = new ArrayList<Object>(64);
    private String m_table;

    /*
     * Default constructor for deserializing operations
     */
    public VoltRecord() {
    }

    /**
     * Constructor that sets the table associated with the records fields
     * @param tableName a VoltDB table name
     */
    public VoltRecord(String tableName) {
        if (tableName == null || tableName.trim().isEmpty()) {
            throw new IllegalArgumentException("null or empty table name");
        }
        m_table = tableName;
    }

    /**
     * Constructors that sets both the field values, and the table name
     * associated with the field's content
     *
     * @param tableName a VoltDB table name
     * @param fields a list of fields values
     */
    public VoltRecord(String tableName, Object... fields) {
        this(tableName);
        FluentIterable.of(fields).copyInto(m_fields);
    }

    /**
     * Constructors that sets both the field values, and the table name
     * associated with the field's content
     *
     * @param tableName a VoltDB table name
     * @param fields a list of fields values
     */
    public VoltRecord(String tableName, Iterable<Object> fields) {
        this(tableName);
        FluentIterable.from(fields).copyInto(m_fields);
    }

    /**
     * Sets the record's table name only if it is not already set
     *
     * @param tableName VoltDB table name
     * @return itself for chained setter invocations
     */
    public VoltRecord setTableName(String tableName) {
        if (tableName != null && !tableName.trim().isEmpty() && m_table == null) {
            m_table = tableName;
        }
        return this;
    }

    /**
     * Gets the object value for the given index into the underlying list
     * @param atIdx index
     * @return the object value at the given index
     */
    public Object get(int atIdx) {
        return m_fields.get(atIdx);
    }

    /**
     * Sets the object at the given index into the underlying list
     *
     * @param atIdx index
     * @param value object value
     * @return itself for chained setter invocations
     */
    public VoltRecord set(int atIdx, Object value) {
        m_fields.set(atIdx, value);
        return this;
    }

    /**
     * Adds a field value to the underlying list
     *
     * @param field value
     * @return itself for chained setter invocations
     */
    public VoltRecord add(Object field) {
        m_fields.add(field);
        return this;
    }

    /**
     * Adds all the given values to the underlying list
     *
     * @param fields list of field values
     * @return itself for chained setter invocations
     */
    public VoltRecord addAll(Object[] fields) {
        FluentIterable.of(fields).copyInto(m_fields);
        return this;
    }

    /**
     * Adds all the given values to the underlying list
     *
     * @param fields list of field values
     * @return itself for chained setter invocations
     */
    public VoltRecord addAll(Iterable<Object> fields) {
        FluentIterable.from(fields).copyInto(m_fields);
        return this;
    }

    /**
     * Adds all the given values to the underlying list
     * (for groovy << operator)
     *
     * @param fields list of field values
     * @return itself for chained setter invocations
     */
    public VoltRecord leftShift(Iterable<Object> fields) {
        return addAll(fields);
    }

    /**
     * Returns the size of the underlying list of field values
     *
     * @return how many values contained wherein
     */
    public int size() {
        return m_fields.size();
    }

    /**
     * Clears  the underlying list
     *
     * @return itself for chained setter invocations
     */
    public VoltRecord clear() {
        m_fields.clear();
        return this;
    }

    /**
     * @return an {@linkplain Iterator} to the underlying list of field values
     */
    @Override
    public Iterator<Object> iterator() {
        return m_fields.iterator();
    }

    /**
     * Indicates whether or not the underlying list of field values is empty
     * @return true if it is empty. false if it is not
     */
    public boolean isEmpty() {
        return m_fields.isEmpty();
    }

    /**
     * Serializes itself to the given {@linkplain DataOutput} stream
     * It looks up the adapters cache for the data adapters associated
     * with this record's table name.
     */
    @Override
    public void write(DataOutput out) throws IOException {
        DataAdapters adapters = DataAdapters.adaptersFor(m_table, null);
        if (adapters == null) {
            throw new IOException("no adapters configured for table " + m_table);
        }
        Text.writeString(out, m_table);
        adapters.forOutput().adapt(out, this);
    }

    /**
     * De-serializes itself from the given {@linkplain DataInput} stream
     * It looks up the adapters cache for the data adapters associated
     * with this record's table name.
     */
    @Override
    public void readFields(DataInput in) throws IOException {
        setTableName(Text.readString(in, 512));
        DataAdapters adapters = DataAdapters.adaptersFor(m_table, null);
        if (adapters == null) {
            throw new IOException("no adapters configured for table " + m_table);
        }
        adapters.forInput().adapt(in, this);
    }

    /**
     * Feeds its underlying list of field values to the given loader
     * @param loader a volt loader
     *
     * @throws IOException
     */
    public void write(CSVBulkDataLoader loader) throws IOException {
        RowWithMetaData meta = new RowWithMetaData(new WeakReference<VoltRecord>(this), -1);
        try {
            loader.insertRow(meta, m_fields.toArray(new Object[m_fields.size()]));
        } catch (InterruptedException e) {
            throw new IOException("interrupted loader insert", e);
        }
    }

    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + ((m_fields == null) ? 0 : m_fields.hashCode());
        result = prime * result + ((m_table == null) ? 0 : m_table.hashCode());
        return result;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        VoltRecord other = (VoltRecord) obj;
        if (m_fields == null) {
            if (other.m_fields != null)
                return false;
        } else if (!m_fields.equals(other.m_fields))
            return false;
        if (m_table == null) {
            if (other.m_table != null)
                return false;
        } else if (!m_table.equals(other.m_table))
            return false;
        return true;
    }

    @Override
    public String toString() {
        return "VoltRecord [m_fields=" + m_fields + ", m_table=" + m_table + "]";
    }

}