package edu.brown.hstore.stats;
import java.util.ArrayList;
import java.util.Iterator;
import org.apache.log4j.Logger;
import org.voltdb.StatsSource;
import org.voltdb.SysProcSelector;
import org.voltdb.VoltTable;
import org.voltdb.VoltTable.ColumnInfo;
import org.voltdb.VoltType;
import edu.brown.hstore.HStoreSite;
import edu.brown.hstore.PartitionLockQueue;
import edu.brown.hstore.TransactionQueueManager;
import edu.brown.logging.LoggerUtil;
import edu.brown.logging.LoggerUtil.LoggerBoolean;
import edu.brown.profilers.ProfileMeasurement;
import edu.brown.profilers.PartitionLockQueueProfiler;
import edu.brown.profilers.TransactionQueueManagerProfiler;
import edu.brown.utils.MathUtil;
public class TransactionQueueManagerProfilerStats extends StatsSource {
private static final Logger LOG = Logger.getLogger(PartitionExecutorProfilerStats.class);
private static final LoggerBoolean debug = new LoggerBoolean();
private static final LoggerBoolean trace = new LoggerBoolean();
static {
LoggerUtil.attachObserver(LOG, debug, trace);
}
private final HStoreSite hstore_site;
private final TransactionQueueManager queue_manager;
public TransactionQueueManagerProfilerStats(HStoreSite hstore_site) {
super(SysProcSelector.QUEUEPROFILER.name(), false);
this.hstore_site = hstore_site;
this.queue_manager = hstore_site.getTransactionQueueManager();
}
@Override
protected Iterator<Object> getStatsRowKeyIterator(boolean interval) {
final Iterator<Integer> it = hstore_site.getLocalPartitionIds().iterator();
return new Iterator<Object>() {
@Override
public boolean hasNext() {
return it.hasNext();
}
@Override
public Object next() {
return it.next();
}
@Override
public void remove() {
it.remove();
}
};
}
@Override
protected void populateColumnSchema(ArrayList<ColumnInfo> columns) {
super.populateColumnSchema(columns);
columns.add(new VoltTable.ColumnInfo("PARTITION", VoltType.INTEGER));
// Make a dummy profiler just so that we can get the fields from it
TransactionQueueManagerProfiler profiler = new TransactionQueueManagerProfiler();
assert(profiler != null);
columns.add(new VoltTable.ColumnInfo("AVG_CONCURRENT", VoltType.FLOAT));
for (ProfileMeasurement pm : profiler.getProfileMeasurements()) {
String name = pm.getName().toUpperCase();
columns.add(new VoltTable.ColumnInfo(name, VoltType.BIGINT));
columns.add(new VoltTable.ColumnInfo(name+"_CNT", VoltType.BIGINT));
} // FOR
// ThrottlingQueue
columns.add(new VoltTable.ColumnInfo("THROTTLED", VoltType.BIGINT));
columns.add(new VoltTable.ColumnInfo("THROTTLED_CNT", VoltType.BIGINT));
// Add in PartitionLockQueueProfiler stats
PartitionLockQueueProfiler initProfiler = new PartitionLockQueueProfiler();
columns.add(new VoltTable.ColumnInfo("AVG_TXN_WAIT", VoltType.FLOAT));
for (ProfileMeasurement pm : initProfiler.queueStates.values()) {
String name = pm.getName().toUpperCase();
columns.add(new VoltTable.ColumnInfo(name, VoltType.BIGINT));
columns.add(new VoltTable.ColumnInfo(name+"_CNT", VoltType.BIGINT));
} // FOR
}
@Override
protected synchronized void updateStatsRow(Object rowKey, Object[] rowValues) {
int partition = (Integer)rowKey;
TransactionQueueManager.Debug dbg = this.queue_manager.getDebugContext();
TransactionQueueManagerProfiler profiler = dbg.getProfiler(partition);
PartitionLockQueue initQueue = this.queue_manager.getLockQueue(partition);
PartitionLockQueueProfiler initProfiler = initQueue.getDebugContext().getProfiler();
int offset = this.columnNameToIndex.get("PARTITION");
rowValues[offset++] = partition;
rowValues[offset++] = MathUtil.weightedMean(profiler.concurrent_dtxn);
for (ProfileMeasurement pm : profiler.getProfileMeasurements()) {
rowValues[offset++] = pm.getTotalThinkTime();
rowValues[offset++] = pm.getInvocations();
} // FOR
// ThrottlingQueue
ProfileMeasurement throttlePM = initQueue.getThrottleTime();
rowValues[offset++] = throttlePM.getTotalThinkTime();
rowValues[offset++] = throttlePM.getInvocations();
// PartitionLockQueue
rowValues[offset++] = MathUtil.weightedMean(initProfiler.waitTimes);
for (ProfileMeasurement pm : initProfiler.queueStates.values()) {
rowValues[offset++] = pm.getTotalThinkTime();
rowValues[offset++] = pm.getInvocations();
} // FOR
super.updateStatsRow(rowKey, rowValues);
}
}