Package org.voltdb.messaging

Source Code of org.voltdb.messaging.FragmentResponseMessage

/* This file is part of VoltDB.
* Copyright (C) 2008-2014 VoltDB Inc.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with VoltDB.  If not, see <http://www.gnu.org/licenses/>.
*/

package org.voltdb.messaging;

import java.nio.ByteBuffer;
import java.util.ArrayList;

import org.voltcore.messaging.Subject;
import org.voltcore.messaging.VoltMessage;
import org.voltcore.utils.CoreUtils;
import org.voltdb.PrivateVoltTableFactory;
import org.voltdb.VoltTable;
import org.voltdb.exceptions.SerializableException;

/**
* Message from an execution site which is participating in a transaction
* to the stored procedure coordinator for that transaction. The contents
* are the tables output by the plan fragments and a status code. In the
* event of an error, a text message can be embedded in a table attached.
*
*/
public class FragmentResponseMessage extends VoltMessage {

    public static final byte SUCCESS          = 1;
    public static final byte USER_ERROR       = 2;
    public static final byte UNEXPECTED_ERROR = 3;

    long m_executorHSId;
    long m_destinationHSId;
    long m_txnId;
    private long m_spHandle;
    byte m_status;
    // default dirty to true until proven otherwise
    // Not currently used; leaving it in for now
    boolean m_dirty = true;
    boolean m_recovering = false;
    // WHA?  Why do we have a separate dependency count when
    // the array lists will tell you their lengths?  Doesn't look like
    // we do anything else with this value other than track the length
    short m_dependencyCount = 0;
    ArrayList<Integer> m_dependencyIds = new ArrayList<Integer>();
    ArrayList<VoltTable> m_dependencies = new ArrayList<VoltTable>();
    SerializableException m_exception;

    /** Empty constructor for de-serialization */
    FragmentResponseMessage() {
        m_subject = Subject.DEFAULT.getId();
    }

    public FragmentResponseMessage(FragmentTaskMessage task, long HSId) {
        m_executorHSId = HSId;
        m_txnId = task.getTxnId();
        m_spHandle = task.getSpHandle();
        m_destinationHSId = task.getCoordinatorHSId();
        m_subject = Subject.DEFAULT.getId();
    }

    // IV2 hacky constructor
    // We need to be able to create a new FragmentResponseMessage
    // with unioned dependency table for sysprocs.  Let us build a
    // FragmentResponse from a prior one.  Don't copy the tables
    // and dependencies because we'll fill those in later.
    public FragmentResponseMessage(FragmentResponseMessage resp)
    {
        m_executorHSId = resp.m_executorHSId;
        m_destinationHSId = resp.m_destinationHSId;
        m_txnId = resp.m_txnId;
        m_spHandle = resp.m_spHandle;
        m_status = resp.m_status;
        m_dirty = resp.m_dirty;
        m_recovering = resp.m_recovering;
        m_exception = resp.m_exception;
        m_subject = Subject.DEFAULT.getId();
    }

    /**
     * If the status code is failure then an exception may be included.
     * @param status
     * @param e
     */
    public void setStatus(byte status, SerializableException e) {
        m_status = status;
        m_exception = e;
    }

    public boolean isRecovering() {
        return m_recovering;
    }

    public void setRecovering(boolean recovering) {
        m_recovering = recovering;
    }

    public void addDependency(int dependencyId, VoltTable table) {
        m_dependencyIds.add(dependencyId);
        m_dependencies.add(table);
        m_dependencyCount++;
    }

    // IV2: need to be able to reset this for dep tracking
    // until we change it to count partitions rather than
    // initiator HSIds
    public void setExecutorSiteId(long executorHSId) {
        m_executorHSId = executorHSId;
    }

    public long getExecutorSiteId() {
        return m_executorHSId;
    }

    public long getDestinationSiteId() {
        return m_destinationHSId;
    }

    public long getTxnId() {
        return m_txnId;
    }

    public long getSpHandle() {
        return m_spHandle;
    }

    public byte getStatusCode() {
        return m_status;
    }

    public int getTableCount() {
        return m_dependencyCount;
    }

    public int getTableDependencyIdAtIndex(int index) {
        return m_dependencyIds.get(index);
    }

    public VoltTable getTableAtIndex(int index) {
        return m_dependencies.get(index);
    }

    public SerializableException getException() {
        return m_exception;
    }

