package edu.berkeley.thebes.twopl.tm;
import org.apache.thrift.TException;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import edu.berkeley.thebes.common.thrift.TTransactionAbortedException;
import edu.berkeley.thebes.twopl.common.ThebesTwoPLTransactionClient;
import edu.berkeley.thebes.twopl.common.thrift.TwoPLTransactionResult;
import edu.berkeley.thebes.twopl.common.thrift.TwoPLTransactionService;
import edu.berkeley.thebes.twopl.tm.SimpleStackOperationInterpreter.Function;
import edu.berkeley.thebes.twopl.tm.SimpleStackOperationInterpreter.StatementNode;
import java.io.FileNotFoundException;
import java.nio.ByteBuffer;
import java.util.List;
import java.util.Set;
import javax.naming.ConfigurationException;
public class TwoPLTransactionServiceHandler implements TwoPLTransactionService.Iface {
private ThebesTwoPLTransactionClient client;
public TwoPLTransactionServiceHandler(ThebesTwoPLTransactionClient client) {
this.client = client;
}
@Override
public synchronized TwoPLTransactionResult execute(List<String> transaction) throws TException {
System.out.println("NEW VERSION");
ThebesTwoPLTransactionClient client = new ThebesTwoPLTransactionClient();
try {
client.open();
} catch (ConfigurationException e1) {
e1.printStackTrace();
} catch (FileNotFoundException e1) {
e1.printStackTrace();
}
SimpleStackOperationInterpreter interpreter =
new SimpleStackOperationInterpreter(client);
// Parse the transaction and determine which keys are read to & written from
List<StatementNode> statements = Lists.newArrayList();
Set<String> readKeys = Sets.newHashSet();
Set<String> writeKeys = Sets.newHashSet();
for (String operation : transaction) {
if (operation.startsWith("put")) {
String[] x = operation.split(" ");
readKeys.remove(x[1]);
writeKeys.add(x[1]);
} else {
String key = operation.substring(operation.indexOf(" ")+1);
if (!writeKeys.contains(key)) {
readKeys.add(key);
}
}
/*
StatementNode statement = interpreter.parse(operation);
String key = statement.getTarget();
if (statement.getFunction() == Function.PUT) {
readKeys.remove(key);
writeKeys.add(key);
} else if (statement.getFunction() == Function.GET) {
if (!writeKeys.contains(key)) {
readKeys.add(key);
}
}
statements.add(statement);
*/
}
// Now actually execute commands, starting by locking everything we need.
client.beginTransaction();
try {
for (String writeKey : writeKeys) {
client.writeLock(writeKey);
}
for (String readKey : readKeys) {
client.readLock(readKey);
}
for (String operation : transaction) {
if (operation.startsWith("put")) {
String[] x = operation.split(" ");
readKeys.remove(x[1]);
writeKeys.add(x[1]);
client.put(x[1], ByteBuffer.wrap(x[2].getBytes()));
} else {
String[] x = operation.split(" ");
client.get(x[1]);
}
}
client.commitTransaction();
/*
for (StatementNode statement : statements) {
// TODO: Clean up interpreter by having it merely evaluate, not execute.
interpreter.execute(statement);
}*/
} catch (AssertionError e) {
e.printStackTrace();
throw new TTransactionAbortedException(e.getMessage());
} catch (Exception e) {
e.printStackTrace();
} finally {
client.abortTransaction();
}
return new TwoPLTransactionResult(interpreter.getOutput());
}
}