Package org.voltdb.jni

Source Code of org.voltdb.jni.ExecutionEngineIPC

/* This file is part of VoltDB.
* Copyright (C) 2008-2010 VoltDB Inc.
*
* VoltDB is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* VoltDB 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with VoltDB.  If not, see <http://www.gnu.org/licenses/>.
*/

package org.voltdb.jni;

import java.io.BufferedReader;
import java.io.EOFException;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.nio.ByteBuffer;
import java.nio.channels.SocketChannel;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.logging.Level;
import java.util.logging.Logger;

import org.voltdb.BackendTarget;
import org.voltdb.DependencySet;
import org.voltdb.ParameterSet;
import org.voltdb.PrivateVoltTableFactory;
import org.voltdb.SysProcSelector;
import org.voltdb.TableStreamType;
import org.voltdb.VoltTable;
import org.voltdb.catalog.Table;
import org.voltdb.exceptions.EEException;
import org.voltdb.exceptions.SerializableException;
import org.voltdb.export.ExportProtoMessage;
import org.voltdb.messaging.FastDeserializer;
import org.voltdb.messaging.FastSerializer;
import org.voltdb.utils.DBBPool.BBContainer;
import org.voltdb.utils.NotImplementedException;

import edu.brown.hstore.HStore;
import edu.brown.hstore.PartitionExecutor;


/* Serializes data over a connection that presumably is being read
* by a voltdb execution engine. The serialization is currently a
* a packed binary big endian buffer. Each buffer has a header
* that provides the total length (as an int) and the command being
* serialized (also as an int). Commands are described by the Commands
* enum.
*
* These serializations are implemented as required since a lot of
* the native interface isn't needed in many cases.
*
* The serialization could be more robust. Probably the right way to
* get that robustness would be to create FastSerializable classes
* for the more complex calls and read them through the fast serializable
* C++ interface.
*
* (The fastserializer still requires hand-authoring the ser/deser
* logic in java and C and doesn't result in any more favorable
* packing; in fact the resulting wire content might be the same in
* most cases... And you can't fast serialize an array of primitive
* types without writing a wrapper object.)
*
* Responses to the IPC interface start with a 1 byte result code. If the
* result code is failure then no message follows. If the result code
* is success and a response is warranted it will follow and is length prefixed if necessary.
* Unlike requests to the EE, the length prefix in responses does not include the 1 byte
* result code nor the 4 byte length field. When we correct the 1 and 4 byte network reads and writes
* we can this. A length will not prefix the response
* if the length of the response can be deduced from the original request.
*
* The return message format for DMLPlanFragments is all big endian:
* 1 byte result code
* 8 byte results codes. Same number of results as numPlanFragments.
*
* The return message format for QueryPlanFragments is all big endian:
* 1 byte result code
* 4 byte result length. Does not include the length of the result code or result length field.
* X bytes of serialized VoltTables. Same number of tables as numPlanFragments
*
* The return message format for PlanFragment is all big endian:
* 1 byte result code
* 4 byte result length. Does not include the length of the result code or result length field.
* 4 byte result indicating number of dependencies returned
* The dependency tables
*
* The return message format for ReceiveDependency consists of a single byte result code.
*
* The return message format for Load table consists of a single byte result code.
*/

public class ExecutionEngineIPC extends ExecutionEngine {
    /**
     * Exposes error generated by the Valgrind client to org.voltdb.regressionsuites.LocalSingeProcessServer
     * which will fail a test if this list is not empty.
     */
    public static final List<String> m_valgrindErrors = Collections.synchronizedList(new ArrayList<String>());

    /** Commands are serialized over the connection */
    private enum Commands {
        Initialize(0),
        LoadCatalog(2),
        ToggleProfiler(3),
        Tick(4),
        GetStats(5),
        QueryPlanFragments(6),
        PlanFragment(7),
        LoadTable(9),
        releaseUndoToken(10),
        undoUndoToken(11),
        CustomPlanFragment(12),
        SetLogLevels(13),
        Quiesce(16),
        ActivateTableStream(17),
        TableStreamSerializeMore(18),
        UpdateCatalog(19),
        ExportAction(20),
        RecoveryMessage(21),
        TableHashCode(22),
        Hashinate(23);
        Commands(final int id) {
            m_id = id;
        }

        int m_id;
    }

    private static AtomicInteger eeCount = new AtomicInteger(21214);

