Package edu.brown.benchmark.locality

Source Code of edu.brown.benchmark.locality.LocalityLoader

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

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

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

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

public class LocalityLoader extends BenchmarkComponent {
    private static final Logger LOG = Logger.getLogger(LocalityLoader.class);

    // Composite Id
    private static final long COMPOSITE_ID_MASK = 4294967295l; // (2^32)-1
    private static final int COMPOSITE_ID_OFFSET = 32;

    // 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(LocalityLoader.class, args, true);
    }

    /**
     * Constructor
     *
     * @param args
     */
    public LocalityLoader(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;
        System.err.println("m_scalefactor = " + m_scalefactor + "\n" + StringUtil.formatMaps(m_extraParams));

        // Histograms + Table Sizes + Generators
        for (String tableName : LocalityConstants.TABLENAMES) {
            this.table_sizes.put(tableName, new AtomicLong(0l));

            if (tableName.equals(LocalityConstants.TABLENAME_TABLEA)) {
                this.generators.put(tableName, new TABLEAGenerator());
            } else if (tableName.equals(LocalityConstants.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 : LocalityConstants.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");
    }

    /**
     * @param debug
     */
    protected void setDebug(boolean debug) {
        this.debug = debug;
    }

    protected static Long encodeCompositeId(long a_id, long id) {
        return (a_id | id << COMPOSITE_ID_OFFSET);
    }

    /**
     * Returns the pieces of a composite id The first element of the returned
     * array will be the A_ID portion of the composite and the second element
     * will be the ID portion
     *
     * @param composite_id
     * @return
     */
    protected static long[] decodeCompositeId(long composite_id) {
        long values[] = { composite_id & COMPOSITE_ID_MASK, composite_id >> COMPOSITE_ID_OFFSET };
        return (values);
    }

    // ----------------------------------------------------------------
    // DATA GENERATION
    // ----------------------------------------------------------------

    protected abstract class AbstractTableGenerator {
        protected final String tableName;
        protected final VoltTable table;
        protected Long tableSize;
        protected Long batchSize;

        protected final Object[] row;
        protected long count = 0;

        public AbstractTableGenerator(String tableName, VoltTable table) {
            this.tableName = tableName;
            this.table = table;
            this.row = new Object[this.table.getColumnCount()];

            // Initialize dynamic parameters
            try {
                String field_name = "TABLESIZE_" + tableName;
                Field field_handle = LocalityConstants.class.getField(field_name);
                assert (field_handle != null);
                this.tableSize = Math.round((Long) field_handle.get(null) * LocalityLoader.this.m_scalefactor);

                field_name = "BATCHSIZE_" + tableName;
                field_handle = LocalityConstants.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 {

        public TABLEAGenerator() {
            super(LocalityConstants.TABLENAME_TABLEA, LocalityTables.initializeTableA());
        }

        @Override
        protected void populateRow() {
            int col = 0;

            // A_ID
            row[col++] = new Integer((int) this.count);

            // A_VALUE
            row[col++] = "ABC123"; // FIXME

            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(LocalityConstants.TABLENAME_TABLEB, LocalityTables.initializeTableB());
        }

        @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 > LocalityConstants.TABLESIZE_TABLEB_MULTIPLIER) {
                this.current_b_id = 0;
                this.current_a_id++;
            }
        }
    } // END CLASS
}
TOP

Related Classes of edu.brown.benchmark.locality.LocalityLoader

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.