package edu.berkeley.thebes.common.persistence.disk;
import org.apache.thrift.TException;
import com.yammer.metrics.Metrics;
import com.yammer.metrics.core.Timer;
import com.yammer.metrics.core.TimerContext;
import java.io.IOException;
import edu.berkeley.thebes.common.data.DataItem;
import edu.berkeley.thebes.common.persistence.IPersistenceEngine;
import edu.berkeley.thebes.common.persistence.disk.WriteAheadLogger.LogEntry;
import edu.berkeley.thebes.common.persistence.memory.MemoryPersistenceEngine;
public class WALBackedPersistenceEngine implements IPersistenceEngine {
private final Timer putLatencyTimer = Metrics.newTimer(WALBackedPersistenceEngine.class, "put-latencies");
private final Timer forcePutLatencyTimer = Metrics.newTimer(WALBackedPersistenceEngine.class, "force-put-latencies");
private final Timer stage1Timer = Metrics.newTimer(WALBackedPersistenceEngine.class, "stage1-put-latency");
private final Timer stage2Timer = Metrics.newTimer(WALBackedPersistenceEngine.class, "stage2-put-latency");
private final Timer stage3Timer = Metrics.newTimer(WALBackedPersistenceEngine.class, "stage3-put-latency");
private MemoryPersistenceEngine inMemoryStore;
private WriteAheadLogger writeAheadLogger;
public WALBackedPersistenceEngine(String dbFilename) {
inMemoryStore = new MemoryPersistenceEngine();
writeAheadLogger = new WriteAheadLogger(dbFilename);
}
@Override
public void open() throws IOException {
inMemoryStore.open();
writeAheadLogger.open();
}
@Override
public void close() throws IOException {
inMemoryStore.close();
writeAheadLogger.close();
}
@Override
public void force_put(String key, DataItem value) throws TException {
TimerContext context = forcePutLatencyTimer.time();
try {
TimerContext stageContext = stage1Timer.time();
LogEntry logEntry = writeAheadLogger.startLogPut(key, value);
stageContext.stop(); stageContext = stage2Timer.time();
inMemoryStore.force_put(key, value);
stageContext.stop(); stageContext = stage3Timer.time();
logEntry.waitUntilPersisted();
stageContext.stop();
} finally {
context.stop();
}
}
@Override
public void put_if_newer(String key, DataItem value) throws TException {
TimerContext context = putLatencyTimer.time();
try {
LogEntry logEntry = writeAheadLogger.startLogPut(key, value);
inMemoryStore.put_if_newer(key, value);
logEntry.waitUntilPersisted();
} finally {
context.stop();
}
}
@Override
public DataItem get(String key) throws TException {
return inMemoryStore.get(key);
}
@Override
public void delete(String key) throws TException {
inMemoryStore.delete(key); // TODO: should probably write to the WAL here...
}
}