    /**
     * One connection per ExecutionEngineIPC. This connection also interfaces
     * with Valgrind to report any problems that Valgrind may find including
     * reachable heap blocks on exit. Unfortunately it is not enough to inspect
     * the Valgrind return code as it considers reachable blocks to not be an
     * error.
     **/
    private class Connection {
        private Socket m_socket = null;
        private SocketChannel m_socketChannel = null;
        private Process m_eeProcess;
        private String m_eePID = null;
        private Thread m_stdoutParser = null;
        // Has a received String from Valgrind saying that all heap blocks were freed
        // ignored when running directly againsts the IPC client
        private boolean m_allHeapBlocksFreed = false;
        Connection(final BackendTarget target) {
            /*
             * String ee_exec_path = System.getenv("EEIPC_PATH"); if
             * (ee_exec_path != null) { try { eeProcess =
             * Runtime.getRuntime().exec("valgrind " + ee_exec_path +
             * " > ~aweisberg/valgrind_out 2>&1 "); } catch (IOException e) {
             * throw new RuntimeException(e); } try { Thread.sleep(1000); }
             * catch (InterruptedException e) { // TODO Auto-generated catch
             * block e.printStackTrace(); } }
             */
            int port = 21214;
            if (target == BackendTarget.NATIVE_EE_IPC) {
                System.out
                        .println("Press enter after you have started the EE process to initiate the connection to the EE");
                try {
                    System.in.read();
                } catch (final IOException e1) {
                    // TODO Auto-generated catch block
                    e1.printStackTrace();
                }
            } else if (target == BackendTarget.NATIVE_EE_VALGRIND_IPC) {
                System.out.println("Running " + target);
                final ArrayList<String> args = new ArrayList<String>();
                final String voltdbIPCPath = System.getenv("VOLTDBIPC_PATH");
                args.add("valgrind");
                args.add("--leak-check=full");
                args.add("--show-reachable=yes");
                args.add("--num-callers=32");
                args.add("--error-exitcode=-1");
                /*
                 * VOLTDBIPC_PATH is set as part of the regression suites and ant check
                 * In that scenario junit will handle logging of Valgrind output.
                 * stdout and stderr is forwarded from the backend.
                 */
                if (voltdbIPCPath == null) {
                    args.add("--quiet");
                    args.add("--log-file=site_" + m_siteId + ".log");
            }
                args.add(voltdbIPCPath == null ? "./voltdbipc" : voltdbIPCPath);
                port = eeCount.getAndIncrement();
                args.add(Integer.toString(port));
                final ProcessBuilder pb = new ProcessBuilder(args);
                pb.redirectErrorStream(true);

                try {
                    m_eeProcess = pb.start();
                    final Process p = m_eeProcess;
                    Runtime.getRuntime().addShutdownHook(new Thread() {
                        @Override
                        public void run() {
                            p.destroy();
                        }
                    });
                } catch (final IOException e) {
                    e.printStackTrace();
                    HStore.crashDB();
            }

                /*
                 * This block attempts to read the PID and then waits for the listening message
                 * indicating that the IPC EE is ready to accept a connection on a socket
                 */
                final BufferedReader r = new BufferedReader(new InputStreamReader(m_eeProcess.getInputStream()));
                try {
                    boolean failure = false;
                    String pidString = r.readLine();
                    if (pidString == null) {
                        failure = true;
                    } else {
                        System.out.println("PID string \"" + pidString + "\"");
                        pidString = pidString.substring(2);
                        pidString = pidString.substring(0, pidString.indexOf("="));
                        m_eePID = pidString;
                    }
                    while (true) {
                        String line = null;
                        if (!failure) {
                            line = r.readLine();
                        }
                        if (line != null && !failure) {
                            System.out.println("[ipc=" + m_eePID + "]:::" + line);
                            if (line.contains("listening")) {
                                break;
                            } else {
                                continue;
                            }
                        } else {
                            try {
                                m_eeProcess.waitFor();
                            } catch (final InterruptedException e) {
                                // TODO Auto-generated catch block
                                e.printStackTrace();
                            }
                            System.out.println("[ipc=" + m_eePID + "] Returned end of stream and exit value " + m_eeProcess.exitValue());
                            HStore.crashDB();
                        }
                    }
                } catch (final IOException e) {
                    e.printStackTrace();
                    return;
                }

                /*
                 * Create a thread to parse Valgrind's output and populdate m_valgrindErrors with errors.
                 */
                final Process p = m_eeProcess;
                m_stdoutParser = new Thread() {
                    @Override
                    public void run() {
                        while (true) {
                            try {
                                final String line = r.readLine();
                                if (line != null) {
                                    System.out.println("[ipc=" + p.hashCode() + "]:::" + line);
                                    if (line.startsWith("==" + m_eePID + "==")) {
                                        processValgrindOutput(line);
                                    }
                                } else {
                                    try {
                                        p.waitFor();
                                    } catch (final InterruptedException e) {
                                        e.printStackTrace();
                                    }
                                    System.out.println("[ipc=" + m_eePID + "] Returned end of stream and exit value " + p.exitValue());
                                    if (!m_allHeapBlocksFreed) {
                                        m_valgrindErrors.add("Not all heap blocks were freed");
                                    }
                                    return;
                                }
                            } catch (final IOException e) {
                                e.printStackTrace();
                                return;
                            }
                        }
                    }

                    private void processValgrindOutput(final String line) {
                        final String errorLineString = "ERROR SUMMARY: ";
                        final String heapBlocksFreedString = "All heap blocks were freed";
                        /*
                         * An indirect way of making sure Valgrind reports no error memory accesses
                         */
                        if (line.contains(errorLineString)) {
                            final int index = line.indexOf(errorLineString) + errorLineString.length();
                            final char errorNumChar = line.charAt(index);
                            if (!(errorNumChar == '0')) {
                                m_valgrindErrors.add(line);
                            }
                        } else if (line.contains(heapBlocksFreedString)) {
                            m_allHeapBlocksFreed = true;
                        }
                    }
                };
                m_stdoutParser.setDaemon(false);
                m_stdoutParser.start();
            } else {
                throw new RuntimeException("Shouldn't instantiate an ExecutionEngineIPC with BackendTarget " + target);
            }

            try {
                m_socketChannel = SocketChannel.open(new InetSocketAddress(
                        "localhost", port));
                m_socketChannel.configureBlocking(true);
                m_socket = m_socketChannel.socket();
                m_socket.setTcpNoDelay(true);
            } catch (final Exception e) {
                System.out.println(e.getMessage());
                System.out
                        .println("Failed to initialize IPC EE connection. Quitting.");
                while (true) {}

                //System.exit(-1);
            }
            System.out.println("Created IPC connection for site.");
        }

        /* Close the socket indicating to the EE it should terminate */
        public void close() throws InterruptedException {
            if (m_socketChannel != null) {
                try {
                    m_socketChannel.close();
                } catch (final IOException e) {
                    throw new RuntimeException(e);
                }
                m_socketChannel = null;
                m_socket = null;
            }
            if (m_eeProcess != null) {
                m_eeProcess.waitFor();
            }
            if (m_stdoutParser != null) {
                m_stdoutParser.join();
            }
        }

//        /** blocking write of all m_data to outputstream */
//        void write(final byte data[], final int amount) throws IOException {
//            // write 4 byte length (which includes its own 4 bytes) in big-endian
//            // order. this hurts .. but I'm not sure of a better way.
//            final byte[] length = new byte[4];
//            int amt = amount + 4;
//            // System.out.println("Sending " + amt + " bytes");
//            assert (amt >= 8);
//            for (int i = 3; i >= 0; --i) {
//                length[i] = (byte) (amt & 0xff);
//                amt >>= 8;
//            }
//            m_socket.getOutputStream().write(length);
//            m_socket.getOutputStream().write(data, 0, amount);
//        }

        /** blocking write of all m_data to outputstream */
        void write() throws IOException {
            // write 4 byte length (which includes its own 4 bytes) in big-endian
            // order. this hurts .. but I'm not sure of a better way.
            m_dataNetwork.clear();
            final int amt = m_data.remaining();
            m_dataNetwork.putInt(amt + 4);
            m_dataNetwork.limit(4 + amt);
            m_dataNetwork.rewind();
            while (m_dataNetwork.hasRemaining()) {
                m_socketChannel.write(m_dataNetwork);
            }
        }

