Package org.voltdb

Source Code of org.voltdb.ClientResponseDebug$QueryEstimate

package org.voltdb;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.TreeMap;

import org.voltdb.catalog.Statement;
import org.voltdb.messaging.FastDeserializer;
import org.voltdb.messaging.FastSerializable;
import org.voltdb.messaging.FastSerializer;
import org.voltdb.utils.Pair;

import edu.brown.catalog.special.CountedStatement;
import edu.brown.hstore.estimators.EstimatorState;
import edu.brown.hstore.estimators.Estimate;
import edu.brown.hstore.txns.LocalTransaction;
import edu.brown.utils.PartitionSet;
import edu.brown.utils.StringUtil;

/**
* Special wrapper object that contains extra information about a transaction
*/
public class ClientResponseDebug implements FastSerializable {
   
    /**
     * Inner class that converts CountedStatements into ids+counter, since
     * we won't have the catalog when we deserialize it on the client side
     */
    private class QueryEstimate implements FastSerializable {
        /**
         * Pair -> StatementId : StatementCounter
         */
        private final List<Pair<Integer, Integer>> statements = new ArrayList<Pair<Integer, Integer>>();
        private int partition;
       
        public QueryEstimate() {
            // Nothing to do
        }
       
        public QueryEstimate(int partition, Collection<CountedStatement> statements) {
            this.partition = partition;
            for (CountedStatement cntStmt : statements) {
                this.statements.add(Pair.of(cntStmt.statement.getId(), cntStmt.counter));   
            } // FOR
        }
       
        @Override
        public void readExternal(FastDeserializer in) throws IOException {
            this.partition = in.readInt();
            int num_statements = in.readShort();
            this.statements.clear();
            for (int i = 0; i < num_statements; i++) {
                int stmtId = in.readInt();
                int stmtCtr = in.readShort();
                this.statements.add(Pair.of(stmtId, stmtCtr));
            } // FOR
            assert(num_statements == this.statements.size());
        }
        @Override
        public void writeExternal(FastSerializer out) throws IOException {
            out.writeInt(this.partition);
            out.writeShort(this.statements.size());
            for (Pair<Integer, Integer> stmt : this.statements) {
                out.writeInt(stmt.getFirst());
                out.writeShort(stmt.getSecond());
            } // FOR
        }
        @Override
        public String toString() {
            return String.format("{Partition #%02d - %s}", this.partition, this.statements);
        }
    } // CLASS
   
    private boolean predict_singlePartition;
    private boolean predict_abortable;
    private boolean predict_readOnly;
    private final PartitionSet predict_touchedPartitions = new PartitionSet();
   
    private String estimateType;
    private int estimateUpdateCount = 0;

    /**
     * Partition -> List<QueryEstimate>
     */
    private final Map<Integer, List<QueryEstimate>> estimateRemoteQueryUpdates = new TreeMap<Integer, List<QueryEstimate>>();

   
    /**
     * Partitions that were marked for early 2PC
     */
    private final PartitionSet early_preparePartitions = new PartitionSet();
   
    private boolean prefetched = false;
    private final PartitionSet exec_touchedPartitions = new PartitionSet();
   
    // ----------------------------------------------------------------------------
    // INITIALIZATION
    // ----------------------------------------------------------------------------
   
    public ClientResponseDebug() {
        // Needed for serialization
    }
   
    public ClientResponseDebug(LocalTransaction ts) {
        this.predict_singlePartition = ts.isPredictSinglePartition();
        this.predict_abortable = ts.isPredictAbortable();
        this.predict_readOnly = ts.isPredictReadOnly();
        this.predict_touchedPartitions.addAll(ts.getPredictTouchedPartitions());
        this.prefetched = ts.hasPrefetchQueries();
        this.exec_touchedPartitions.addAll(ts.getTouchedPartitions().values());
       
        if (this.predict_singlePartition == false) {
            this.early_preparePartitions.addAll(ts.getDonePartitions());
        }
       
        EstimatorState t_state = ts.getEstimatorState();
        if (t_state != null) {
            this.estimateType = t_state.getClass().getSimpleName();
            for (Estimate est : t_state.getEstimates()) {
                this.estimateUpdateCount++;
                for (int partition : this.exec_touchedPartitions) {
                    if (est.hasQueryEstimate(partition)) {
                        Collection<CountedStatement> stmts = est.getQueryEstimate(partition);
                        this.addQueryEstimate(new QueryEstimate(partition, stmts));
                    }
                } // FOR (partition)
            } // FOR (estimate)
        }
    }
   
    protected void addQueryEstimate(QueryEstimate query_estimate) {
        List<QueryEstimate> estimates = this.estimateRemoteQueryUpdates.get(query_estimate.partition);
        if (estimates == null) {
            estimates = new ArrayList<QueryEstimate>();
            this.estimateRemoteQueryUpdates.put(query_estimate.partition, estimates);
        }
        estimates.add(query_estimate);
    }
   
    // ----------------------------------------------------------------------------
    // DATA METHODS
    // ----------------------------------------------------------------------------

    public boolean isPredictSinglePartition() {
        return this.predict_singlePartition;
    }

    public boolean isPredictAbortable() {
        return this.predict_abortable;
    }

