1 package simpledb.file;
2
3 import static simpledb.file.Page.BLOCK_SIZE;
4 import java.io.*;
5 import java.nio.ByteBuffer;
6 import java.nio.channels.FileChannel;
7 import java.util.*;
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24 public class FileMgr {
25 private File dbDirectory;
26 private boolean isNew;
27 private Map<String,FileChannel> openFiles = new HashMap<String,FileChannel>();
28
29
30
31
32
33
34
35
36
37
38 public FileMgr(String dbname) {
39 String homedir = System.getProperty("user.home");
40 dbDirectory = new File(homedir, dbname);
41 isNew = !dbDirectory.exists();
42
43
44 if (isNew && !dbDirectory.mkdir())
45 throw new RuntimeException("cannot create " + dbname);
46
47
48 for (String filename : dbDirectory.list())
49 if (filename.startsWith("temp"))
50 new File(dbDirectory, filename).delete();
51 }
52
53
54
55
56
57
58 synchronized void read(Block blk, ByteBuffer bb) {
59 try {
60 bb.clear();
61 FileChannel fc = getFile(blk.fileName());
62 fc.read(bb, blk.number() * BLOCK_SIZE);
63 }
64 catch (IOException e) {
65 throw new RuntimeException("cannot read block " + blk);
66 }
67 }
68
69
70
71
72
73
74 synchronized void write(Block blk, ByteBuffer bb) {
75 try {
76 bb.rewind();
77 FileChannel fc = getFile(blk.fileName());
78 fc.write(bb, blk.number() * BLOCK_SIZE);
79 }
80 catch (IOException e) {
81 throw new RuntimeException("cannot write block" + blk);
82 }
83 }
84
85
86
87
88
89
90
91
92 synchronized Block append(String filename, ByteBuffer bb) {
93 int newblknum = size(filename);
94 Block blk = new Block(filename, newblknum);
95 write(blk, bb);
96 return blk;
97 }
98
99
100
101
102
103
104 public synchronized int size(String filename) {
105 try {
106 FileChannel fc = getFile(filename);
107 return (int)(fc.size() / BLOCK_SIZE);
108 }
109 catch (IOException e) {
110 throw new RuntimeException("cannot access " + filename);
111 }
112 }
113
114
115
116
117
118
119 public boolean isNew() {
120 return isNew;
121 }
122
123
124
125
126
127
128
129
130
131
132 private FileChannel getFile(String filename) throws IOException {
133 FileChannel fc = openFiles.get(filename);
134 if (fc == null) {
135 File dbTable = new File(dbDirectory, filename);
136 RandomAccessFile f = new RandomAccessFile(dbTable, "rws");
137 fc = f.getChannel();
138 openFiles.put(filename, fc);
139 }
140 return fc;
141 }
142 }