SimpleDBのディスクIOをメモリIOに置換してモデル検査(失敗)
ディスクIOをメモリIOに入れ替えて擬似的にファイルシステムを操作しているような実装にする
code: simpledb/file/FileMgr.java
package simpledb.file;
import java.io.*;
import java.util.*;
import java.nio.ByteBuffer;
public class FileMgr {
private File dbDirectory;
private int blocksize;
private boolean isNew;
private Map<String,RandomAccessFile> openFiles = new HashMap<>();
private Map<String, List<Byte>> memoryStorage = new HashMap<>();
public FileMgr(File dbDirectory, int blocksize) {
this.dbDirectory = dbDirectory;
this.blocksize = blocksize;
isNew = !dbDirectory.exists();
// create the directory if the database is new
if (isNew)
dbDirectory.mkdirs();
// remove any leftover temporary tables
for (String filename : dbDirectory.list())
if (filename.startsWith("temp"))
new File(dbDirectory, filename).delete();
}
public synchronized void read(BlockId blk, Page p) {
byte[] data = getBlockData(blk.fileName(), blk.number());
ByteBuffer buffer = p.contents();
buffer.clear();
buffer.put(data);
}
public synchronized void write(BlockId blk, Page p) {
ByteBuffer buffer = p.contents();
byte[] bytes;
if (buffer.hasArray()) {
bytes = buffer.array();
} else {
buffer.get(bytes);
}
setBlockData(blk.fileName(), blk.number(), bytes);
}
public synchronized BlockId append(String filename) {
List<Byte> fileData = memoryStorage.computeIfAbsent(filename, k -> new ArrayList<>());
for (int i = 0; i < blocksize; i++) {
fileData.add((byte) 0);
}
return new BlockId(filename, fileData.size() / blocksize - 1);
}
private byte[] getBlockData(String filename, int blocknum) {
List<Byte> fileData = memoryStorage.getOrDefault(filename, new ArrayList<>());
int start = blocknum * blocksize;
if (start + blocksize <= fileData.size()) {
for (int i = 0; i < blocksize; i++) {
blockDatai = fileData.get(start + i); }
} else {
Arrays.fill(blockData, (byte) 0);
}
return blockData;
}
private void setBlockData(String filename, int blocknum, byte[] data) {
List<Byte> fileData = memoryStorage.computeIfAbsent(filename, k -> new ArrayList<>());
int start = blocknum * blocksize;
for (int i = 0; i < data.length; i++) {
if (start + i < fileData.size()) {
fileData.set(start + i, datai); } else {
}
}
}
public int length(String filename) {
try {
RandomAccessFile f = getFile(filename);
return (int)(f.length() / blocksize);
}
catch (IOException e) {
throw new RuntimeException("cannot access " + filename);
}
}
public boolean isNew() {
return isNew;
}
public int blockSize() {
return blocksize;
}
private RandomAccessFile getFile(String filename) throws IOException {
RandomAccessFile f = openFiles.get(filename);
if (f == null) {
File dbTable = new File(dbDirectory, filename);
f = new RandomAccessFile(dbTable, "rws");
openFiles.put(filename, f);
}
return f;
}
}
結果は失敗、java.nio.ByteBufferも使えないらしい。