package org.reldb.rel.v0.vm;
import java.io.PrintStream;
import org.reldb.rel.v0.generator.Generator;
import org.reldb.rel.v0.storage.*;
import org.reldb.rel.v0.values.*;
/**
* The Rel virtual machine.
*
* @author dave
*/
public class VirtualMachine {
// currently executing Context
private Context currentContext;
// root execution Context.
private Context rootContext;
// Active database
private RelDatabase database;
// Generator
private Generator generator;
// Output stream
private PrintStream printStream;
// Update notice counts
private long inserts;
private long updates;
private long deletes;
private boolean inserted;
private boolean updated;
private boolean deleted;
/** Create a virtual machine. */
public VirtualMachine(Generator generator, RelDatabase database, PrintStream printStream) {
this.generator = generator;
this.database = database;
this.printStream = printStream;
reset();
}
/** Clear tuple update notices. */
public void clearTupleUpdateNotices() {
inserts = 0;
updates = 0;
deletes = 0;
inserted = false;
updated = false;
deleted = false;
}
public void noticeInsert(long insert) {
inserts += insert;
inserted = true;
}
public void noticeUpdate(long update) {
updates += update;
updated = true;
}
public void noticeDelete(long delete) {
deletes += delete;
deleted = true;
}
public void outputTupleUpdateNotices() {
if ((inserted || updated || deleted)) {
if (generator.isVerboseRelvarUpdates()) {
if (inserted)
printStream.println("NOTICE: Inserted " + inserts + " tuple" + ((inserts == 1) ? "" : "s") + ".");
if (updated)
printStream.println("NOTICE: Updated " + updates + " tuple" + ((updates == 1) ? "" : "s") + ".");
if (deleted)
printStream.println("NOTICE: Deleted " + deletes + " tuple" + ((deletes == 1) ? "" : "s") + ".");
}
clearTupleUpdateNotices();
}
}
/** Get the active database */
public RelDatabase getRelDatabase() {
return database;
}
/** Get the output stream assigned to this VM. */
public PrintStream getPrintStream() {
return printStream;
}
/** Reset the VM. */
public void reset() {
Context halting = currentContext;
while (halting != null) {
halting.halt();
halting = halting.getCaller();
}
rootContext = new Context(generator, this);
clearTupleUpdateNotices();
}
/** Get the currently-executing Instruction. */
public Instruction getCurrentInstruction() {
return currentContext.getCurrentInstruction();
}
final void setCurrentContext(Context context) {
currentContext = context;
}
public Context getCurrentContext() {
return currentContext;
}
/** Execute the given Operator in the root Context. */
public final void execute(Operator op) {
rootContext.call(op);
}
/** Pop a value from the root Context. */
public final Value pop() {
return rootContext.pop();
}
/** Get the number of items on the stack in the root Context. */
public final int getStackCount() {
return rootContext.getStackCount();
}
}