package edu.brown.hstore.specexec;
import java.io.IOException;
import java.util.List;
import org.apache.log4j.Logger;
import org.voltdb.ParameterSet;
import org.voltdb.exceptions.ServerFaultException;
import org.voltdb.messaging.FastDeserializer;
import com.google.protobuf.ByteString;
import edu.brown.hstore.HStoreSite;
import edu.brown.hstore.Hstoreservice.WorkFragment;
import edu.brown.hstore.txns.AbstractTransaction;
import edu.brown.logging.LoggerUtil;
import edu.brown.logging.LoggerUtil.LoggerBoolean;
/**
* Utility methods for processing prefetch queries in txns
* @author pavlo
*/
public abstract class PrefetchQueryUtil {
private static final Logger LOG = Logger.getLogger(PrefetchQueryUtil.class);
private static final LoggerBoolean debug = new LoggerBoolean();
static {
LoggerUtil.attachObserver(LOG, debug);
}
/**
*
* @param hstore_site
* @param ts
* @param fd
* @param partition
* @return
*/
public static boolean dispatchPrefetchQueries(final HStoreSite hstore_site,
final AbstractTransaction ts,
final FastDeserializer fd,
final int partition) {
if (debug.val)
LOG.debug(String.format("%s - Looking to dispatch prefetch %s for partition %d",
ts, WorkFragment.class.getSimpleName(), partition));
// Go through the prefetch WorkFragments and find the one that we need to send
// to our target partition. We'll then queue it up at its corresponding PartitionExecutor
boolean sent = false;
for (WorkFragment frag : ts.getPrefetchFragments()) {
if (frag.getPartitionId() == partition) {
if (debug.val)
LOG.debug(String.format("%s - Dispatching prefetch %s to partition %d",
ts, frag.getClass().getSimpleName(), partition));
// We need to convert our raw ByteString ParameterSets into the actual objects
if (ts.hasPrefetchParameters() == false) {
synchronized (ts) {
if (ts.hasPrefetchParameters() == false) {
convertPrefetchParameters(ts, fd);
}
} // SYNCH
}
hstore_site.transactionWork(ts, frag);
sent = true;
break;
}
} // FOR
if (debug.val && sent == false)
LOG.debug(String.format("%s - Did not find a prefetch %s for partition %d",
ts, WorkFragment.class.getSimpleName(), partition));
return (sent);
}
protected static void convertPrefetchParameters(AbstractTransaction ts, FastDeserializer fd) {
if (debug.val)
LOG.debug(String.format("%s - Converting raw prefetch parameter bytes into ParameterSets", ts));
List<ByteString> rawParams = ts.getPrefetchRawParameterSets();
int num_parameters = rawParams.size();
ParameterSet params[] = new ParameterSet[num_parameters];
for (int i = 0; i < params.length; i++) {
fd.setBuffer(rawParams.get(i).asReadOnlyByteBuffer());
try {
params[i] = fd.readObject(ParameterSet.class);
} catch (IOException ex) {
String msg = "Failed to deserialize pre-fetch ParameterSet at offset #" + i;
throw new ServerFaultException(msg, ex, ts.getTransactionId());
}
if (debug.val)
LOG.debug(String.format("%s - Prefetch ParameterSet [%02d] -> %s",
ts, i, params[i]));
} // FOR
ts.attachPrefetchParameters(params);
}
}