    @Override
    public int getSerializedSize()
    {
        int msgsize = super.getSerializedSize();

        msgsize += 8 // executorHSId
            + 8 // destinationHSId
            + 8 // txnId
            + 8 // m_spHandle
            + 1 // status byte
            + 1 // dirty flag
            + 1 // node recovering flag
            + 2; // dependency count

        // one int per dependency ID
        msgsize += 4 * m_dependencyCount;

        // one byte to indicate null dependency result table
        msgsize += m_dependencies.size();

        // Add the actual result lengths
        for (VoltTable dep : m_dependencies)
        {
            if (dep != null) {
                msgsize += dep.getSerializedSize();
            }
        }

        if (m_exception != null) {
            msgsize += m_exception.getSerializedSize();
        } else {
            msgsize += 4; //Still serialize exception length 0
        }

        return msgsize;
    }

    @Override
    public void flattenToBuffer(ByteBuffer buf)
    {
        assert(m_exception == null || m_status != SUCCESS);
        buf.put(VoltDbMessageFactory.FRAGMENT_RESPONSE_ID);

        buf.putLong(m_executorHSId);
        buf.putLong(m_destinationHSId);
        buf.putLong(m_txnId);
        buf.putLong(m_spHandle);
        buf.put(m_status);
        buf.put((byte) (m_dirty ? 1 : 0));
        buf.put((byte) (m_recovering ? 1 : 0));
        buf.putShort(m_dependencyCount);
        for (int i = 0; i < m_dependencyCount; i++)
            buf.putInt(m_dependencyIds.get(i));

        for (int i = 0; i < m_dependencyCount; i++)
        {
            VoltTable dep = m_dependencies.get(i);
            if (dep == null) {
                buf.put((byte) 0);
            } else {
                buf.put((byte) 1);
                dep.flattenToBuffer(buf);
            }
        }

        if (m_exception != null) {
            m_exception.serializeToBuffer(buf);
        } else {
            buf.putInt(0);
        }

        assert(buf.capacity() == buf.position());
        buf.limit(buf.position());
    }

    @Override
    public void initFromBuffer(ByteBuffer buf) {
        m_executorHSId = buf.getLong();
        m_destinationHSId = buf.getLong();
        m_txnId = buf.getLong();
        m_spHandle = buf.getLong();
        m_status = buf.get();
        m_dirty = buf.get() == 0 ? false : true;
        m_recovering = buf.get() == 0 ? false : true;
        m_dependencyCount = buf.getShort();
        for (int i = 0; i < m_dependencyCount; i++)
            m_dependencyIds.add(buf.getInt());
        for (int i = 0; i < m_dependencyCount; i++) {
            boolean isNull = buf.get() == 0 ? true : false;
            if (isNull) {
                m_dependencies.add(null);
            } else {
                m_dependencies.add(PrivateVoltTableFactory.createVoltTableFromSharedBuffer(buf));
            }
        }
        m_exception = SerializableException.deserializeFromBuffer(buf);
        assert(buf.capacity() == buf.position());
    }

    @Override
    public String toString() {
        StringBuilder sb = new StringBuilder();

        sb.append("FRAGMENT_RESPONSE (FROM ");
        sb.append(CoreUtils.hsIdToString(m_executorHSId));
        sb.append(" TO ");
        sb.append(CoreUtils.hsIdToString(m_destinationHSId));
        sb.append(") FOR TXN ");
        sb.append(m_txnId);
        sb.append(", SP HANDLE: ");
        sb.append(m_spHandle);

        if (m_status == SUCCESS)
            sb.append("\n  SUCCESS");
        else if (m_status == UNEXPECTED_ERROR)
            sb.append("\n  UNEXPECTED_ERROR");
        else
            sb.append("\n  USER_ERROR");

        if (m_dirty)
            sb.append("\n  DIRTY");
        else
            sb.append("\n  PRISTINE");

        for (int i = 0; i < m_dependencyCount; i++) {
            sb.append("\n  DEP ").append(m_dependencyIds.get(i));
            sb.append(" WITH ").append(m_dependencies.get(i).getRowCount()).append(" ROWS (");
            for (int j = 0; j < m_dependencies.get(i).getColumnCount(); j++) {
                sb.append(m_dependencies.get(i).getColumnName(j)).append(", ");
            }
            sb.setLength(sb.lastIndexOf(", "));
            sb.append(")");
        }

        return sb.toString();
    }
}
TOP

Related Classes of org.voltdb.messaging.FragmentResponseMessage

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.