        /**
         * An error code specific to the IPC backend that indicates
         * that as part of fulfilling a previous request the IPC
         * backend requires a dependency table. This is not really
         * an error code.
         */
        static final int kErrorCode_RetrieveDependency = 100;

        /**
         * An error code to be sent in a response to an RetrieveDependency request.
         * Indicates that a dependency table was found and that it follows
         */
        static final int kErrorCode_DependencyFound = 101;

        /**
         * An error code to be sent in a response to an RetrieveDependency request.
         * Indicates that no dependency tables could be found and that no data follows.
         */
        static final int kErrorCode_DependencyNotFound = 102 ;

        /**
         * Invoke crash VoltDB
         */
        static final int kErrorCode_CrashVoltDB = 104;

        /**
         * Read a single byte indicating a return code. This method has evolved
         * to include providing dependency tables necessary for the completion of previous
         * request. The method loops ready status bytes instead of recursing to avoid
         * excessive recursion in the case where a large number of dependency tables
         * must be fetched before the request can be satisfied.
         *
         * Facing further evolutionary pressure, readStatusByte has  grown
         * EL buffer reading fins. EL buffers arrive here mid-command execution.
         * @return
         * @throws IOException
         */
        int readStatusByte() throws IOException {
            int status = kErrorCode_RetrieveDependency;

            while (true) {
                status = m_socket.getInputStream().read();
                if (status == kErrorCode_RetrieveDependency) {
                    final ByteBuffer dependencyIdBuffer = ByteBuffer.allocate(4);
                    while (dependencyIdBuffer.hasRemaining()) {
                        final int read = m_socketChannel.read(dependencyIdBuffer);
                        if (read == -1) {
                            throw new IOException("Unable to read enough bytes for dependencyId in order to " +
                            " satisfy IPC backend request for a dependency table");
                        }
                    }
                    dependencyIdBuffer.rewind();
                    sendDependencyTable(dependencyIdBuffer.getInt());
                    continue;
                }
                if (status == kErrorCode_CrashVoltDB) {
                    ByteBuffer lengthBuffer = ByteBuffer.allocate(4);
                    while (lengthBuffer.hasRemaining()) {
                        final int read = m_socket.getChannel().read(lengthBuffer);
                        if (read == -1) {
                            throw new EOFException();
                        }
                    }
                    lengthBuffer.flip();
                    ByteBuffer messageBuffer = ByteBuffer.allocate(lengthBuffer.getInt());
                    while (messageBuffer.hasRemaining()) {
                        final int read = m_socket.getChannel().read(messageBuffer);
                        if (read == -1) {
                            throw new EOFException();
                        }
                    }

                    final int reasonLength = messageBuffer.getInt();
                    final byte reasonBytes[] = new byte[reasonLength];
                    messageBuffer.get(reasonBytes);
                    final String message = new String(reasonBytes, "UTF-8");

                    final int filenameLength = messageBuffer.getInt();
                    final byte filenameBytes[] = new byte[filenameLength];
                    messageBuffer.get(filenameBytes);
                    final String filename = new String(filenameBytes, "UTF-8");

                    final int lineno = messageBuffer.getInt();


                    final int numTraces = messageBuffer.getInt();
                    final String traces[] = new String[numTraces];

                    for (int ii = 0; ii < numTraces; ii++) {
                        final int traceLength = messageBuffer.getInt();
                        final byte traceBytes[] = new byte[traceLength];
                        traces[ii] = new String(traceBytes, "UTF-8");
                    }

                    ExecutionEngine.crashVoltDB(message, traces, filename, lineno);
                }

                try {
                    checkErrorCode(status);
                    break;
                }
                catch (final RuntimeException e) {
                    if (e instanceof SerializableException) {
                        throw e;
                    } else {
                        throw (IOException)e.getCause();
                    }
                }
            }

            return status;
        }


        /**
         * Read and deserialize some number of tables from the wire. Assumes that the message is length prefixed.
         * @param tables Output array as well as indicator of exactly how many tables to read off of the wire
         * @throws IOException
         */
        public void readResultTables(final VoltTable tables[]) throws IOException {
            final ByteBuffer resultTablesLengthBytes = ByteBuffer.allocate(4);

            //resultTablesLengthBytes.order(ByteOrder.LITTLE_ENDIAN);
            while (resultTablesLengthBytes.hasRemaining()) {
                int read = m_socketChannel.read(resultTablesLengthBytes);
                if (read == -1) {
                    throw new EOFException();
                }
            }
            resultTablesLengthBytes.flip();

            final int resultTablesLength = resultTablesLengthBytes.getInt();
            final ByteBuffer resultTablesBuffer = ByteBuffer
                    .allocate(resultTablesLength);
            //resultTablesBuffer.order(ByteOrder.LITTLE_ENDIAN);
            while (resultTablesBuffer.hasRemaining()) {
                int read = m_socketChannel.read(resultTablesBuffer);
                if (read == -1) {
                    throw new EOFException();
                }
            }
            resultTablesBuffer.flip();

            final FastDeserializer ds = new FastDeserializer(resultTablesBuffer);
            // check if anything was changed
            final boolean dirty = ds.readBoolean();
            if (dirty)
                m_dirty = true;

            for (int ii = 0; ii < tables.length; ii++) {
                final int dependencyCount = ds.readInt(); // ignore the table count
                assert(dependencyCount == 1); //Expect one dependency generated per plan fragment
                ds.readInt(); // ignore the dependency ID
                tables[ii] = (VoltTable) ds.readObject(tables[ii], null);
            }
        }

