Package edu.brown.benchmark.wikipedia

Source Code of edu.brown.benchmark.wikipedia.WikipediaClient

/*******************************************************************************
* oltpbenchmark.com
*  Project Info:  http://oltpbenchmark.com
*  Project Members:    Carlo Curino <carlo.curino@gmail.com>
*         Evan Jones <ej@evanjones.ca>
*         DIFALLAH Djellel Eddine <djelleleddine.difallah@unifr.ch>
*         Andy Pavlo <pavlo@cs.brown.edu>
*         CUDRE-MAUROUX Philippe <philippe.cudre-mauroux@unifr.ch> 
*          Yang Zhang <yaaang@gmail.com>
*
*  This library 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.0 of the License, or (at your option) any later version.
*
*  This library 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 Lesser General Public License for more details.
******************************************************************************/
package edu.brown.benchmark.wikipedia;

import java.io.IOException;
import java.util.Random;

import org.apache.log4j.Logger;
import org.voltdb.VoltProcedure.VoltAbortException;
import org.voltdb.VoltTable;
import org.voltdb.client.Client;
import org.voltdb.client.ClientResponse;
import org.voltdb.client.ProcedureCallback;

import edu.brown.api.BenchmarkComponent;
import edu.brown.benchmark.wikipedia.procedures.GetPageAnonymous;
import edu.brown.benchmark.wikipedia.util.TextGenerator;
import edu.brown.benchmark.wikipedia.util.WikipediaUtil;
import edu.brown.logging.LoggerUtil;
import edu.brown.logging.LoggerUtil.LoggerBoolean;
import edu.brown.rand.RandomDistribution.Flat;
import edu.brown.rand.RandomDistribution.FlatHistogram;
import edu.brown.rand.RandomDistribution.Zipf;
import edu.brown.statistics.ObjectHistogram;
import edu.brown.utils.StringUtil;

public class WikipediaClient extends BenchmarkComponent {
    private static final Logger LOG = Logger.getLogger(WikipediaClient.class);
    private static final LoggerBoolean debug = new LoggerBoolean();
    private static final LoggerBoolean trace = new LoggerBoolean();
    static {
        LoggerUtil.attachObserver(LOG, debug, trace);
    }

  private Random randGenerator = new Random();
  private final WikipediaUtil util;

 
  private final Flat flat_users;
  private final Zipf zipf_pages;
  private final Flat flat_pages;
 
    /**
     * Set of transactions structs with their appropriate parameters
     */
    public static enum Transaction {
        ADD_WATCHLIST("Add WatchList", WikipediaConstants.FREQUENCY_ADD_WATCHLIST),
        GET_PAGE_ANONYMOUS("Get Page Anonymous", WikipediaConstants.FREQUENCY_GET_PAGE_ANONYMOUS),
        GET_PAGE_AUTHENTICATED("Get Page Authenticated", WikipediaConstants.FREQUENCY_GET_PAGE_AUTHENTICATED),
        REMOVE_WATCHLIST("Remove Watch List", WikipediaConstants.FREQUENCY_REMOVE_WATCHLIST),
        UPDATE_PAGE("Update Page", WikipediaConstants.FREQUENCY_UPDATE_PAGE);

        /**
         * Constructor
         */
        private Transaction (String displayName, int weight) {
            this.displayName = displayName;
            this.callName = displayName.replace(" ", "");
            this.weight = weight;
        }
        public final String displayName;
        public final String callName;
        public final int weight; // probability (in terms of percentage) the
        // transaction gets executed
       
        public static Transaction getTransaction (String callname) {
            Transaction res = null;
            for (Transaction t : Transaction.values()) {
                if (callname.equals(t.callName))
                    res = t;
            }
            return res;
        }
       
    }
 
