/*******************************************************************************
* 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.procedures;
import org.voltdb.ProcInfo;
import org.voltdb.SQLStmt;
import org.voltdb.VoltProcedure;
import org.voltdb.VoltTable;
import java.util.ArrayList;
import java.util.Random;
import edu.brown.rand.RandomDistribution.Zipf;
import edu.brown.benchmark.wikipedia.WikipediaConstants;
@ProcInfo(
partitionInfo = "PAGE.PAGE_ID: 0",
singlePartition = true
)
public class GetPageAnonymous extends VoltProcedure {
// -----------------------------------------------------------------
// STATEMENTS
// -----------------------------------------------------------------
public SQLStmt selectPageRestriction = new SQLStmt(
"SELECT * FROM " + WikipediaConstants.TABLENAME_PAGE_RESTRICTIONS +
" WHERE pr_page = ?"
);
public SQLStmt selectIpBlocks = new SQLStmt(
"SELECT * FROM " + WikipediaConstants.TABLENAME_IPBLOCKS +
" WHERE ipb_address = ?"
);
public SQLStmt selectRevisionsByPage = new SQLStmt(
"SELECT rev_id FROM " + WikipediaConstants.TABLENAME_REVISION + " WHERE rev_page = ?");
public SQLStmt selectPageRevision = new SQLStmt(
"SELECT * " +
" FROM " + WikipediaConstants.TABLENAME_REVISION +
" WHERE rev_page = ? " +
" AND rev_id = ? "
);
public SQLStmt selectPage = new SQLStmt(
"SELECT page_title, page_latest, page_restrictions " +
" FROM " + WikipediaConstants.TABLENAME_PAGE +
" WHERE page_id = ? " +
" AND page_namespace = ?"
);
/*
public SQLStmt selectRevision = new SQLStmt(
"SELECT * " +
" FROM " + WikipediaConstants.TABLENAME_REVISION +
" WHERE " +
"rev_id = ? LIMIT 1"
);
public SQLStmt selectPageRevisionNotLatest = new SQLStmt(
"SELECT * " +
" FROM " + WikipediaConstants.TABLENAME_PAGE + ", " +
WikipediaConstants.TABLENAME_REVISION +
" WHERE page_id = rev_page " +
" AND rev_page = ? " +
" AND page_id = ? " +
" AND rev_id = ? LIMIT 1"
);
*/
public SQLStmt selectText = new SQLStmt(
"SELECT old_text, old_flags FROM " + WikipediaConstants.TABLENAME_TEXT +
" WHERE old_page = ? " +
" AND old_id = ? "
);
private final Random rnd = new Random();
private boolean flipCoin(double phead)
{
assert phead <= 1.0;
return rnd.nextDouble() <= phead;
}
// -----------------------------------------------------------------
// RUN
// -----------------------------------------------------------------
public VoltTable run(long pageId, int pageNamespace, String userIp, boolean forSelect) {
VoltTable rs[] = null;
voltQueueSQL(selectPageRestriction, pageId);
voltQueueSQL(selectIpBlocks, userIp);
/*
//voltQueueSQL(selectPageRevision, pageId, pageId);
VoltTable rs[] = voltExecuteSQL();
//assert(rs.length == 3):"length expected is:3, but is:" + rs.length;
assert(rs.length == 2):"length expected is:2, but is:" + rs.length;
*/
voltQueueSQL(selectPage, pageId, pageNamespace);
rs = voltExecuteSQL();
// Grab Page Restrictions
while (rs[0].advanceRow()) {
String pr_type = rs[0].getString(0);
assert(pr_type != null);
} // WHILE
// check using blocking of a user by either the IP address or the
// user_name
while (rs[1].advanceRow()) {
String ipb_expiry = rs[1].getString(10);
assert(ipb_expiry != null);
} // WHILE
/*
int revisionId, textId;
if (flipCoin(WikipediaConstants.PAST_REV_CHECK_PROB)) {
// get a list of all past revisions
voltQueueSQL(selectRevisionsByPage, pageId);
rs = voltExecuteSQL();
if (!rs[0].advanceRow()) {
String msg = String.format("Invalid Page: Missing revision Namespace:%d / Title:--%s-- / PageId:%d",
pageNamespace, pageTitle, pageId);
throw new VoltAbortException(msg);
}
ArrayList<Integer> revIds = new ArrayList<Integer>();
while(rs[0].advanceRow())
{
revIds.add((int)rs[0].getLong(1));
}
int revId;
if (revIds.size() == 1) {
// only one rev, so we must pick it
revId = revIds.get(0);
} else {
// revIds.size() - 1 so we exclude the latest revision (we want to make
// this branch load *not* the latest page
Zipf zip = new Zipf(rnd, 0, revIds.size() - 1, WikipediaConstants.PAST_REV_ZIPF_SKEW);
// pick the index into revIds
int idx = (int)zip.nextLong();
assert idx >= 0 && idx < (revIds.size() - 1);
// index from the end, since we want to favor latest revisions
revId = revIds.get( (revIds.size() - 2) - idx );
}
voltQueueSQL(selectPageRevisionNotLatest, pageId, pageId, revId);
rs = voltExecuteSQL();
if (!rs[0].advanceRow()) {
String msg = String.format("Invalid Page: Missing revision Namespace:%d / Title:--%s-- / PageId:%d",
pageNamespace, pageTitle, pageId);
throw new VoltAbortException(msg);
}
revisionId = (int)rs[0].getLong("rev_id");
textId = (int)rs[0].getLong("rev_text_id");
assert !rs[0].advanceRow();
}
else { // we are only interested in the latest page
// System.err.println("selectPage:\n" + rs[0]);
// System.err.println("selectRevision:\n" + rs[1]);
// System.err.println("selectPageRevision, PageId:" + pageId);
// voltQueueSQL(selectPageRevision, pageId, pageId);
voltQueueSQL(selectPageRevision,pageId, pageId);
rs = voltExecuteSQL();
if (!rs[0].advanceRow()) {
String msg = String.format("Invalid Page: Missing revision Namespace:%d / Title:--%s-- / PageId:%d",
pageNamespace, pageTitle, pageId);
throw new VoltAbortException(msg);
}
revisionId = (int)rs[0].getLong("rev_id");
textId = (int)rs[0].getLong("rev_text_id");
assert !rs[0].advanceRow();
}
*/
// Check that we have a page
if (rs[2].advanceRow() == false) {
String msg = String.format("Invalid pageId %d", pageId);
throw new VoltAbortException(msg);
}
int col = 0;
String pageTitle = rs[2].getString(col++);
long pageLatest = rs[2].getLong(col++);
// Grab Page Revision + Text
voltQueueSQL(selectPageRevision, pageId, pageLatest);
voltQueueSQL(selectText, pageId, pageLatest);
rs = voltExecuteSQL(true);
if (rs[0].advanceRow() == false) {
String msg = String.format("No such revision revId=%d exists for pageId:%d / pageNamespace:%d",
pageLatest, pageId, pageNamespace);
throw new VoltAbortException(msg);
}
long revisionId = rs[0].getLong(0);
long textId = rs[0].getLong(2);
String user_text = rs[0].getString(5);
assert(rs[0].advanceRow() == false);
// NOTE: the following is our variation of wikipedia... the original did
// not contain old_page column!
if (rs[1].advanceRow() == false) {
String msg = String.format("No such textId=%d exists for pageId:%d / pageNamespace:%d",
textId, pageId, pageNamespace);
throw new VoltAbortException(msg);
}
String old_text = rs[1].getString(0);
VoltTable result = new VoltTable(WikipediaConstants.GETPAGE_OUTPUT_COLS);
if (forSelect == false) {
result.addRow(pageId, // PAGE_ID
pageTitle, // PAGE_TITLE
old_text, // OLD_TEXT
textId, // TEXT_ID
revisionId, // REVISION_ID
user_text); // USER_TEXT
}
assert !rs[0].advanceRow();
return (result);
}
}