        /**
         * Read the result dependencies returned from the execution of a plan fragment.
         * Returns a list of pairs of dependency ids and dependency tables.
         */
        public DependencySet readDependencies() throws IOException {
            // read the result set size, which doesn't include this 4 byte
            // length notification!
            final ByteBuffer resultSetSizeBuff = ByteBuffer.allocate(4);
            resultSetSizeBuff.rewind();
            while (resultSetSizeBuff.hasRemaining()) {
                int read = m_socketChannel.read(resultSetSizeBuff);
                if (read == -1) {
                    throw new EOFException();
                }
            }

            resultSetSizeBuff.rewind();
            final int resultsSize = resultSetSizeBuff.getInt();

            // read the serialized dependencies
            final ByteBuffer depsBuff = ByteBuffer.allocate(resultsSize);
            depsBuff.clear().rewind();
            while (depsBuff.hasRemaining()) {
                int read = m_socketChannel.read(depsBuff);
                if (read == -1) {
                    throw new EOFException();
                }
            }

            // deserialize the dependencies
            depsBuff.rewind();
            final boolean dirty = depsBuff.get() > 0;
            if (dirty) {
                m_dirty = true;
            }
            final int numDependencies = depsBuff.getInt();
            final int[] depIds = new int[numDependencies];
            final VoltTable[] dependencies = new VoltTable[numDependencies];
            final FastDeserializer fds = new FastDeserializer(depsBuff);
            for (int ii = 0; ii < numDependencies; ++ii) {
                depIds[ii] = fds.readInt();
                dependencies[ii] = fds.readObject(VoltTable.class);
            }
            assert(depIds.length == 1);

            // and finally return the constructed dependency set
            return new DependencySet(depIds, dependencies);
        }

        public void throwException(final int errorCode) throws IOException {
            final ByteBuffer lengthBuffer = ByteBuffer.allocate(4);
            while (lengthBuffer.hasRemaining()) {
                int read = m_socketChannel.read(lengthBuffer);
                if (read == -1) {
                    throw new EOFException();
                }
            }
            lengthBuffer.flip();
            final int exceptionLength = lengthBuffer.getInt();//Length is only between EE and Java.
            if (exceptionLength == 0) {
                throw new EEException(errorCode);
            } else {
                final ByteBuffer exceptionBuffer = ByteBuffer.allocate(exceptionLength + 4);
                exceptionBuffer.putInt(exceptionLength);
                while(exceptionBuffer.hasRemaining()) {
                    int read = m_socketChannel.read(exceptionBuffer);
                    if (read == -1) {
                        throw new EOFException();
                    }
                }
                assert(!exceptionBuffer.hasRemaining());
                exceptionBuffer.rewind();
                throw SerializableException.deserializeFromBuffer(exceptionBuffer);
            }
        }
    }

    /** Local m_data */
    private final int m_clusterIndex;
    private final int m_siteId;
    private final int m_partitionId;
    private final int m_hostId;
    private final String m_hostname;
    // private final FastSerializer m_fser;
    private final Connection m_connection;
    private final BBContainer m_dataNetworkOrigin;
    private final ByteBuffer m_dataNetwork;
    private ByteBuffer m_data;

    // private int m_counter;

    public ExecutionEngineIPC(
            final PartitionExecutor site,
            final int clusterIndex,
            final int siteId,
            final int partitionId,
            final int hostId,
            final String hostname,
            final BackendTarget target) {
        super(site);
        // m_counter = 0;
        m_clusterIndex = clusterIndex;
        m_siteId = siteId;
        m_partitionId = partitionId;
        m_hostId = hostId;
        m_hostname = hostname;
        // m_fser = new FastSerializer(false, false);
        m_connection = new Connection(target);

        // voltdbipc assumes host byte order everywhere
        m_dataNetworkOrigin = org.voltdb.utils.DBBPool.allocateDirect(1024 * 1024 * 10);
        m_dataNetwork = m_dataNetworkOrigin.b;
        m_dataNetwork.position(4);
        m_data = m_dataNetwork.slice();

        initialize(m_clusterIndex, m_siteId, m_partitionId, m_hostId, m_hostname);
    }

    /** Utility method to generate an EEXception that can be overriden by derived classes**/
    @Override
    protected void throwExceptionForError(final int errorCode) {
        try {
            m_connection.throwException(errorCode);
        } catch (final IOException e) {
            throw new RuntimeException(e);
        }
    }

    @Override
    public void release() throws EEException, InterruptedException {
        m_connection.close();
        m_dataNetworkOrigin.discard();
    }

    /**
     * the abstract api assumes construction initializes but here initialization
     * is just another command.
     */
    public void initialize(
            final int clusterIndex,
            final int siteId,
            final int partitionId,
            final int hostId,
            final String hostname
            ) {
        int result = ExecutionEngine.ERRORCODE_ERROR;
        m_data.clear();
        m_data.putInt(Commands.Initialize.m_id);
        m_data.putInt(clusterIndex);
        m_data.putInt(siteId);
        m_data.putInt(partitionId);
        m_data.putInt(hostId);
        m_data.putLong(EELoggers.getLogLevels());
        m_data.putShort((short)hostname.length());
        try {
            m_data.put(hostname.getBytes("UTF-8"));
        } catch (UnsupportedEncodingException e) {
            throw new RuntimeException(e);
        }
        try {
            m_data.flip();
            m_connection.write();
            result = m_connection.readStatusByte();
        } catch (final IOException e) {
            System.out.println("Exception: " + e.getMessage());
            throw new RuntimeException(e);
        }
        checkErrorCode(result);
    }

    /** write the catalog as a UTF-8 byte string via connection */
    @Override
    public void loadCatalog(final String serializedCatalog) throws EEException {
        int result = ExecutionEngine.ERRORCODE_ERROR;
        m_data.clear();

        try {
            final byte catalogBytes[] = serializedCatalog.getBytes("UTF-8");
            if (m_data.capacity() < catalogBytes.length + 100) {
                m_data = ByteBuffer.allocate(catalogBytes.length + 100);
            }
            m_data.putInt(Commands.LoadCatalog.m_id);
            m_data.put(catalogBytes);
            m_data.put((byte)'\0');
        } catch (final UnsupportedEncodingException ex) {
            Logger.getLogger(ExecutionEngineIPC.class.getName()).log(
                    Level.SEVERE, null, ex);
        }

        try {
            m_data.flip();
            m_connection.write();
            result = m_connection.readStatusByte();
        } catch (final IOException e) {
            System.out.println("Exception: " + e.getMessage());
            throw new RuntimeException(e);
        }
        checkErrorCode(result);
    }

