Package edu.brown.benchmark.mapreduce

Source Code of edu.brown.benchmark.mapreduce.MapReduceLoader$AbstractTableGenerator

/***************************************************************************
*   Copyright (C) 2010 by H-Store Project                                 *
*   Brown University                                                      *
*   Massachusetts Institute of Technology                                 *
*   Yale University                                                       *
*                                                                         *
*   Permission is hereby granted, free of charge, to any person obtaining *
*   a copy of this software and associated documentation files (the       *
*   "Software"), to deal in the Software without restriction, including   *
*   without limitation the rights to use, copy, modify, merge, publish,   *
*   distribute, sublicense, and/or sell copies of the Software, and to    *
*   permit persons to whom the Software is furnished to do so, subject to *
*   the following conditions:                                             *
*                                                                         *
*   The above copyright notice and this permission notice shall be        *
*   included in all copies or substantial portions of the Software.       *
*                                                                         *
*   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       *
*   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    *
*   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*
*   IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR     *
*   OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, *
*   ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR *
*   OTHER DEALINGS IN THE SOFTWARE.                                       *
***************************************************************************/
package edu.brown.benchmark.mapreduce;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.concurrent.atomic.AtomicLong;

import org.apache.log4j.Logger;
import org.voltdb.VoltTable;
import org.voltdb.catalog.Table;

import edu.brown.api.BenchmarkComponent;
import edu.brown.catalog.CatalogUtil;
import edu.brown.utils.StringUtil;
import edu.brown.hstore.conf.HStoreConf;

public class MapReduceLoader extends BenchmarkComponent {
    private static final Logger LOG = Logger.getLogger(MapReduceLoader.class);
   
    // scale all table cardinalities by this factor
    private final double m_scalefactor;
   
    // When set to true, all operations will run single-threaded
    private boolean debug = true;
   
    // Data Generator Classes
    // TableName -> AbstactTableGenerator
    private final Map<String, AbstractTableGenerator> generators = new HashMap<String, AbstractTableGenerator>();
   
    // Table Sizes
    // TableName -> Tuple Count
    private final Map<String, AtomicLong> table_sizes = new HashMap<String, AtomicLong>();
   
    public static void main(String args[]) throws Exception {
        edu.brown.api.BenchmarkComponent.main(MapReduceLoader.class, args, true);
    }
   
    /**
     * Constructor
     * @param args
     */
    public MapReduceLoader(String[] args) {
        super(args);
       
        double scaleFactor = HStoreConf.singleton().client.scalefactor;
        for (String key : m_extraParams.keySet()) {
            String value = m_extraParams.get(key);

            // Scale Factor
            if (key.equalsIgnoreCase("CLIENT.SCALEFACTOR")) { // FIXME
                scaleFactor = Double.parseDouble(value);
            }
        } // FOR
        m_scalefactor = scaleFactor;   
        LOG.debug("m_scalefactor = " + m_scalefactor + "\n" + StringUtil.formatMaps(m_extraParams));
       
        // Histograms + Table Sizes + Generators
        for (String tableName : MapReduceConstants.TABLENAMES) {
            this.table_sizes.put(tableName, new AtomicLong(0l));
           
            if (tableName.equals(MapReduceConstants.TABLENAME_TABLEA)) {
                this.generators.put(tableName, new TABLEAGenerator());
            } else if (tableName.equals(MapReduceConstants.TABLENAME_TABLEB)) {
                this.generators.put(tableName, new TABLEBGenerator());
            }
        } // FOR
    }
   
    @Override
    public String[] getTransactionDisplayNames() {
        return new String[] {};
    }