    /**
     * Callback Class
     * @author xin
     *
     */
    private class WikipediaCallback implements ProcedureCallback {
        private final int idx;
        public WikipediaCallback(int idx) {
            super();
            this.idx = idx;
        }
        @Override
        public void clientCallback(ClientResponse clientResponse) {
            //if (debug.val) LOG.debug(clientResponse);
           
            // Increment the BenchmarkComponent's internal counter on the
            // number of transactions that have been completed
            incrementTransactionCounter(clientResponse, this.idx);
        }
    } // END CLASS
   
   
    /**
     * Data Members
     */

    // Storing the ordinals of transaction per wikipedia probability distribution
    private final FlatHistogram<Transaction> txnWeights;
//    private final int[] txnWeights = new int[100];

    // Callbacks
    protected final WikipediaCallback callbacks[];

    /**
     * Main method
     *
     * @param args
     */
    public static void main(String[] args) {
        BenchmarkComponent.main(WikipediaClient.class, args, false);
    }
   
    /**
     * Constructor
     * @param args
     */
   
    public WikipediaClient(String[] args) {
        super(args);
       
        // Initialize the sampling table
        ObjectHistogram<Transaction> txns = new ObjectHistogram<Transaction>();
        for (Transaction t : Transaction.values()) {
            Integer weight = this.getTransactionWeight(t.callName);
            if (weight == null) weight = t.weight;
            txns.put(t, weight);
        } // FOR
        assert(txns.getSampleCount() == 100) : txns;
        this.txnWeights = new FlatHistogram<Transaction>(this.randGenerator, txns);
        if (debug.val) LOG.debug("Transaction Workload Distribution:\n" + txns);
       
        // Setup callbacks
        int num_txns = Transaction.values().length;
        this.callbacks = new WikipediaCallback[num_txns];
        for (int i = 0; i < num_txns; i++) {
            this.callbacks[i] = new WikipediaCallback(i);
        } // FOR
       
        this.util = new WikipediaUtil(this.randGenerator, this.getScaleFactor());
       
        this.flat_users = new Flat(this.randGenerator, 1, util.num_users);
        this.zipf_pages = new Zipf(this.randGenerator, 1, util.num_pages, WikipediaConstants.USER_ID_SIGMA);
        this.flat_pages = new Flat(this.randGenerator, 1, util.num_pages);
    }
   
    /**
     * Return a transaction randomly selected per WikipediaClient probability specs
     */
    private Transaction selectTransaction() {
        // Transaction force = null; // (this.getClientId() == 0 ?
        // Transaction.INSERT_CALL_FORWARDING :
        // Transaction.GET_SUBSCRIBER_DATA); //
        // Transaction.INSERT_CALL_FORWARDING;
        // if (force != null) return (force);
        return this.txnWeights.nextValue();
    }
   