    /** write the diffs as a UTF-8 byte string via connection */
    @Override
    public void updateCatalog(final String catalogDiffs, int catalogVersion) throws EEException {
        int result = ExecutionEngine.ERRORCODE_ERROR;
        m_data.clear();

        try {
            final byte catalogBytes[] = catalogDiffs.getBytes("UTF-8");
            if (m_data.capacity() < catalogBytes.length + 100) {
                m_data = ByteBuffer.allocate(catalogBytes.length + 100);
            }
            m_data.putInt(Commands.UpdateCatalog.m_id);
            m_data.putInt(catalogVersion);
            m_data.put(catalogBytes);
            m_data.put((byte)'\0');
        } catch (final UnsupportedEncodingException ex) {
            Logger.getLogger(ExecutionEngineIPC.class.getName()).log(
                    Level.SEVERE, null, ex);
        }

        try {
            m_data.flip();
            m_connection.write();
            result = m_connection.readStatusByte();
        } catch (final IOException e) {
            System.out.println("Exception: " + e.getMessage());
            throw new RuntimeException(e);
        }
        checkErrorCode(result);
    }

    @Override
    public void tick(final long time, final long lastCommittedTxnId) {
        int result = ExecutionEngine.ERRORCODE_ERROR;
        m_data.clear();
        m_data.putInt(Commands.Tick.m_id);
        m_data.putLong(time);
        m_data.putLong(lastCommittedTxnId);
        try {
            m_data.flip();
            m_connection.write();
            result = m_connection.readStatusByte();
        } catch (final IOException e) {
            System.out.println("Exception: " + e.getMessage());
            throw new RuntimeException(e);
        }
        checkErrorCode(result);
        // no return code for tick.
    }

    @Override
    public void quiesce(long lastCommittedTransactionId) {
        int result = ExecutionEngine.ERRORCODE_ERROR;
        m_data.clear();
        m_data.putInt(Commands.Quiesce.m_id);
        m_data.putLong(lastCommittedTransactionId);
        try {
            m_data.flip();
            m_connection.write();
            result = m_connection.readStatusByte();
        } catch (final IOException e) {
            System.out.println("Excpeption: " + e.getMessage());
            throw new RuntimeException();
        }
        checkErrorCode(result);
    }

    private void sendPlanFragmentsInvocation(final Commands cmd,
            final long[] planFragmentIds, final int numFragmentIds,
            final int[] input_depIds,
            final int[] output_depIds,
            final ParameterSet[] parameterSets, final int numParameterSets, final long txnId,
            final long lastCommittedTxnId, final long undoToken) {
        // big endian, not direct
        final FastSerializer fser = new FastSerializer();
        try {
            for (int i = 0; i < numFragmentIds; ++i) {
                parameterSets[i].writeExternal(fser);
            }
        } catch (final IOException exception) {
            throw new RuntimeException(exception);
        }

        m_data.clear();
        m_data.putInt(cmd.m_id);
        m_data.putLong(txnId);
        m_data.putLong(lastCommittedTxnId);
        m_data.putLong(undoToken);
        m_data.putInt(numFragmentIds);
        m_data.putInt(numParameterSets);
        for (int i = 0; i < numFragmentIds; ++i) {
            m_data.putLong(planFragmentIds[i]);
        }
        /** PAVLO **/
        for (int i = 0; i < numFragmentIds; ++i) {
            m_data.putInt(input_depIds[i]);
        }
        for (int i = 0; i < numFragmentIds; ++i) {
            m_data.putInt(output_depIds[i]);
        }
        /** PAVLO **/
        m_data.put(fser.getBuffer());

        try {
            m_data.flip();
            m_connection.write();
        } catch (final Exception e) {
            System.out.println("Exception: " + e.getMessage());
            throw new RuntimeException(e);
        }
    }