    public boolean isPredictReadOnly() {
        return this.predict_readOnly;
    }

    public PartitionSet getPredictTouchedPartitions() {
        return this.predict_touchedPartitions;
    }

    public PartitionSet getExecTouchedPartitions() {
        return this.exec_touchedPartitions;
    }
   
    /**
     * Get the set of partitions that were marked for early 2PC prepare
     * @return
     */
    public PartitionSet getEarlyPreparePartitions() {
        return this.early_preparePartitions;
    }

    /**
     * Returns true if this transaction was executed with prefetched queries.
     * @return
     */
    public boolean hadPrefetchedQueries() {
        return this.prefetched;
    }
   
    public String getEstimatorType() {
        return (this.estimateType);
    }
    public int getEstimatorUpdateCount() {
        return (this.estimateUpdateCount);
    }
   
    public List<CountedStatement>[] getRemoteQueryEstimates(CatalogContext catalogContext, int partition) {
        List<QueryEstimate> estimates = this.estimateRemoteQueryUpdates.get(partition);
        int num_estimates = (estimates != null ? estimates.size() : 0);
        @SuppressWarnings("unchecked")
        List<CountedStatement> result[] = (List<CountedStatement>[])new List<?>[num_estimates];
        for (int i = 0; i < result.length; i++) {
            result[i] = new ArrayList<CountedStatement>();
            QueryEstimate query_est = estimates.get(i);
            for (Pair<Integer, Integer> p : query_est.statements) {
                Statement stmt =  catalogContext.getStatementById(p.getFirst());
                assert(stmt != null) : "Invalid Statement id '" + p.getFirst() + "'";
                result[i].add(new CountedStatement(stmt, p.getSecond()));
            } // FOR
        } // FOR
        return (result);
    }
   
    // ----------------------------------------------------------------------------
    // SERIALIZATION METHODS
    // ----------------------------------------------------------------------------
   
   
    @Override
    public void readExternal(FastDeserializer in) throws IOException {
        this.predict_singlePartition = in.readBoolean();
        this.predict_abortable = in.readBoolean();
        this.predict_readOnly = in.readBoolean();
        this.predict_touchedPartitions.readExternal(in);
        this.early_preparePartitions.readExternal(in);
        this.prefetched = in.readBoolean();
        this.exec_touchedPartitions.readExternal(in);
       
        // TXN ESTIMATE INFO
        this.estimateType = in.readString();
        this.estimateUpdateCount = in.readInt();
       
        // QUERY ESTIMATES
        int num_partitions = in.readShort();
        for (int i = 0; i < num_partitions; i++) {
            int partition = in.readInt();
            int num_estimates = in.readShort();
            for (int j = 0; j < num_estimates; j++) {
                QueryEstimate query_est = new QueryEstimate();
                query_est.readExternal(in);
                assert(partition == query_est.partition);
                this.addQueryEstimate(query_est);   
            } // FOR
        } // FOR
    }

    @Override
    public void writeExternal(FastSerializer out) throws IOException {
        out.writeBoolean(this.predict_singlePartition);
        out.writeBoolean(this.predict_abortable);
        out.writeBoolean(this.predict_readOnly);
        this.predict_touchedPartitions.writeExternal(out);
        this.early_preparePartitions.writeExternal(out);
        out.writeBoolean(this.prefetched);
        this.exec_touchedPartitions.writeExternal(out);
       
        // TXN ESTIMATE INFO
        out.writeString(this.estimateType);
        out.writeInt(this.estimateUpdateCount);
       
        // QUERY ESTIMATES
        out.writeShort(this.estimateRemoteQueryUpdates.size());
        for (Entry<Integer, List<QueryEstimate>> e : this.estimateRemoteQueryUpdates.entrySet()) {
            out.writeInt(e.getKey());
            out.writeShort(e.getValue().size());
            for (QueryEstimate query_est : e.getValue()) {
                query_est.writeExternal(out);   
            } // FOR
        } // FOR
    }
   
    @Override
    public String toString() {
        List<Map<String, Object>> maps = new ArrayList<Map<String,Object>>();
        Map<String, Object> m;
       
        m = new LinkedHashMap<String, Object>();
        m.put("Predict Single-Partitioned", this.predict_singlePartition);
        m.put("Predict Touched Partitions", this.predict_touchedPartitions);
        m.put("Predict Read Only", this.predict_readOnly);
        m.put("Predict Abortable", this.predict_abortable);
        m.put("Had Prefetched Queries", this.prefetched);
        maps.add(m);
       
        m = new LinkedHashMap<String, Object>();
        m.put("Estimator Type", this.estimateType);
        m.put("Estimate Updates", this.estimateUpdateCount);
        m.put("Remote Query Estimates", this.estimateRemoteQueryUpdates);
        maps.add(m);
       
        m = new LinkedHashMap<String, Object>();
        m.put("Exec Touched Partitions", this.exec_touchedPartitions);
        m.put("Early 2PC Partitions", this.early_preparePartitions);
        maps.add(m);
       
        return StringUtil.formatMaps(maps.toArray(new Map<?, ?>[maps.size()]));
    }

}
TOP

Related Classes of org.voltdb.ClientResponseDebug$QueryEstimate

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.