package edu.brown.benchmark.markov.procedures; import java.util.HashSet; import org.voltdb.SQLStmt; import org.voltdb.VoltProcedure; import org.voltdb.VoltTable; import edu.brown.benchmark.markov.MarkovConstants; /** * DoneProcedure This procedure has a series of multi partition writes and reads * followed by a single single-partition write. The MarkovGraph should reflect * this. */ public class DoneAtPartition extends VoltProcedure { public final SQLStmt fromC = new SQLStmt("SELECT C_ID, C_A_ID FROM " + MarkovConstants.TABLENAME_TABLEC + " WHERE C_IATTR01 = ?"); public final SQLStmt updateB = new SQLStmt("UPDATE " + MarkovConstants.TABLENAME_TABLEB + " SET B_IATTR01 = B_IATTR01 + ? WHERE B_A_ID = ?"); public final SQLStmt selectB = new SQLStmt("SELECT B_IATTR01, B_ID, B_A_ID " + " FROM " + MarkovConstants.TABLENAME_TABLEB + " WHERE B_A_ID = ? " + " ORDER BY B_IATTR01 DESC LIMIT 1"); public final SQLStmt updateA = new SQLStmt("UPDATE " + MarkovConstants.TABLENAME_TABLEA + " SET A_IATTR01 = ?, " + // B_ID " A_IATTR02 = ? " + // MAX(B_IATTR01) " WHERE A_ID = ?"); public VoltTable[] run(long a_id, long value) { voltQueueSQL(fromC, value); // (MP) Select from C based on a parameter - should be multi-partition // we are comparing with a non-partitioning attribute of C // VoltTable[] intermediate_results = voltExecuteSQL(); HashSet<Long> c_a_ids = new HashSet<Long>(); while (intermediate_results[0].advanceRow()) { long c_a_id = intermediate_results[0].getLong("C_A_ID"); voltQueueSQL(updateB, value, c_a_id); // (MP - one shot) Update B based on a partitioning attribute of B // however, this update is not necessarily on the same partition as // our current // a_id, so it will go to other partitions to conduct the update c_a_ids.add(c_a_id); } // WHILE voltExecuteSQL(); // Because we can't do the distributed aggregate using IN, we have to // manually // find the max for ourselves long maxBValue = 0; long maxID = 0; for (Long c_a_id : c_a_ids) { voltQueueSQL(selectB, c_a_id); // (MP) We are selecting from B based on a bunch of different // c_a_ids we retrieved // from our first call. As a result, this is going to be // multi-partition most of the time. VoltTable[] b_results = voltExecuteSQL(); assert (b_results.length == 1); assert (b_results[0].getRowCount() > 0); assert (b_results[0].advanceRow()); long bValue = b_results[0].getLong("B_IATTR01"); maxBValue = Math.max(maxBValue, bValue); if (maxBValue == bValue) { maxID = b_results[0].getLong("B_ID"); } } // FOR voltQueueSQL(updateA, maxID, maxBValue, a_id); // (SP) An update of the part of A that is at our 'home' partition // We match based on the parameter a_id return voltExecuteSQL(); } }