    /**
     * Benchmark execution loop
     */
    @Override
    public void runLoop() {
        if (debug.val) LOG.debug("Starting runLoop()");
        Client client = this.getClientHandle();
        try {
            while (true) {
                // Figure out what page they're going to update
                this.runOnce();
                client.backpressureBarrier();
            } // WHILE
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }
   
    @Override
  protected boolean runOnce() throws IOException {
        Transaction target = this.selectTransaction();
        this.startComputeTime(target.displayName);
        Object params[] = null;
        try {
            params = this.generateParams(target);
        } catch (Throwable ex) {
            throw new RuntimeException("Unexpected error when generating params for " + target, ex);
        } finally {
            this.stopComputeTime(target.displayName);
        }
        assert(params != null);
        boolean ret = this.getClientHandle().callProcedure(this.callbacks[target.ordinal()],
                                                           target.callName,
                                                           params);

        //if (debug.val) LOG.debug("Executing txn:" + target.callName + ",with params:" + params);
        return ret;
  }
  private String generateUserIP() {
        return String.format("%d.%d.%d.%d", randGenerator.nextInt(255)+1,
                                            randGenerator.nextInt(256),
                                            randGenerator.nextInt(256),
                                            randGenerator.nextInt(256));
    }
  
    @Override
    public String[] getTransactionDisplayNames() {
        // Return an array of transaction names
        String procNames[] = new String[Transaction.values().length];
        for (int i = 0; i < procNames.length; i++) {
            procNames[i] = Transaction.values()[i].displayName;
        }
        return (procNames);
    }

    protected Object[] generateParams(Transaction txn) {
        Object params[] = null;
        switch (txn) {
            case ADD_WATCHLIST:
            case REMOVE_WATCHLIST: {
                long pageId = this.flat_pages.nextLong();
                int nameSpace = util.getPageNameSpace(pageId);
                int userId = this.flat_users.nextInt();
                params = new Object[]{
                        userId,
                        nameSpace,
                        pageId
                };
                break;
            }
            case GET_PAGE_ANONYMOUS: {
                String userIp = this.generateUserIP();
                long pageId = this.zipf_pages.nextLong();
                int nameSpace = util.getPageNameSpace(pageId);
                params = new Object[]{
                        pageId,
                        nameSpace,
                        userIp,
                        true,
                };
                break;
            }
            case GET_PAGE_AUTHENTICATED: {
                int userId = this.flat_users.nextInt();
                String userIp = this.generateUserIP();
                long pageId = this.zipf_pages.nextLong();
                int nameSpace = util.getPageNameSpace(pageId);
                params = new Object[]{
                        pageId,
                        nameSpace,
                        userId,
                        userIp,
                        true,
                };
                break;
            }
            case UPDATE_PAGE: {
                int userId = this.flat_users.nextInt();
                long pageId = this.zipf_pages.nextLong();
                int nameSpace = util.getPageNameSpace(pageId);
                String user_ip = this.generateUserIP();
                params = new Object[]{
                        pageId,
                        nameSpace,
                        user_ip,
                        false,
                };
                ClientResponse cr = null;
                if (debug.val) LOG.debug("Invoking GetPageAnonymous before executing UpdatePage");
                try {
                    cr = this.getClientHandle().callProcedure(GetPageAnonymous.class.getSimpleName(), params);
                } catch (Exception e) {
                    throw new RuntimeException("Failed to call GetPageAnonymous...", e);
                }
                assert(cr != null);
                if (LOG.isDebugEnabled())
                    LOG.debug("GetPageAnonymous Result:\n" + cr);
               
                // voltTable
                VoltTable res[] = cr.getResults();
                VoltTable vt = res[0];
               
                // deal with the VoltTable and try to ...
                if (!vt.advanceRow() ) {
                    String msg = "No result for the GetPageAnonymous stored procedure";
                    throw new VoltAbortException(msg);
                }

                String vt_userText = vt.getString("USER_TEXT");
                long vt_pageId = vt.getLong("PAGE_ID");
                String vt_pageTitle = vt.getString("PAGE_TITLE");
                String vt_oldText = vt.getString("OLD_TEXT");
                int vt_textId = (int) vt.getLong("TEXT_ID");
                int vt_revisionId = (int) vt.getLong("REVISION_ID");

                assert(vt_pageId == pageId) : String.format("pageId=%d / pageTitle=%d", vt_pageId, vt_pageTitle);
                assert(vt.advanceRow() == false) : "This assert should be false, vt has only one row";

                // Permute the original text of the article
                // Important: We have to make sure that we fill in the entire array
                String newText = new String(util.generateRevisionText(vt_oldText.toCharArray()));
                int revCommentLen = util.h_commentLength.nextValue().intValue();
                String revComment = TextGenerator.randomStr(this.randGenerator, revCommentLen);
                int revMinorEdit = util.h_minorEdit.nextValue().intValue();
               
                params = new Object[]{
                        vt_pageId,
                        vt_textId,
                        nameSpace,
                        newText,
                        userId,
                        user_ip,
                        vt_userText,
                        vt_revisionId,
                        revComment,
                        revMinorEdit
                };
                break;
            }
            default:
                 assert(false):"Should not come to this point";
        }
        assert(params != null);
       
        if (debug.val) LOG.debug(txn + " Params:\n" + StringUtil.join("\n", params));
        return params;
    }
}
TOP

Related Classes of edu.brown.benchmark.wikipedia.WikipediaClient

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.