    /**
     * Main execution loop for invoking all the data generator threads
     */
    @Override
    public void runLoop() {
        List<Thread> load_threads = new ArrayList<Thread>();
        for (final String tableName : MapReduceConstants.TABLENAMES) {
            load_threads.add(new Thread() {
                @Override
                public void run() {
                    generateTableData(tableName);
                }
            });
        } // FOR
       
        try {
            for (Thread thread : load_threads) {
                thread.start();
                if (this.debug) thread.join();
            }
            if (!this.debug) {
                for (Thread thread : load_threads) thread.join();
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
            System.exit(-1);
        }

        LOG.info("Finished generating data for all tables");
    }
   
    /**
     * Load the tuples for the given table name
     * @param tableName
     */
    protected void generateTableData(String tableName) {
        LOG.debug("Starting data generator for '" + tableName + "'");
        final AbstractTableGenerator generator = this.generators.get(tableName);
        assert(generator != null);
        long tableSize = generator.getTableSize();
        long batchSize = generator.getBatchSize();
        final AtomicLong table_ctr = this.table_sizes.get(tableName);
        VoltTable table = generator.getVoltTable();
       
        LOG.info("Loading " + tableSize + " tuples for table '" + tableName + "'");
        while (generator.hasMore()) {
            generator.addRow();
            if (table.getRowCount() >= batchSize) {
                if (table_ctr.get() % 100000 == 0) LOG.info(String.format(tableName + ": loading %d rows (id %d of %d)", table.getRowCount(), generator.getCount(), tableSize));
                loadVoltTable(tableName, table);
                table_ctr.addAndGet(table.getRowCount());
                table.clearRowData();
            }
        } // WHILE
        if (table.getRowCount() > 0) {
            LOG.info(tableName + ": loading final " + table.getRowCount() + " rows.");
            loadVoltTable(tableName, table);
            this.table_sizes.get(tableName).addAndGet(table.getRowCount());
            table.clearRowData();
        }
        LOG.info(tableName + ": Inserted " + this.table_sizes.get(tableName) + " tuples");
    }

    // ----------------------------------------------------------------
    // DATA GENERATION
    // ----------------------------------------------------------------
   
    protected abstract class AbstractTableGenerator {
        protected final String tableName;
        protected final Table catalog_tbl;
        protected final VoltTable table;
        protected Long tableSize;
        protected Long batchSize;
       
        protected final Object[] row;
        protected long count = 0;
       
        public AbstractTableGenerator(String tableName) {
            this.tableName = tableName;
            this.catalog_tbl = getCatalogContext().database.getTables().get(this.tableName);
            assert(this.catalog_tbl != null);
            this.table = CatalogUtil.getVoltTable(this.catalog_tbl);
            this.row = new Object[this.table.getColumnCount()];
           
            // Initialize dynamic parameters
            try {
                String field_name = "TABLESIZE_" + tableName;
                Field field_handle = MapReduceConstants.class.getField(field_name);
                assert(field_handle != null);
                this.tableSize = Math.round((Long)field_handle.get(null) * MapReduceLoader.this.m_scalefactor);

                field_name = "BATCHSIZE_" + tableName;
                field_handle = MapReduceConstants.class.getField(field_name);
                assert(field_handle != null);
                this.batchSize = (Long)field_handle.get(null);
            } catch (Exception ex) {
                LOG.error(ex);
                System.exit(1);
            }
            LOG.info("Preparing to load " + this.tableSize + " tuples for '" + this.tableName + "' [batchSize=" + this.batchSize + "]");
        }
       
        public boolean hasMore() {
            return (this.count < this.tableSize);
        }
       
        public VoltTable getVoltTable() {
            return this.table;
        }
       
        public Long getTableSize() {
            return this.tableSize;
        }
       
        public Long getBatchSize() {
            return this.batchSize;
        }
       
        public String getTableName() {
            return this.tableName;
        }
       
        public long getCount() {
            return this.count;
        }
       
        /**
         * Invoked by generateTableData() to create a new row in our temporary
         * table. We don't need to worry about batches, counts, or anything else. Just makin' tuples
         */
        public void addRow() {
            this.populateRow();
            this.count++;
            this.table.addRow(this.row);
        }
       
        protected abstract void populateRow();
    } // END CLASS
   
    /**
     * TABLEA Generator
     */
    protected class TABLEAGenerator extends AbstractTableGenerator {
       
        final Random rand = new Random();
       
        public TABLEAGenerator() {
            super(MapReduceConstants.TABLENAME_TABLEA);
        }
       
        @Override
        protected void populateRow() {
            int col = 0;
           
            // A_ID
            row[col++] = new Integer((int)this.count);
           
            // A_NAME
            row[col++] = String.format("%s-%04d", MapReduceConstants.NAME_PREFIX,
                                                  rand.nextInt(MapReduceConstants.NUM_UNIQUE_NAMES));
           
            // A_AGE
            row[col++] = rand.nextInt(MapReduceConstants.MAX_AGE);

            assert (col == this.table.getColumnCount());
        }
    } // END CLASS

    /**
     * TABLEB Generator
     */
    protected class TABLEBGenerator extends AbstractTableGenerator {
        private long current_a_id = 0;
        private long current_b_id = 0;
       
        public TABLEBGenerator() {
            super(MapReduceConstants.TABLENAME_TABLEB);
        }
       
        @Override
        protected void populateRow() {
            int col = 0;
           
            // B_ID
            row[col++] = new Integer((int)this.current_b_id);
           
            // B_A_ID
            row[col++] = new Integer((int)this.current_a_id);

            // B_VALUE
            row[col++] = "DEF456"; // FIXME
           
            assert (col == this.table.getColumnCount());
           
            if (++this.current_b_id > MapReduceConstants.TABLESIZE_TABLEB_MULTIPLIER) {
                this.current_b_id = 0;
                this.current_a_id++;
            }
        }
    } // END CLASS
}
TOP

Related Classes of edu.brown.benchmark.mapreduce.MapReduceLoader$AbstractTableGenerator

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.