package lru;
import simulation.Stats;
import simulation.Simulation;
import simulation.CacheSimInterface;
import events.NFSReadEvent;
import disk.FilesystemModel;
import disk.FileBlockRange;
import java.util.Iterator;
import java.util.TreeMap;
import java.util.TreeSet;
public class LRUTopSim implements CacheSimInterface {
Simulation sim;
int seqThreshold;
int prefetchWindow;
LRUCache lruCache;
Stats stats;
TreeMap<Long,NFSReadEvent> requests;
public LRUTopSim(Simulation sim, int nentries, int seqThreshold, int prefetchWindow) {
this.sim = sim;
this.seqThreshold = seqThreshold;
this.prefetchWindow = prefetchWindow;
lruCache = new LRUCache(nentries);
stats = new Stats();
requests = new TreeMap<Long,NFSReadEvent>();
}
public Stats getStats() {return stats;}
@Override
public void handleReadRequest(NFSReadEvent e) {
long fb = e.getFileBlock();
if (lruCache.contains(e.getFileHandle(), fb)) {
BlockInfo b = lruCache.lookup(e.getFileHandle(), fb);
assert b != null;
lruCache.updateTime(b, e.getTime()); // Upgrades a prefetch to a demand fetch.
if (b.isReady) {
// CACHE HIT
stats.addHit();
}
} else {
// CACHE MISS
requests.put(e.getUniqueID(), e);
BlockInfo b = new BlockInfo(e.getFileHandle(), fb, e.getTime(), 0, false);
BlockInfo previousBlock = lruCache.lookup(e.getFileHandle(), fb-1);
if (null != previousBlock)
b.sequentialCount = previousBlock.sequentialCount + 1;
lruCache.insert(b);
long diskNum = sim.filesystemModel.getDiskNum(e.getFileHandle());
long db = sim.filesystemModel.fileBlockToDiskBlock(e.getFileHandle(), fb);
sim.diskSim.submitReadRequest(e.getTime(), e.getUniqueID(), diskNum, db);
// Prefetch on sequential miss.
if (b.sequentialCount >= seqThreshold) {
for (int i=1; i <= prefetchWindow; i++) {
BlockInfo p = new BlockInfo(e.getFileHandle(), fb+i, e.getTime(), seqThreshold, true);
lruCache.insert(p);
long prefetchID = -(e.getUniqueID()*prefetchWindow + i); // hack
requests.put(prefetchID, e);
long dbi = sim.filesystemModel.fileBlockToDiskBlock(e.getFileHandle(), fb+i);
sim.diskSim.submitReadRequest(e.getTime(), e.getUniqueID(), diskNum, dbi);
}
}
}
}
@Override
public void blockReady(long eventID, long diskBlock) {
assert requests.containsKey(eventID);
NFSReadEvent e = requests.get(eventID);
BlockInfo b = lruCache.lookup(e.getFileHandle(), e.getFileBlock());
lruCache.markReady(b);
if (!b.isPrefetch) {
// DEMAND FETCH
stats.addMiss(sim.simDriver.getCurrentTime()-b.accessTime);
}
}
}