Package org.voltdb

Source Code of org.voltdb.CatalogContext

/* This file is part of VoltDB.
* Copyright (C) 2008-2010 VoltDB L.L.C.
*
* 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;

import java.io.File;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

import org.voltdb.catalog.Catalog;
import org.voltdb.catalog.CatalogMap;
import org.voltdb.catalog.Cluster;
import org.voltdb.catalog.Database;
import org.voltdb.catalog.Host;
import org.voltdb.catalog.Partition;
import org.voltdb.catalog.PlanFragment;
import org.voltdb.catalog.Procedure;
import org.voltdb.catalog.Site;
import org.voltdb.catalog.Statement;
import org.voltdb.catalog.Table;
import org.voltdb.utils.JarClassLoader;

import edu.brown.catalog.CatalogUtil;
import edu.brown.mappings.ParameterMappingsSet;
import edu.brown.mappings.ParametersUtil;
import edu.brown.utils.PartitionSet;

public class CatalogContext {

    // THE CATALOG!
    public final Catalog catalog;

    // PUBLIC IMMUTABLE CACHED INFORMATION
    public final Cluster cluster;
    public final Database database;
    public final CatalogMap<Host> hosts;
    public final CatalogMap<Site> sites;
   
    // ParameterMappingsSet
    public final ParameterMappingsSet paramMappings;
   
    /** The total number of unique Hosts in the cluster */
    public final int numberOfHosts;
    /** The total number of unique Sites in the cluster */
    public final int numberOfSites;
    /** The total number of unique Partitions in the cluster */
    public final int numberOfPartitions;
    /** The total number of unique tables in the database */
    public final int numberOfTables;
   
    // PRIVATE
    public final File jarPath;
    private final JarClassLoader catalogClassLoader;

    // ------------------------------------------------------------
    // PARTITIONS
    // ------------------------------------------------------------
   
    private final Partition partitions[];
    private final PartitionSet partitionIdCollection = new PartitionSet();
    private final Integer partitionIdArray[];
   
    /** PartitionId -> Singleton set of that PartitionId */
    private final PartitionSet partitionSingletons[];
   
    /** PartitionId -> SiteId */
    private final int partitionSiteXref[];
   
    // ------------------------------------------------------------
    // PROCEDURES
    // ------------------------------------------------------------
   
    public final CatalogMap<Procedure> procedures;
   
    private final Collection<Procedure> regularProcedures = new ArrayList<Procedure>();
    private final Collection<Procedure> sysProcedures = new ArrayList<Procedure>();
    private final Collection<Procedure> mrProcedures = new ArrayList<Procedure>();
    private final Procedure proceduresArray[];
   
    // ------------------------------------------------------------
    // STATEMENTS
    // ------------------------------------------------------------
   
    private final Map<Integer, Statement> stmtIdXref = new HashMap<Integer, Statement>();
   
    // ------------------------------------------------------------
    // TABLES
    // ------------------------------------------------------------
   
    private final Collection<Table> sysTables = new ArrayList<Table>();
    private final Collection<Table> dataTables = new ArrayList<Table>();
    private final Collection<Table> viewTables = new ArrayList<Table>();
    private final Collection<Table> mapReduceTables = new ArrayList<Table>();
    private final Collection<Table> replicatedTables = new ArrayList<Table>();
    private final Collection<Table> evictableTables = new ArrayList<Table>();
   
    // ------------------------------------------------------------
    // PLANFRAGMENTS
    // ------------------------------------------------------------
   
    /**
     * PlanFragmentId -> TableIds Read/Written
     */
    private final Map<Long, int[]> fragmentReadTables = new HashMap<Long, int[]>();
    private final Map<Long, int[]> fragmentWriteTables = new HashMap<Long, int[]>();
   
    public CatalogContext(Catalog catalog) {
        this(catalog, (File)null);
    }

    public CatalogContext(Catalog catalog, String pathToCatalogJar) {
        this(catalog, new File(pathToCatalogJar));
    }
   
    public CatalogContext(Catalog catalog, File pathToCatalogJar) {
        // check the heck out of the given params in this immutable class
        assert(catalog != null);
        if (catalog == null) {
            throw new RuntimeException("Can't create CatalogContext with null catalog.");
        }

        this.jarPath = pathToCatalogJar;
        this.catalog = catalog;
        this.cluster = CatalogUtil.getCluster(this.catalog);
        this.database = CatalogUtil.getDatabase(this.catalog);
        this.hosts = this.cluster.getHosts();
        this.sites = this.cluster.getSites();
       
        if (this.jarPath != null) {
            this.catalogClassLoader = new JarClassLoader(this.jarPath.getAbsolutePath());
            this.paramMappings = ParametersUtil.getParameterMappingsSetFromJar(this.database, this.jarPath);
        } else {
            this.catalogClassLoader = null;
            this.paramMappings = null;
        }
       
        // ------------------------------------------------------------
        // PROCEDURES
        // ------------------------------------------------------------
        this.procedures = database.getProcedures();
        this.proceduresArray = new Procedure[this.procedures.size()+1];
        for (Procedure proc : this.procedures) {
            this.proceduresArray[proc.getId()] = proc;
            if (proc.getSystemproc()) {
                this.sysProcedures.add(proc);
            }
            else if (proc.getMapreduce()) {
                this.mrProcedures.add(proc);
            }
            else {
                this.regularProcedures.add(proc);
            }
        } // FOR
       
        // count nodes
        this.numberOfHosts = cluster.getHosts().size();

        // count exec sites
        this.numberOfSites = cluster.getSites().size();
       
        // ------------------------------------------------------------
        // PARTITIONS
        // ------------------------------------------------------------
        this.numberOfPartitions = cluster.getNum_partitions();
        this.partitions = new Partition[this.numberOfPartitions];
        this.partitionIdArray = new Integer[this.numberOfPartitions];
        this.partitionSingletons = new PartitionSet[this.numberOfPartitions];
        this.partitionSiteXref = new int[this.numberOfPartitions];
        for (Partition part : CatalogUtil.getAllPartitions(catalog)) {
            int p = part.getId();
            this.partitions[p] = part;
            this.partitionIdArray[p] = Integer.valueOf(p);
            this.partitionSingletons[p] = new PartitionSet(p);
            this.partitionIdCollection.add(this.partitionIdArray[p]);
            this.partitionSiteXref[part.getId()] = ((Site)part.getParent()).getId();
        } // FOR
       
        // ------------------------------------------------------------
        // TABLES
        // ------------------------------------------------------------
        for (Table tbl : this.database.getTables()) {
            // SYSTEM TABLE
            if (tbl.getSystable()) {
                this.sysTables.add(tbl);
            }
            // MAPREDUCE TABLE
            else if (tbl.getMapreduce()) {
                this.mapReduceTables.add(tbl);
            }
            // MATERIALIZED VIEW TABLE
            else if (tbl.getMaterializer() != null) {
                this.viewTables.add(tbl);
            }
            // REGULAR DATA TABLE
            else {
                this.dataTables.add(tbl);
                if (tbl.getIsreplicated()) {
                    this.replicatedTables.add(tbl);
                }
                if (tbl.getEvictable() && !tbl.getBatchevicted()) {
                    this.evictableTables.add(tbl);
                }
            }
        } // FOR
        this.numberOfTables = database.getTables().size();
       
        // PLANFRAGMENTS
        this.initPlanFragments();
    }
   
    private void initPlanFragments() {
        Set<PlanFragment> allFrags = new HashSet<PlanFragment>();
        for (Procedure proc : database.getProcedures()) {
            for (Statement stmt : proc.getStatements()) {
                allFrags.clear();
                allFrags.addAll(stmt.getFragments());
                allFrags.addAll(stmt.getMs_fragments());
                for (PlanFragment frag : allFrags) {
                    Collection<Table> tables = CatalogUtil.getReferencedTables(frag);
                    int tableIds[] = new int[tables.size()];
                    int i = 0;
                    for (Table tbl : tables) {
                        tableIds[i++] = tbl.getRelativeIndex();
                    } // FOR
                    if (frag.getReadonly()) {
                        this.fragmentReadTables.put(Long.valueOf(frag.getId()), tableIds);
                    } else {
                        this.fragmentWriteTables.put(Long.valueOf(frag.getId()), tableIds);
                    }
                } // FOR (frag)
            } // FOR (stmt)
        } // FOR (proc)
    }
   

    public CatalogContext deepCopy() {
        return new CatalogContext(catalog.deepCopy(), jarPath);
    }

    public CatalogContext update(String pathToNewJar, String diffCommands) {
        Catalog newCatalog = catalog.deepCopy();
        newCatalog.execute(diffCommands);
        CatalogContext retval = new CatalogContext(newCatalog, pathToNewJar);
        return retval;
    }

    /**
     * Given a class name in the catalog jar, loads it from the jar, even if the
     * jar is served from a url and isn't in the classpath.
     *
     * @param procedureClassName The name of the class to load.
     * @return A java Class variable assocated with the class.
     * @throws ClassNotFoundException if the class is not in the jar file.
     */
    public Class<?> classForProcedure(String procedureClassName) throws ClassNotFoundException {
        //System.out.println("Loading class " + procedureClassName);

        // this is a safety mechanism to prevent catalog classes overriding voltdb stuff
        if (procedureClassName.startsWith("org.voltdb."))
            return Class.forName(procedureClassName);

        // look in the catalog for the file
        return catalogClassLoader.loadClass(procedureClassName);
    }
   
   
    // ------------------------------------------------------------
    // SITES
    // ------------------------------------------------------------
   
    /**
     * Return the unique Site catalog object for the given id
     * @param catalog_item
     * @return
     */
    public Site getSiteById(int site_id) {
        assert(site_id >= 0);
        return (this.sites.get("id", site_id));
    }
   
    /**
     * Return the site id for the given partition
     * @param partition_id
     * @return
     */
    public int getSiteIdForPartitionId(int partition_id) {
        return (this.partitionSiteXref[partition_id]);
    }
   
    /**
     * Return the site for the given partition
     * @param partition
     * @return
     */
    public Site getSiteForPartition(int partition) {
        int siteId = this.partitionSiteXref[partition];
        return (this.getSiteById(siteId));
    }

    // ------------------------------------------------------------
    // PARTITIONS
    // ------------------------------------------------------------
   
    /**
     * Return an array containing all the Partition handles in the cluster
     */
    public Partition[] getAllPartitions() {
        return (this.partitions);
    }
   
    /**
     * Return the Partition catalog object for the given PartitionId
     * @param id
     * @return
     */
    public Partition getPartitionById(int id) {
        return (this.partitions[id]);
    }
   
    /**
     * Return all the partition ids in this H-Store database cluster
     */
    public PartitionSet getAllPartitionIds() {
        return (this.partitionIdCollection);
    }
   
    /**
     * Return all the partition ids in this H-Store database cluster
     */
    public Integer[] getAllPartitionIdArray() {
        return (this.partitionIdArray);
    }
   
    /**
     * Return a PartitionSet that only contains the given partition id
     * @param partition
     */
    public PartitionSet getPartitionSetSingleton(int partition) {
        return (this.partitionSingletons[partition]);
    }
   
    // ------------------------------------------------------------
    // TABLES + COLUMNS
    // ------------------------------------------------------------

    /**
     * Return the Table for the given name
     * @param tableName
     */
    public Table getTableByName(String tableName) {
        return (this.database.getTables().getIgnoreCase(tableName));
    }
   
    /**
     * Return the Table for the given id
     * @param tableId
     */
    public Table getTableById(int tableId) {
        // HACK HACK HACK
        assert(tableId-1 >= 0);
        Table tables[] = this.database.getTables().values();
        if (tableId-1 >= tables.length) {
            String msg = "Invalid tableId '" + tableId + "'";
            throw new IllegalArgumentException(msg);
        }
        return (tables[tableId-1]);
    }
   
    /**
     * Return all of the internal system tables for the database
     */
    public Collection<Table> getSysTables() {
        return (sysTables);
    }

    /**
     * Return all of the user-defined data tables for the database
     */
    public Collection<Table> getDataTables() {
        return (dataTables);
    }
   
    /**
     * Return all of the materialized view tables for the database
     */
    public Collection<Table> getViewTables() {
        return (viewTables);
    }

    /**
     * Return all of the MapReduce input data tables for the database
     */
    public Collection<Table> getMapReduceTables() {
        return (mapReduceTables);
    }
   
    /**
     * Return all of the replicated tables for the database
     */
    public Collection<Table> getReplicatedTables() {
        return (replicatedTables);
    }
   
    /**
     * Return all of the evictable tables for the database
     */
    public Collection<Table> getEvictableTables() {
        return (evictableTables);
    }

    // ------------------------------------------------------------
    // PROCEDURES
    // ------------------------------------------------------------
   
    public Procedure getProcedureById(int procId) {
        if (procId >= 0 && procId < this.proceduresArray.length) {
            return (this.proceduresArray[procId]);
        }
        return (null);
    }
   
    /**
     * Return all of the regular transactional Procedures in the catalog
     */
    public Collection<Procedure> getRegularProcedures() {
        return (this.regularProcedures);
    }
   
    /**
     * Return all of the internal system Procedures in the catalog
     */
    public Collection<Procedure> getSysProcedures() {
        return (this.sysProcedures);
    }
   
    /**
     * Return all of the MapReduce Procedures in the catalog
     */
    public Collection<Procedure> getMapReduceProcedures() {
        return (this.mrProcedures);
    }
   
    // ------------------------------------------------------------
    // STATEMENTS
    // ------------------------------------------------------------
   
    public Statement getStatementById(int stmtId) {
        // HACK: The first call will actually build the cache
        if (this.stmtIdXref.isEmpty()) {
            synchronized (this.stmtIdXref) {
                if (this.stmtIdXref.isEmpty()) {
                    for (Procedure catalog_proc : this.procedures.values()) {
                        for (Statement catalog_stmt : catalog_proc.getStatements().values()) {
                            this.stmtIdXref.put(catalog_stmt.getId(), catalog_stmt);
                        } // FOR (stmt)
                    } // FOR (proc)
                }
            } // SYNCH
        }
        return (this.stmtIdXref.get(stmtId));
    }
   
    // ------------------------------------------------------------
    // PLANFRAGMENTS
    // ------------------------------------------------------------
   
    /**
     * Return the tableIds that are read by this PlanFragment
     * @param planFragmentId
     * @return
     */
    public int[] getReadTableIds(Long planFragmentId) {
        return (this.fragmentReadTables.get(planFragmentId));
    }

    /**
     * Return the tableIds that are written by this PlanFragment
     * @param planFragmentId
     * @return
     */
    public int[] getWriteTableIds(Long planFragmentId) {
        return (this.fragmentWriteTables.get(planFragmentId));
    }
}
TOP

Related Classes of org.voltdb.CatalogContext

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.