Package org.voltdb.iv2

Source Code of org.voltdb.iv2.SysProcDuplicateCounter

/* 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.iv2;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import org.voltdb.VoltTable;
import org.voltdb.messaging.FragmentResponseMessage;
import org.voltdb.utils.MiscUtils;
import org.voltdb.utils.VoltTableUtil;

/**
* A special subclass of DuplicateCounter for multi-part
* system procedures that expect to see results from every
* site.  It unions the VoltTables in the offered
* FragmentResponses.
*/
public class SysProcDuplicateCounter extends DuplicateCounter
{
    Map<Integer, List<VoltTable>> m_alldeps =
        new HashMap<Integer, List<VoltTable>>();

    SysProcDuplicateCounter(
            long destinationHSId,
            long realTxnId,
            List<Long> expectedHSIds, String procName)    {
        super(destinationHSId, realTxnId, expectedHSIds, procName);
    }

    /**
     * It is possible that duplicate counter will get mixed dummy responses and
     * real responses from replicas, think elastic join and rejoin. The
     * requirement here is that the duplicate counter should never mix these two
     * types of responses together in the list of tables for a given
     * dependency. Mixing them will cause problems for union later. In case of
     * mixed responses, real responses are always preferred. As long as there
     * are real responses for a dependency, dummy responses will be dropped for
     * that dependency.
     */
    @Override
    int offer(FragmentResponseMessage message)
    {
        long hash = 0;
        for (int i = 0; i < message.getTableCount(); i++) {
            int depId = message.getTableDependencyIdAtIndex(i);
            VoltTable dep = message.getTableAtIndex(i);
            List<VoltTable> tables = m_alldeps.get(depId);
            if (tables == null)
            {
                tables = new ArrayList<VoltTable>();
                m_alldeps.put(depId, tables);
            }

            if (!message.isRecovering()) {
                /*
                 * If the current table is a real response, check if
                 * any previous responses were dummy, if so, replace
                 * the dummy ones with this legit response.
                 */
                if (!tables.isEmpty() && tables.get(0).getStatusCode() == VoltTableUtil.NULL_DEPENDENCY_STATUS) {
                    tables.clear();
                }

                // Only update the hash with non-dummy responses
                hash ^= MiscUtils.cheesyBufferCheckSum(dep.getBuffer());
            } else {
                /* If it's a dummy response, record it if and only if
                 * it's the first response. If the previous response
                 * is a real response, we don't want the dummy response.
                 * If the previous one is also a dummy, one should be
                 * enough.
                 */
                if (!tables.isEmpty()) {
                    continue;
                }
            }

            tables.add(dep);
        }

        return checkCommon(hash, message.isRecovering(), null, message);
    }

    @Override
    FragmentResponseMessage getLastResponse()
    {
        FragmentResponseMessage unioned =
            new FragmentResponseMessage((FragmentResponseMessage)m_lastResponse);
        // union up all the deps we've collected and jam them in
        for (Entry<Integer, List<VoltTable>> dep : m_alldeps.entrySet()) {
            VoltTable grouped = VoltTableUtil.unionTables(dep.getValue());
            unioned.addDependency(dep.getKey(), grouped);
        }
        return unioned;
    }
}
TOP

Related Classes of org.voltdb.iv2.SysProcDuplicateCounter

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.