    @Override
    public DependencySet executePlanFragment(final long planFragmentId, final int outputDepId,
            final int inputDepId, final ParameterSet parameterSet, final long txnId,
            final long lastCommittedTxnId, final long undoToken)
            throws EEException {
        // big endian, not direct
        final FastSerializer fser = new FastSerializer();
        try {
            parameterSet.writeExternal(fser);
        } catch (final IOException exception) {
            throw new RuntimeException(exception);
        }

        m_data.clear();
        m_data.putInt(Commands.PlanFragment.m_id);
        m_data.putLong(txnId);
        m_data.putLong(lastCommittedTxnId);
        m_data.putLong(undoToken);
        m_data.putLong(planFragmentId);
        m_data.putInt(outputDepId);
        m_data.putInt(inputDepId);
        m_data.put(fser.getBuffer());

        try {
            m_data.flip();
            m_connection.write();
        } catch (final Exception e) {
            System.out.println("Exception: " + e.getMessage());
            throw new RuntimeException(e);
        }

        int result = ExecutionEngine.ERRORCODE_ERROR;
        try {
            result = m_connection.readStatusByte();
        } catch (final IOException e) {
            System.out.println("Exception: " + e.getMessage());
            throw new RuntimeException(e);
        }

        if (result != ExecutionEngine.ERRORCODE_SUCCESS) {
            throw new EEException(result);
        } else {
            try {
                return m_connection.readDependencies();
            } catch (final IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
        return null;
    }

    @Override
    public VoltTable executeCustomPlanFragment(final String plan, int outputDepId,
            int inputDepId, final long txnId, final long lastCommittedTxnId,
            final long undoQuantumToken) throws EEException
    {
        final FastSerializer fser = new FastSerializer();
        try {
            fser.writeString(plan);
        } catch (final IOException exception) {
            throw new RuntimeException(exception);
        }

        m_data.clear();
        m_data.putInt(Commands.CustomPlanFragment.m_id);
        m_data.putLong(txnId);
        m_data.putLong(lastCommittedTxnId);
        m_data.putLong(undoQuantumToken);
        m_data.putInt(outputDepId);
        m_data.putInt(inputDepId);
        m_data.put(fser.getBuffer());

        try {
            m_data.flip();
            m_connection.write();
        } catch (final Exception e) {
            System.out.println("Exception: " + e.getMessage());
            throw new RuntimeException(e);
        }

        int result = ExecutionEngine.ERRORCODE_ERROR;
        try {
            result = m_connection.readStatusByte();
        } catch (final IOException e) {
            System.out.println("Exception: " + e.getMessage());
            throw new RuntimeException(e);
        }
        if (result == ExecutionEngine.ERRORCODE_SUCCESS) {
            final VoltTable resultTables[] = new VoltTable[1];
            resultTables[0] = PrivateVoltTableFactory.createUninitializedVoltTable();
            try {
                m_connection.readResultTables(resultTables);
            } catch (final IOException e) {
                throw new EEException(
                        ExecutionEngine.ERRORCODE_WRONG_SERIALIZED_BYTES);
            }
            return resultTables[0];
        }
        return null;
    }

    @Override
    public DependencySet executeQueryPlanFragmentsAndGetDependencySet(
            long[] planFragmentIds,
            int numFragmentIds,
            int[] input_depIds,
            int[] output_depIds,
            ParameterSet[] parameterSets,
            int numParameterSets,
            long txnId, long lastCommittedTxnId, long undoToken) throws EEException {
       
        // TODO
        return (null);
    }
   
//    @Override
//    public VoltTable[] executeQueryPlanFragmentsAndGetResults(
//            final long[] planFragmentIds, final int numFragmentIds,
//            final int[] input_depIds,
//            final int[] output_depIds,
//            final ParameterSet[] parameterSets, final int numParameterSets, final long txnId,
//            final long lastCommittedTxnId, final long undoToken) throws EEException {
//        sendPlanFragmentsInvocation(Commands.QueryPlanFragments,
//                planFragmentIds, numFragmentIds,
//                input_depIds,
//                output_depIds,
//                parameterSets,
//                numParameterSets, txnId, lastCommittedTxnId, undoToken);
//        int result = ExecutionEngine.ERRORCODE_ERROR;
//        try {
//            result = m_connection.readStatusByte();
//        } catch (final IOException e) {
//            System.out.println("Exception: " + e.getMessage());
//            throw new RuntimeException(e);
//        }
//        if (result == ExecutionEngine.ERRORCODE_SUCCESS) {
//            final VoltTable resultTables[] = new VoltTable[numFragmentIds];
//            for (int ii = 0; ii < numFragmentIds; ii++) {
//                resultTables[ii] = PrivateVoltTableFactory.createUninitializedVoltTable();
//            }
//            try {
//                m_connection.readResultTables(resultTables);
//            } catch (final IOException e) {
//                throw new EEException(
//                        ExecutionEngine.ERRORCODE_WRONG_SERIALIZED_BYTES);
//            }
//            return resultTables;
//        }
//        return null;
//    }

    @Override
    public VoltTable serializeTable(final int tableId) throws EEException {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    /**
     * Unsupported implementation of toggleProfiler
     */
    @Override
    public int toggleProfiler(final int toggle) {
        throw new UnsupportedOperationException("Not supported yet.");
    }


    @Override
    public void loadTable(final int tableId, final VoltTable table, final long txnId,
            final long lastCommittedTxnId, final long undoToken, boolean allowExport)
        throws EEException
    {
        m_data.clear();
        m_data.putInt(Commands.LoadTable.m_id);
        m_data.putInt(tableId);
        m_data.putLong(txnId);
        m_data.putLong(lastCommittedTxnId);
        m_data.putLong(undoToken);

        if(allowExport)
            m_data.putShort((short) 1);
        else
            m_data.putShort((short) 0);

        final ByteBuffer tableBytes = table.getTableDataReference();
        if (m_data.remaining() < tableBytes.remaining()) {
            m_data.flip();
            final ByteBuffer newBuffer = ByteBuffer.allocate(m_data.remaining()
                    + tableBytes.remaining());
            newBuffer.rewind();
            //newBuffer.order(ByteOrder.LITTLE_ENDIAN);
            newBuffer.put(m_data);
            m_data = newBuffer;
        }
        m_data.put(tableBytes);

        try {
            m_data.flip();
            m_connection.write();
        } catch (final Exception e) {
            System.out.println("Exception: " + e.getMessage());
            throw new RuntimeException(e);
        }

        int result = ExecutionEngine.ERRORCODE_ERROR;
        try {
            result = m_connection.readStatusByte();
        } catch (final IOException e) {
            System.out.println("Exception: " + e.getMessage());
            throw new RuntimeException(e);
        }

        if (result != ExecutionEngine.ERRORCODE_SUCCESS) {
            throw new EEException(result);
        }
    }

    @Override
    public VoltTable[] getStats(
            final SysProcSelector selector,
            final int[] locators,
            final boolean interval,
            final Long now) {
        m_data.clear();
        m_data.putInt(Commands.GetStats.m_id);
        m_data.putInt(selector.ordinal());
        if (interval) {
            m_data.put((byte)1);
        } else {
            m_data.put((byte)0);
        }
        m_data.putLong(now);
        m_data.putInt(locators.length);
        for (final int locator : locators) {
            m_data.putInt(locator);
        }

        m_data.flip();
        try {
            m_connection.write();
        } catch (final IOException e) {
            System.out.println("Exception: " + e.getMessage());
            throw new RuntimeException(e);
        }

        int result = ExecutionEngine.ERRORCODE_ERROR;
        try {
            result = m_connection.readStatusByte();
        } catch (final IOException e) {
            System.out.println("Exception: " + e.getMessage());
            throw new RuntimeException(e);
        }

        try {
            if (result == ExecutionEngine.ERRORCODE_SUCCESS) {
                final ByteBuffer messageLengthBuffer = ByteBuffer.allocate(4);
                while (messageLengthBuffer.hasRemaining()) {
                    int read = m_connection.m_socketChannel.read(messageLengthBuffer);
                    if (read == -1) {
                        throw new EOFException();
                    }
                }
                messageLengthBuffer.rewind();
                final ByteBuffer messageBuffer = ByteBuffer.allocate(messageLengthBuffer.getInt());
                while (messageBuffer.hasRemaining()) {
                    int read = m_connection.m_socketChannel.read(messageBuffer);
                    if (read == -1) {
                        throw new EOFException();
                    }
                }
                messageBuffer.rewind();

                final FastDeserializer fds = new FastDeserializer(messageBuffer);
                final VoltTable results[] = new VoltTable[1];
                final VoltTable resultTable = PrivateVoltTableFactory.createUninitializedVoltTable();
                results[0] = (VoltTable)fds.readObject(resultTable, this);
                return results;
            }
        } catch (final IOException e) {
            System.out.println("Exception: " + e.getMessage());
            throw new RuntimeException(e);
        }
        return null;
    }

    @Override
    public boolean releaseUndoToken(final long undoToken) {
        m_data.clear();
        m_data.putInt(Commands.releaseUndoToken.m_id);
        m_data.putLong(undoToken);

        try {
            m_data.flip();
            m_connection.write();
        } catch (final Exception e) {
            System.out.println("Exception: " + e.getMessage());
            throw new RuntimeException(e);
        }

        int result = ExecutionEngine.ERRORCODE_ERROR;
        try {
            result = m_connection.readStatusByte();
        } catch (final IOException e) {
            e.printStackTrace();
            throw new RuntimeException(e);
        }

        if (result != ExecutionEngine.ERRORCODE_SUCCESS) {
            return false;
        }
        return true;
    }

    @Override
    public boolean undoUndoToken(final long undoToken) {
        m_data.clear();
        m_data.putInt(Commands.undoUndoToken.m_id);
        m_data.putLong(undoToken);

        try {
            m_data.flip();
            m_connection.write();
        } catch (final Exception e) {
            System.out.println("Exception: " + e.getMessage());
            throw new RuntimeException(e);
        }

        int result = ExecutionEngine.ERRORCODE_ERROR;
        try {
            result = m_connection.readStatusByte();
        } catch (final Exception e) {
            System.out.println("Exception: " + e.getMessage());
            throw new RuntimeException(e);
        }

        if (result != ExecutionEngine.ERRORCODE_SUCCESS) {
            return false;
        }
        return true;
    }

    @Override
    public boolean setLogLevels(final long logLevels) throws EEException {
        m_data.clear();
        m_data.putInt(Commands.SetLogLevels.m_id);
        m_data.putLong(logLevels);

        try {
            m_data.flip();
            m_connection.write();
        } catch (final Exception e) {
            System.out.println("Exception: " + e.getMessage());
            throw new RuntimeException(e);
        }

        int result = ExecutionEngine.ERRORCODE_ERROR;
        try {
            result = m_connection.readStatusByte();
        } catch (final IOException e) {
            System.out.println("Exception: " + e.getMessage());
            throw new RuntimeException(e);
        }

        if (result != ExecutionEngine.ERRORCODE_SUCCESS) {
            return false;
        }
        return true;
    }

    /**
     * Retrieve a dependency table and send it via the connection. If
     * no table is available send a response code indicating such.
     * The message is prepended with two lengths. One length is for
     * the network layer and is the size of the whole message not including
     * the length prefix.
     * @param dependencyId ID of the dependency table to send to the client
     */
    private void sendDependencyTable(final int dependencyId) throws IOException{
        final byte[] dependencyBytes = nextDependencyAsBytes(dependencyId);
        if (dependencyBytes == null) {
            m_connection.m_socket.getOutputStream().write(Connection.kErrorCode_DependencyNotFound);
            return;
        }
        // 1 for response code + 4 for dependency length prefix + dependencyBytes.length
        final ByteBuffer message = ByteBuffer.allocate(1 + 4 + dependencyBytes.length);

        // write the response code
        message.put((byte)Connection.kErrorCode_DependencyFound);

        // write the dependency's length prefix
        message.putInt(dependencyBytes.length);

        // finally, write dependency table itself
        message.put(dependencyBytes);
        message.rewind();
        if (m_connection.m_socketChannel.write(message) != message.capacity()) {
            throw new IOException("Unable to send dependency table to client. Attempted blocking write of " +
                    message.capacity() + " but not all of it was written");
        }
    }

    @Override
    public boolean activateTableStream(int tableId, TableStreamType streamType) {
        m_data.clear();
        m_data.putInt(Commands.ActivateTableStream.m_id);
        m_data.putInt(tableId);
        m_data.putInt(streamType.ordinal());

        try {
            m_data.flip();
            m_connection.write();
        } catch (final Exception e) {
            System.out.println("Exception: " + e.getMessage());
            throw new RuntimeException(e);
        }

        int result = ExecutionEngine.ERRORCODE_ERROR;
        try {
            result = m_connection.readStatusByte();
        } catch (final Exception e) {
            System.out.println("Exception: " + e.getMessage());
            throw new RuntimeException(e);
        }

        if (result != ExecutionEngine.ERRORCODE_SUCCESS) {
            return false;
        }
        return true;
    }

    @Override
    public int tableStreamSerializeMore(BBContainer c, int tableId, TableStreamType streamType) {
        int bytesReturned = -1;
        ByteBuffer view = c.b.duplicate();
        try {
            m_data.clear();
            m_data.putInt(Commands.TableStreamSerializeMore.m_id);
            m_data.putInt(tableId);
            m_data.putInt(streamType.ordinal());
            m_data.putInt(c.b.remaining());

            m_data.flip();
            m_connection.write();

            m_connection.readStatusByte();

            ByteBuffer lengthBuffer = ByteBuffer.allocate(4);
            while (lengthBuffer.hasRemaining()) {
                int read = m_connection.m_socketChannel.read(lengthBuffer);
                if (read == -1) {
                    throw new EOFException();
                }
            }
            lengthBuffer.flip();
            final int length = lengthBuffer.getInt();
            bytesReturned = length;
            /*
             * Error or no more tuple data for this table.
             */
            if (length == -1 || length == 0) {
                return length;
            }
            view.limit(view.position() + length);
            while (view.hasRemaining()) {
                m_connection.m_socketChannel.read(view);
            }
        } catch (final IOException e) {
            System.out.println("Exception: " + e.getMessage());
            throw new RuntimeException(e);
        }

        return bytesReturned;
    }

    @Override
    public ExportProtoMessage exportAction(boolean ackAction, boolean pollAction,
            boolean resetAction, boolean syncAction,
            long ackOffset, long seqNo, int partitionId, long mTableId) {
        try {
            m_data.clear();
            m_data.putInt(Commands.ExportAction.m_id);
            m_data.putInt(ackAction ? 1 : 0);
            m_data.putInt(pollAction ? 1 : 0);
            m_data.putInt(resetAction ? 1 : 0);
            m_data.putInt(syncAction ? 1 : 0);
            m_data.putLong(ackOffset);
            m_data.putLong(seqNo);
            m_data.putLong(mTableId);
            m_data.flip();
            m_connection.write();

            ByteBuffer data = null;
            ByteBuffer results = ByteBuffer.allocate(8);
            while (results.remaining() > 0)
                m_connection.m_socketChannel.read(results);
            results.flip();
            long result_offset = results.getLong();
            if (result_offset < 0) {
                ExportProtoMessage reply = null;
                reply = new ExportProtoMessage(partitionId, mTableId);
                reply.error();
                return reply;
            }
            else {
                results = ByteBuffer.allocate(4);
                while (results.remaining() > 0)
                    m_connection.m_socketChannel.read(results);
                results.flip();
                int result_sz = results.getInt();
                data = ByteBuffer.allocate(result_sz + 4);
                data.putInt(result_sz);
                while (data.remaining() > 0)
                    m_connection.m_socketChannel.read(data);
                data.flip();

                ExportProtoMessage reply = null;
                if (pollAction) {
                    reply = new ExportProtoMessage(partitionId, mTableId);
                    reply.pollResponse(result_offset, data);
                }
                return reply;
            }

        } catch (final IOException e) {
            throw new RuntimeException(e);
        }

    }

    @Override
    public void processRecoveryMessage( ByteBuffer buffer, long pointer) {
        try {
            m_data.clear();
            m_data.putInt(Commands.RecoveryMessage.m_id);
            m_data.putInt(buffer.remaining());
            m_data.put(buffer);

            m_data.flip();
            m_connection.write();

            m_connection.readStatusByte();
        } catch (final IOException e) {
            System.out.println("Exception: " + e.getMessage());
            throw new RuntimeException(e);
        }
    }

    @Override
    public long tableHashCode(int tableId) {
        try {
            m_data.clear();
            m_data.putInt(Commands.TableHashCode.m_id);
            m_data.putInt(tableId);

            m_data.flip();
            m_connection.write();

            m_connection.readStatusByte();
            ByteBuffer hashCode = ByteBuffer.allocate(8);
            while (hashCode.hasRemaining()) {
                int read = m_connection.m_socketChannel.read(hashCode);
                if (read <= 0) {
                    throw new EOFException();
                }
            }
            hashCode.flip();
            return hashCode.getLong();
        } catch (final IOException e) {
            System.out.println("Exception: " + e.getMessage());
            throw new RuntimeException(e);
        }
    }

    @Override
    public int hashinate(Object value, int partitionCount)
    {
        ParameterSet parameterSet = new ParameterSet(true);
        parameterSet.setParameters(value);

        final FastSerializer fser = new FastSerializer();
        try {
            parameterSet.writeExternal(fser);
        } catch (final IOException exception) {
            throw new RuntimeException(exception);
        }

        m_data.clear();
        m_data.putInt(Commands.Hashinate.m_id);
        m_data.putInt(partitionCount);
        m_data.put(fser.getBuffer());
        try {
            m_data.flip();
            m_connection.write();

            m_connection.readStatusByte();
            ByteBuffer part = ByteBuffer.allocate(4);
            while (part.hasRemaining()) {
                int read = m_connection.m_socketChannel.read(part);
                if (read <= 0) {
                    throw new EOFException();
                }
            }
            part.flip();
            return part.getInt();
        } catch (final Exception e) {
            System.out.println("Exception: " + e.getMessage());
            throw new RuntimeException(e);
        }
    }

    @Override
    public void trackingEnable(Long txnId) throws EEException {
        throw new NotImplementedException("Read/Write Set Tracking is disabled for IPC ExecutionEngine");
    }
    @Override
    public void trackingFinish(Long txnId) throws EEException {
        throw new NotImplementedException("Read/Write Set Tracking is disabled for IPC ExecutionEngine");
    }
    @Override
    public VoltTable trackingReadSet(Long txnId) throws EEException {
        throw new NotImplementedException("Read/Write Set Tracking is disabled for IPC ExecutionEngine");
    }
    @Override
    public VoltTable trackingWriteSet(Long txnId) throws EEException {
        throw new NotImplementedException("Read/Write Set Tracking is disabled for IPC ExecutionEngine");
    }
   
    @Override
    public void antiCacheInitialize(File dbFilePath, long blockSize) throws EEException {
        throw new NotImplementedException("Anti-Caching is disabled for IPC ExecutionEngine");
    }

    @Override
    public void antiCacheReadBlocks(Table catalog_tbl, short[] block_ids, int[] tuple_offsets) {
        throw new NotImplementedException("Anti-Caching is disabled for IPC ExecutionEngine");
    }

    @Override
    public void antiCacheMergeBlocks(Table catalog_tbl) {
        throw new NotImplementedException("Anti-Caching is disabled for IPC ExecutionEngine");
    }

    @Override
    public VoltTable antiCacheEvictBlock(Table catalog_tbl, long block_size, int num_blocks) {
        throw new NotImplementedException("Anti-Caching is disabled for IPC ExecutionEngine");
    }


    @Override
    public VoltTable antiCacheEvictBlockInBatch(Table catalog_tbl, Table child_tbl, long block_size, int num_blocks) {
        throw new NotImplementedException("Anti-Caching is disabled for IPC ExecutionEngine");
  }

   
    @Override
    public void MMAPInitialize(File dbDir, long mapSize, long syncFrequency) throws EEException {
        throw new NotImplementedException("Storage MMAP is disabled for IPC ExecutionEngine");
    }
   
    // ARIES
    @Override
    public void ARIESInitialize(File dbDir, File logFile) throws EEException {
        throw new NotImplementedException("ARIES recovery is disabled for IPC ExecutionEngine");
    }
   
    @Override
    public long getArieslogBufferLength() {
        // XXX: do nothing, we only implement this for JNI now.
        throw new NotImplementedException("ARIES recovery is disabled for IPC ExecutionEngine");
    }

    @Override
    public void getArieslogData(int bufferLength, byte[] arieslogDataArray) {
        throw new NotImplementedException("ARIES recovery is disabled for IPC ExecutionEngine");
    }

    @Override
    public void doAriesRecoveryPhase(long replayPointer, long replayLogSize, long replayTxnId) {
        throw new NotImplementedException("ARIES recovery is disabled for IPC ExecutionEngine");
    }

    @Override
    public void freePointerToReplayLog(long ariesReplayPointer) {
        throw new NotImplementedException("ARIES recovery is disabled for IPC ExecutionEngine");
    }  

    @Override
    public long readAriesLogForReplay(long[] size) {
        throw new NotImplementedException("ARIES recovery is disabled for IPC ExecutionEngine");
    }
   
}
TOP

Related Classes of org.voltdb.jni.ExecutionEngineIPC

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.