package pt.ist.fenixframework.pstm;
import java.util.Iterator;
import jvstm.TopLevelTransaction;
import pt.ist.dap.implementation.simple.SimpleContextManager;
import pt.ist.dap.structure.PClass;
import pt.ist.dap.structure.PField;
import pt.ist.dap.structure.StructureManager;
import pt.ist.fenixframework.FenixFramework;
import pt.ist.fenixframework.Transaction;
import pt.ist.fenixframework.backend.fenixjvstm.FenixJvstmConfig;
import pt.ist.fenixframework.dml.DomainClass;
import pt.ist.fenixframework.dml.DomainModel;
import pt.ist.fenixframework.dml.Role;
import pt.ist.fenixframework.dml.Slot;
public class DataAccessPatterns {
private static final String DAP_ROOT_DIR = "dap-" + Util.getHostAddress();
private static boolean COLLECT_DATA = false;
public static void init(FenixJvstmConfig config) {
if (config.getCollectDataAccessPatterns()) {
try {
COLLECT_DATA = true;
SimpleContextManager.setPath(config.getCollectDataAccessPatternsPath() + DAP_ROOT_DIR);
SimpleContextManager.init();
setupDapStructures();
startWriteThread();
} catch (Throwable e) {
System.err.println("Problem during the initialization of the data-access patterns module: " + e);
e.printStackTrace();
}
}
}
public static void noteGetAccess(Object receiver, String slotName) {
if (COLLECT_DATA) {
try {
String ctxt = ((TopLevelTransaction) Transaction.current()).getContext();
if ((ctxt != null) && (!ctxt.equals(""))) {
SimpleContextManager.updateReadStatisticsFenix(receiver.getClass().getName(), slotName, 1, ctxt);
}
} catch (Throwable t) {
// ignore all throwables so that no exception during
// the data-access patterns collection breaks the
// application
System.err.println("DAP: noted exception during data collection " + t);
}
}
}
private static void setupDapStructures() {
DomainModel model = FenixFramework.getDomainModel();
StructureManager mng = new StructureManager();
for (Iterator iterator = model.getClasses(); iterator.hasNext();) {
DomainClass domClass = (DomainClass) iterator.next();
String className = domClass.getFullName();
PClass pClass = new PClass(className);
while (domClass != null) {
Iterator<Slot> slots = domClass.getSlots();
while (slots.hasNext()) {
Slot slot = slots.next();
String slotName = slot.getName();
String slotType = slot.getSlotType().getFullname();
pClass.addPField(slotName, new PField(slotName, slotType, className, false, false, false, 1));
}
for (Role role : domClass.getRoleSlotsList()) {
String roleName = role.getName();
if (roleName != null) {
String roleType = role.getType().getFullName();
pClass.addPField(roleName, new PField(roleName, roleType, className, true, true, false, 1));
}
}
domClass = (DomainClass) domClass.getSuperclass();
}
mng.addPClass(pClass);
}
SimpleContextManager.setStructureManager(mng);
}
private static void startWriteThread() {
new DapThread().start();
}
static class DapThread extends Thread {
private static final long SECONDS_BETWEEN_REPORTS = 1 * 60;
DapThread() {
setDaemon(true);
}
@Override
public void run() {
try {
while (true) {
try {
sleep(SECONDS_BETWEEN_REPORTS * 1000);
} catch (InterruptedException ie) {
// ignore exception
}
SimpleContextManager.storeStats();
SimpleContextManager.accumulatePrevData();
SimpleContextManager.writeStatisticsToCSV(DAP_ROOT_DIR + "/dap-stats.csv");
}
} catch (Throwable e) {
System.err.println("Found a problem in the thread that writes the data-access patterns stats. Terminating it.");
}
}
}
}